debut du cours de poo
This commit is contained in:
parent
a0040a3b00
commit
075a54ecf1
@ -1,19 +0,0 @@
|
||||
Exercices complémentaires
|
||||
--------------------------
|
||||
|
||||
+ **Manipulation de chaînes de caractères**:
|
||||
(création, accès à un caractère, concaténation), listes (création, ajout
|
||||
d’un élément, suppression d’un élément, accès à un élément, extraction d’une partie de liste), tableaux à une ou plusieurs dimensions.
|
||||
|
||||
+ traitement des chaines de caractères
|
||||
+ s.replace()
|
||||
+ s1 + s2
|
||||
+ un exemple de regexp simple
|
||||
|
||||
+ **Fichiers** :
|
||||
notion de chemin d’accès, lecture et écriture de données numériques ou de type chaîne de caractères depuis ou vers un fichier.
|
||||
On encourage l’utilisation de fichiers en tant que supports de données ou de résultats avant divers traitements, par exemple graphiques.
|
||||
|
||||
+ **Piles**
|
||||
Algorithmes de manipulation : fonctions 'push' et 'pop'. On utilise des listes
|
||||
(ou tableaux à 1 dimension) pour leur implantation.
|
@ -4,7 +4,6 @@ Annexes
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
exercices
|
||||
surete
|
||||
agile
|
||||
scrum
|
||||
|
@ -1,79 +0,0 @@
|
||||
Aperçu des algorithmes fondamentaux
|
||||
===================================
|
||||
|
||||
Les algorithmes sont partout. Absolument partout aujourd'hui.
|
||||
Il n'est pas un domaine de nos activités qui ne soit liés à tel ou tel algorithme.
|
||||
|
||||
En mathématiques
|
||||
-----------------
|
||||
|
||||
- l'algèbre (étude des structures de données)
|
||||
- l'arithmétique modulaire (théorie des nombres)
|
||||
- la géométrie (affine, algébrique, invariants topologiques...)
|
||||
- les diagrammes (diagrammes de Venn...)
|
||||
- les colorisation d'une carte
|
||||
- comportements stochastiques
|
||||
|
||||
En informatique
|
||||
----------------
|
||||
|
||||
- les algorithmes sur la manipulation des structures de données
|
||||
Exemple : les algorithmes de tri, de recherche dans un arbre...
|
||||
- les parcours de graphes (chemins le plus court, voyageur de commerce...)
|
||||
- la cryptologie (code gray)
|
||||
- les stratégies de jeux
|
||||
|
||||
Tirés du monde réel
|
||||
--------------------
|
||||
|
||||
- les jeux (casse-tête, dominos, échiquiers...)
|
||||
- énigmes, logique et paradoxes
|
||||
- problèmes de raisonnements. Il n'existe pas beaucoup de méthodes
|
||||
ou de moyens simples pour traiter et résoudre les énoncés de logique de raisonnement.
|
||||
- La "marche de l'ivrogne" : processus de progression discrète (pas à pas)
|
||||
dont l'étape suivante est lié à l'état présent et pas du tout à la mémoire du passé proche.
|
||||
Il revêt seulement un caractère de type probabilité (stochastique) dit markovien.
|
||||
- algorithmes de colonies de fourmis (chemins optimal pour arriver à la nourriture)
|
||||
|
||||
Le voyageur de commerce
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Le problème du voyageur de commerce, consiste en la recherche d’un trajet minimal permettant à un
|
||||
voyageur de visiter n villes. En règle générale on cherche à minimiser le temps de parcours total ou la
|
||||
distance totale parcourue.
|
||||
|
||||
Il suffit de construire tous les chemins possibles et de calculer leurs longueurs.
|
||||
Avec ``n`` villes il y a ``(n-1)!/2`` chemins possibles.
|
||||
Avec 36 villes on trouve : 5166573983193072464833325668761600000000,
|
||||
si le nombre de villes augmente, ça devient vite rédibitoire.
|
||||
|
||||
Résolution par
|
||||
|
||||
- algorithme de parcours de graphes
|
||||
- algorithme glouton
|
||||
- algorithmes génétiques
|
||||
|
||||
Les algorithmes génétiques s’appuient sur un principe de sélection des individus d’une population qui présen-
|
||||
tent des caractéristiques se rapprochant au mieux de ce que l’on recherche; cette population évoluant par
|
||||
ailleurs selon des critères d’évolution génétique à choisir. Dans le contexte du problème du voyageur de
|
||||
commerce, un individu est une tournée, un chemin et une population un ensemble de tournées. Il s’agit
|
||||
maintenant de dé...nir un critère de sélection ainsi que des règles d’évolution de la population.
|
||||
|
||||
- approches métaheuristiques (exemples: colonies de fourmis)
|
||||
|
||||
Exemple de résolution
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Algorithme du voyageur de commerce}\label{commerce}
|
||||
\begin{algorithmic}[1]
|
||||
|
||||
\BState \emph{Données} : $L$ \Comment{Liste des villes à parcourir avec les distances entre les villes}
|
||||
\BState \emph{Données} : $L'$ \Comment{Liste du parcours des villes à effectuer}
|
||||
\State \emph{début}
|
||||
\BState ...
|
||||
\State \emph{fin}
|
||||
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
@ -1,577 +0,0 @@
|
||||
Les structures de données
|
||||
===========================
|
||||
|
||||
.. glossary::
|
||||
|
||||
ATD
|
||||
|
||||
Abstract Data Type, structure de données abstraites.
|
||||
La représentation des données est forcément un choix.
|
||||
Il est impossible de rendre compte globalement d'un élément du réel,
|
||||
il faut en faire une interprétation abstraite.
|
||||
|
||||
**Exemple**:
|
||||
|
||||
- Un être humain peut être représenté par les données présentes dans sa
|
||||
carte d'identité. Mais un être humain n'est pas sa carte d'identité.
|
||||
- Un être humain peut être représenté par les données présentes dans ses préférences
|
||||
de surf sur internet. Mais un être humain **n'est pas** l'ensemble de ses logs de surf sur le net.
|
||||
|
||||
Les séquences
|
||||
-------------
|
||||
|
||||
Les types séquences (listes)
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# 4::1::5::8::1::[];;
|
||||
- : int list = [4 ;1 ;5 ;8 ;1]
|
||||
|
||||
|
||||
Un ensemble de valeurs portant le même nom de variable et repérées par un nombre, s’appelle un tableau, ou encore une liste, ou une variable indicée.
|
||||
Le nombre qui, au sein d’un tableau, sert à repérer chaque valeur s’appelle l’indice.
|
||||
Chaque fois que l’on doit désigner un élément du tableau, on fait figurer le nom du tableau, suivi de l’indice de l’élément.
|
||||
|
||||
**manipulation** :
|
||||
|
||||
- `insert()`
|
||||
- `append()`
|
||||
- `remove()`
|
||||
- `find()`
|
||||
- `print()`
|
||||
- ...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
zoo = ['bear', 'lion', 'panda', 'zebra']
|
||||
print(zoo)
|
||||
|
||||
# But these list elements are not
|
||||
biggerZoo = ['bear', 'lion', 'panda', 'zebra', ['chimpanzees', 'gorillas', 'orangutans', 'gibbons']]
|
||||
print(biggerZoo)
|
||||
|
||||
- Lists Versus Tuples : types mutables, immutables
|
||||
- Lists Versus Sets : non ordonné, collection simple
|
||||
|
||||
- Recherche dans une liste, recherche du maximum dans une liste
|
||||
- Recherche d’un mot dans une chaîne de caractères.
|
||||
|
||||
Algorithme de la longueur d'une liste
|
||||
--------------------------------------
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# let rec longueur l =
|
||||
match l with
|
||||
[] -> 0
|
||||
| ::s -> 1 + (longueur s);;
|
||||
|
||||
Cette fonction est prédéfinie en Ocaml : `List.length`
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : écrire un algorithme qui déclare et
|
||||
remplisse un tableau de 7 valeurs numériques en les mettant toutes à zéro.
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
::
|
||||
|
||||
Tableau Truc(6) en Numérique
|
||||
Variable i en Numérique
|
||||
Debut
|
||||
Pour i <- 0 à 6
|
||||
Truc(i) <- 0
|
||||
i Suivant
|
||||
Fin
|
||||
|
||||
exemple d'implémentation en python
|
||||
|
||||
.. code-block: python
|
||||
|
||||
>>> liste = []
|
||||
>>> for i in range(6):
|
||||
... liste.append(i)
|
||||
...
|
||||
>>> liste
|
||||
[0, 1, 2, 3, 4, 5]
|
||||
>>>
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Calcul du premier élément maximal dans une liste,
|
||||
proposer une implémentation en python qui renvoie le maximum et
|
||||
la position du max dans la liste.
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
|
||||
.. code-block: python
|
||||
|
||||
def max_list(L) :
|
||||
k = len(L)
|
||||
max, x = L[0], 0
|
||||
i = 1
|
||||
while i < k :
|
||||
if max < L[i]:
|
||||
max = L[i]
|
||||
x = i
|
||||
i = i + 1
|
||||
return max, x
|
||||
|
||||
couple = max_list([4,5,6,9,12,5,10,3,18,5,6,7])
|
||||
print ’Max de L est ’, couple[0]
|
||||
print ’et se trouve à la position ’, couple[1]
|
||||
|
||||
Exemple de généricité : ce code fonctionne avec une chaîne de caractères.
|
||||
|
||||
.. code-block: python
|
||||
|
||||
couple = max_list(’totovaaumarche’)
|
||||
print ’Max de L est ’, couple[0]
|
||||
print ’et se trouve à la position ’, couple[1]
|
||||
|
||||
.. glossary::
|
||||
|
||||
Matrice
|
||||
|
||||
Tableaux de dimension multiple, c'est un tableau de tableau
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Écrivez un algorithme remplissant un tableau de 6 sur 13, avec des zéros.
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
|
||||
implémentation en python
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> matrice = []
|
||||
>>> for i in range(12):
|
||||
... matrice.append([0 for i in range(5)])
|
||||
...
|
||||
>>> from pprint import pprint
|
||||
>>> pprint(matrice)
|
||||
[[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0]]
|
||||
>>>
|
||||
|
||||
Algorithmes de tri
|
||||
------------------
|
||||
|
||||
On désigne par "tri" l'opération consistant à ordonner un ensemble d'éléments en fonction de clés sur lesquelles est définie une relation d'ordre.
|
||||
|
||||
Les algorithmes de tri ont une grande importance pratique.
|
||||
Ils sont fondamentaux dans certains domaines (exemples : map-reduce en database non relationnelle).
|
||||
|
||||
L'étude du tri est également intéressante en elle-même, c'est un des domaines de l'algorithmique très étudié et connu.
|
||||
|
||||
Tri par insertion
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Cet algorithme de tri suit de manière naturelle la structure récursive des
|
||||
listes. Soit l une liste à trier :
|
||||
|
||||
- si l est vide alors elle est déjà triée
|
||||
- sinon, l est de la forme x::s et on trie récursivement la suite s et on obtient une liste triée s’
|
||||
on insert x au bon endroit dans s’ et on obtient une liste triée
|
||||
|
||||
Description de l'algorithme
|
||||
|
||||
- la fonction inserer permet d’insérer un élément x dans une liste l
|
||||
- si la liste l est triée alors x est inséré au bon endroit
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# let rec inserer x l =
|
||||
match l with
|
||||
[] -> [x]
|
||||
| y::s -> if x<=y then x::l else y::(inserer x s);;
|
||||
val inserer : ’a -> ’a list -> ’a list
|
||||
# inserer 5 [3 ;7 ;10];;
|
||||
- : int list = [3 ; 5 ; 7 ; 10]
|
||||
|
||||
Tri rapide
|
||||
~~~~~~~~~~~~
|
||||
|
||||
soit une liste l à trier :
|
||||
|
||||
- si l est vide alors elle est triée
|
||||
- sinon, choisir un élément p de la liste (le premier par exemple)
|
||||
nommé le **pivot**
|
||||
- partager l en deux listes g et d contenant les autres éléments de l
|
||||
qui sont plus petits (resp. plus grands) que la valeur du pivot p
|
||||
- trier récursivement g et d, on obtient deux listes g’ et d’ triées
|
||||
|
||||
.. code-block:: ocaml
|
||||
:caption: fonction de partage d'une liste
|
||||
|
||||
#let rec partage p l =
|
||||
match l with
|
||||
[] -> ([] , [])
|
||||
|x::s -> let g,d = partage p s in
|
||||
if x<=p then (x::g , d) else (g , x::d) ;;
|
||||
val partage : ’a -> ’a list -> ’a list * ’a list = <fun>
|
||||
# partage 5 [1 ;9 ;7 ;3 ;2 ;4];;
|
||||
- : int list * int list = ([1 ; 3 ; 2 ; 4], [9 ; 7])
|
||||
|
||||
.. code-block:: ocaml
|
||||
:caption: algorithme de tri rapide
|
||||
|
||||
# let rec tri rapide l =
|
||||
match l with
|
||||
[] -> []
|
||||
| p::s -> let g , d = partage p s in
|
||||
(tri rapide g)@[p]@(tri rapide d) ;;
|
||||
val tri rapide : ’a list -> ’a list = <fun>
|
||||
# tri rapide [5 ; 1 ; 9 ; 7 ; 3 ; 2 ; 4];;
|
||||
- : int list = [1 ; 2 ; 3 ; 4 ; 5 ; 7 ; 9]
|
||||
|
||||
|
||||
Définition d'un itérateur
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> l = range(10)
|
||||
>>> for i in l:
|
||||
... print l[i]
|
||||
...
|
||||
0
|
||||
...
|
||||
8
|
||||
9
|
||||
>>> l.__iter__()
|
||||
<listiterator object at 0x7f78bb450410>
|
||||
|
||||
|
||||
Les listes chaînées
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
typedef struct list{
|
||||
int elt ;
|
||||
struct list* suivant ;
|
||||
} ;
|
||||
|
||||
|
||||
**Outils de manipulation** :
|
||||
|
||||
- `next()`
|
||||
- `pointer()`
|
||||
- `insert(l, a)`
|
||||
- `remove(a, n)`
|
||||
|
||||
|
||||
Les piles
|
||||
----------
|
||||
|
||||
**manipulation**
|
||||
|
||||
- `insert()` : insérer un élément à la fin de la pile
|
||||
- `dequeue()` : (remove and return) : retirer un élément du haut de la pile
|
||||
- FIFO : "first in first out"
|
||||
|
||||
|
||||
Traduction d'une structure de données dans une autre
|
||||
-----------------------------------------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> listOfStrings = ['One', 'Two', 'Three']
|
||||
>>> strOfStrings = ' '.join(listOfStrings)
|
||||
>>> print(strOfStrings)
|
||||
One Two Three
|
||||
>>>
|
||||
>>> # List Of Integers to a String
|
||||
... listOfNumbers = [1, 2, 3]
|
||||
>>> strOfNumbers = ''.join(str(n) for n in listOfNumbers)
|
||||
>>> print(strOfNumbers)
|
||||
123
|
||||
>>>
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> l = [('host1', '10.1.2.3', '6E:FF:56:A2:AF:18'), ('host3', '10.1.2.5', '6E:FF:56:A2:AF:19')]
|
||||
>>> result = []
|
||||
>>> for hostname, ip, macaddress in l:
|
||||
... result.append(dict(hostname=hostname, ip=ip, macaddress=macaddress))
|
||||
...
|
||||
>>> result
|
||||
[{'hostname': 'host1', 'ip': '10.1.2.3', 'macaddress': '6E:FF:56:A2:AF:18'},
|
||||
{'hostname': 'host3', 'ip': '10.1.2.5', 'macaddress': '6E:FF:56:A2:AF:19'}]
|
||||
>>>
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Proposer un algorithme de traduction de cette structure de donnée
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
[
|
||||
{
|
||||
'address': '192.168.0.0',
|
||||
'mask': '255.255.255.0',
|
||||
'dynamicRanges': [
|
||||
{ 'low': '192.168.0.5', 'high': '192.168.0.12', 'only_unknown': True },
|
||||
{ 'low': '192.168.0.50', 'high': '192.168.0.55', 'only_unknown': False },
|
||||
],
|
||||
},
|
||||
{
|
||||
'address': '192.168.0.0',
|
||||
'mask': '255.255.255.0',
|
||||
'dynamicRanges': [
|
||||
{ 'low': '192.168.0.12', 'high': '192.168.0.45', 'only_unknown': True },
|
||||
{ 'low': '192.168.0.8', 'high': '192.168.0.35', 'only_unknown': False },
|
||||
],
|
||||
},
|
||||
{
|
||||
'address': '192.168.0.1',
|
||||
'mask': '255.255.255.0',
|
||||
'dynamicRanges': [
|
||||
{ 'low': '192.168.0.5', 'high': '192.168.0.12', 'only_unknown': True },
|
||||
{ 'low': '192.168.0.50', 'high': '192.168.0.55', 'only_unknown': False },
|
||||
],
|
||||
},
|
||||
|
||||
]
|
||||
|
||||
En cette structure de données :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
[
|
||||
{
|
||||
address: '192.168.0.0',
|
||||
mask: '255.255.255.0',
|
||||
dynamicRanges: [
|
||||
{ low: '192.168.0.5', high: '192.168.0.12', only_unknown: true },
|
||||
{ low: '192.168.0.50', high: '192.168.0.55', only_unknown: false },j
|
||||
], [
|
||||
{ low: '192.168.0.12', high: '192.168.0.45', only_unknown: true },
|
||||
{ low: '192.168.0.8', high: '192.168.0.35', only_unknown: false },
|
||||
],
|
||||
},
|
||||
{
|
||||
'address': '192.168.0.1',
|
||||
'mask': '255.255.255.0',
|
||||
'dynamicRanges': [
|
||||
{ 'low': '192.168.0.5', 'high': '192.168.0.12', 'only_unknown': True },
|
||||
{ 'low': '192.168.0.50', 'high': '192.168.0.55', 'only_unknown': False },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from pprint import pprint
|
||||
pprint(l)
|
||||
[{'address': '192.168.0.0',
|
||||
'dynamicRanges': [{'high': '192.168.0.12',
|
||||
'low': '192.168.0.5',
|
||||
'only_unknown': True},
|
||||
{'high': '192.168.0.55',
|
||||
'low': '192.168.0.50',
|
||||
'only_unknown': False}],
|
||||
'mask': '255.255.255.0'},
|
||||
{'address': '192.168.0.0',
|
||||
'dynamicRanges': [{'high': '192.168.0.45',
|
||||
'low': '192.168.0.12',
|
||||
'only_unknown': True},
|
||||
{'high': '192.168.0.35',
|
||||
'low': '192.168.0.8',
|
||||
'only_unknown': False}],
|
||||
'mask': '255.255.255.0'}]
|
||||
>>> newdata = []
|
||||
>>> for i in l:
|
||||
... if i['address'] not in [j['address'] for j in newdata]:
|
||||
... newdata.append(i)
|
||||
... else:
|
||||
... for k in newdata:
|
||||
... if k['address'] == i['address']:
|
||||
... k['dynamicRanges'].extend(i['dynamicRanges'])
|
||||
...
|
||||
>>> pprint(newdata)
|
||||
[{'address': '192.168.0.0',
|
||||
'dynamicRanges': [{'high': '192.168.0.12',
|
||||
'low': '192.168.0.5',
|
||||
'only_unknown': True},
|
||||
{'high': '192.168.0.55',
|
||||
'low': '192.168.0.50',
|
||||
'only_unknown': False},
|
||||
{'high': '192.168.0.45',
|
||||
'low': '192.168.0.12',
|
||||
'only_unknown': True},
|
||||
{'high': '192.168.0.35',
|
||||
'low': '192.168.0.8',
|
||||
'only_unknown': False}],
|
||||
'mask': '255.255.255.0'},
|
||||
{'address': '192.168.10.0',
|
||||
'dynamicRanges': [{'high': '192.168.0.12',
|
||||
'low': '192.168.0.5',
|
||||
'only_unknown': True},
|
||||
{'high': '192.168.0.55',
|
||||
'low': '192.168.0.50',
|
||||
'only_unknown': False}],
|
||||
'mask': '255.255.255.0'}]
|
||||
>>>
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Proposer un algorithme qui permette de récupérer la liste
|
||||
des adresses IP disponibles
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
{
|
||||
"local": {
|
||||
"leases": [
|
||||
{
|
||||
"mac": "02:00:c0:a8:00:66",
|
||||
"name": "pcxubuntu",
|
||||
"address": "192.168.0.200"
|
||||
},
|
||||
{
|
||||
"mac": "02:00:c0:a8:00:67",
|
||||
"name": "pcxubuntu",
|
||||
"address": "192.168.0.201"
|
||||
},
|
||||
{
|
||||
"mac": "02:00:c0:a8:00:68",
|
||||
"name": "pcxubuntu",
|
||||
"address": "192.168.0.202"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> l = {
|
||||
... "local": {
|
||||
... "leases": [
|
||||
... {
|
||||
... "mac": "02:00:c0:a8:00:66",
|
||||
... "name": "pcxubuntu",
|
||||
... "address": "192.168.0.200"
|
||||
... },
|
||||
... {
|
||||
... "mac": "02:00:c0:a8:00:67",
|
||||
... "name": "pcxubuntu",
|
||||
... "address": "192.168.0.201"
|
||||
... },
|
||||
... {
|
||||
... "mac": "02:00:c0:a8:00:68",
|
||||
... "name": "pcxubuntu",
|
||||
... "address": "192.168.0.202"
|
||||
... }
|
||||
... ]
|
||||
... }
|
||||
... }
|
||||
>>> leases = l["local"]["leases"]
|
||||
>>> from pprint import pprint
|
||||
>>> pprint(leases)
|
||||
[{'address': '192.168.0.200', 'mac': '02:00:c0:a8:00:66', 'name': 'pcxubuntu'},
|
||||
{'address': '192.168.0.201', 'mac': '02:00:c0:a8:00:67', 'name': 'pcxubuntu'},
|
||||
{'address': '192.168.0.202', 'mac': '02:00:c0:a8:00:68', 'name': 'pcxubuntu'}]
|
||||
>>> addresses = [lease['address'] for lease in leases]
|
||||
>>> addresses
|
||||
['192.168.0.200', '192.168.0.201', '192.168.0.202']
|
||||
>>>
|
||||
|
||||
|
||||
|
||||
Structures de données complexes
|
||||
-------------------------------
|
||||
|
||||
Les types produits nommés
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
On les appelle enregistrements, dictionnaires ou tables de hachage.
|
||||
|
||||
::
|
||||
|
||||
algorithme monAlgorithme
|
||||
// déclaration d'un enregistrement
|
||||
enregistrement Personne
|
||||
chaine nom;
|
||||
chaine prenom;
|
||||
entier age;
|
||||
réel taille;
|
||||
finenregistrement
|
||||
...
|
||||
Personne[50] t;
|
||||
début
|
||||
// Initialisation
|
||||
t[0].nom <- "Duchmol";
|
||||
t[0].prenom <- "Robert";
|
||||
t[0].age <- 24;
|
||||
t[0].taille <- 1.80;
|
||||
...
|
||||
fin
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# type adresse = { rue : string ; ville : string ; cp : int};;
|
||||
# type fiche = {
|
||||
nom : string ;
|
||||
prenom : string ;
|
||||
adresse : adresse ;
|
||||
date naissance : int * int * int ;
|
||||
tel fixe : string ;
|
||||
portable : string
|
||||
};;
|
||||
# let v1 = { a = 1 ; b = false ; c = 'r'};;
|
||||
|
||||
|
||||
|
||||
|
||||
- les sommes (constructeurs)
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# type couleur = Pique | Coeur | Carreau | Trefle;;
|
||||
# let v = (Pique , Coeur);;
|
||||
val v : couleur * couleur = (Pique , Coeur)
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
type nombre =
|
||||
Ent of int | Reel of float | Cplx of float × float
|
||||
Ent, Reel, Cplx sont les constructeurs du type.
|
||||
|
||||
Autres structures de données complexes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- arbres
|
||||
- graphes
|
||||
- dates
|
||||
|
||||
- le parcours de graphes
|
||||
- les calculs de dates
|
@ -1,588 +0,0 @@
|
||||
Les fonctions et les procédures
|
||||
================================
|
||||
|
||||
Préliminaire : rappel de théorie de cybernétique
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Théorie de l'information (Claude Shannon, 1949), (ou théorie de la communication)
|
||||
|
||||
Canal de transmission::
|
||||
|
||||
entrée -> récepteur -> émetteur -> sortie
|
||||
|
||||
.. glossary::
|
||||
|
||||
cybernétique
|
||||
|
||||
étude des fonctions de réflexes conditionnés du cerveau humain
|
||||
utilisation au mieux en PNL ("programmation neuro-linguistique")
|
||||
ou en analyse transactionnelle, ou au pire en ingérinerie sociale.
|
||||
|
||||
La matérialité physique est considérée comme le hardware, le génétique (le
|
||||
réseau neuronal) étant assimilé au network hardware.
|
||||
|
||||
Les objets mentaux (fonctionnements psychologiques et épigénétiques du
|
||||
cerveaux) est assimilé au logiciel, au software.
|
||||
|
||||
IFTTT ("if this then that") : la causalité mondaine est ramenée à un ordre de
|
||||
comportement affecté à un assimilé-machine.
|
||||
|
||||
L'humain est ramené à une machine.
|
||||
C'est articulation entre "déclencheur contextuel" et "action en réponse de"
|
||||
n'est pas une "black box" mais un "feedback" qui, pour l'humain,
|
||||
loin d'être ramené à une entrée/sortie, constitue un **feedback**
|
||||
utile pour la connaissance de soi.
|
||||
|
||||
A la place, la communication est ramenée à une **boucle de rétroaction**
|
||||
(comme dans un prompt) entre un système comportemental et son environnement.
|
||||
La représentation sujet/objet (la perspective traditionnelle) est remplacée
|
||||
par le clivage intérieur/extérieur. Behaviorisme, procédural.
|
||||
|
||||
L'humain est donc ramené à
|
||||
|
||||
- un ordonnanceur
|
||||
- un comportement intrinsèque (boîte noire)
|
||||
|
||||
- un stimuli pavlovien (déclencheur, trigger) est considéré comme un paramètre
|
||||
d'entrée
|
||||
- une instruction comportementale est considérée comme une action de
|
||||
traitement
|
||||
- le résultat est observé.
|
||||
|
||||
Cette articulation entre "déclencheur contextuel" et "action en réponse"
|
||||
est très exactement une forclusion de la profondeur monadique (Leibniz) de
|
||||
l'humain à la black box informationnelle (et cybernétique).
|
||||
|
||||
Pour quoi faire ? Pour pirater. Pour manipuler.
|
||||
Le piratage consiste à
|
||||
|
||||
- isoler les constantes (les procédures répétitives, les algorithmes)
|
||||
- les observer (collecter les données)
|
||||
|
||||
afin de
|
||||
|
||||
- les réécrire (influence toxique, pishing - hammeçonnage)
|
||||
- les détruire (attaque en règle)
|
||||
|
||||
|
||||
Description d'une procédure
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
En programmation impérative, un programme est une suite d’instructions qui font
|
||||
évoluer l’état mémoire, le résultat est dans l’état final de la mémoire.
|
||||
|
||||
- une procédure peut prendre des paramètres
|
||||
- elle modifie l'état courant du système
|
||||
|
||||
- Déclaration des paramètes
|
||||
- Déclaration du corps
|
||||
- Appel de la procédure
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Procédure de permutation de deux entiers}\label{permutation}
|
||||
\begin{algorithmic}[1]
|
||||
\Procedure{permuter}{$a,b$}{}
|
||||
\BState \emph{parametres}:
|
||||
\State $a: \textit{int}$
|
||||
\State $b: \textit{int}$
|
||||
\BState \emph{locales}:
|
||||
\State $z: \textit{int}$ \Comment{Une variable intermédiaire est nécessaire}
|
||||
\BState \emph{corps}:
|
||||
\State $z \gets a$
|
||||
\State $a \gets b$
|
||||
\State $b \gets z$
|
||||
\EndProcedure
|
||||
\State \Call{permuter}{10, 12} \Comment{appel de la procédure}
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
effet de bord
|
||||
|
||||
toute modification de la mémoire ou modification d'un support externe
|
||||
|
||||
instruction
|
||||
|
||||
commande ou phrase en mesure de modifier l'état du programme ou de la machine hôte
|
||||
(allocation mémoire, support externe, disque, écran...)
|
||||
|
||||
Une procédure ne renvoie pas de valeur, mais provoque un 'effet de bord' (écriture dans une globale, dans un flux sortant etc.).
|
||||
|
||||
Une procédure permet de créer une instruction nouvelle qui deviendra une primitive pour le programmeur.
|
||||
Cela permet de structurer le texte source du programme et améliorer sa
|
||||
lisibilité. Cela permet aussi d'appeler plusieurs fois, et à plusieurs endroit
|
||||
dans le code, cette primitive.
|
||||
|
||||
Appel d'une procédure
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
(ex: pseudo-pascal)
|
||||
|
||||
**déclaration de procédure**
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Procédure de permutation de deux entiers}\label{appelpermutation}
|
||||
\begin{algorithmic}[1]
|
||||
\Procedure{permuter}{$a,b$}{}
|
||||
\BState \emph{parametres}:
|
||||
\State $a: \textit{int}$ \Comment{paramètres formels de la procédure}
|
||||
\State $b: \textit{int}$
|
||||
\BState \emph{locales}:
|
||||
\State $z: \textit{int}$ \Comment{les variables locales de la procédure}
|
||||
\BState \emph{corps}:
|
||||
\State ... \Comment{Le corps de la procedure}
|
||||
\EndProcedure
|
||||
\State \Call{permuter}{10, 12} \Comment{l'appel de la procédure}
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
|
||||
- les variables x1,...,xn sont appelées *paramètres formels* de p
|
||||
- les variables v1,...,vm sont appelées *les variables locales* de p
|
||||
|
||||
les valeurs effectivement passées en paramètres, ici `10, 12`
|
||||
sont appelées **paramètres effectifs** de p
|
||||
|
||||
signature
|
||||
|
||||
C'est l'ensemble paramètre formel + resultat de l'appel
|
||||
|
||||
fermeture
|
||||
|
||||
L'ensemble procédure + variables locales + signature + parametres effectifs
|
||||
est appelé une **fermeture**. C'est la procédure + son contexte qui permet
|
||||
de l'instancier dans un programme.
|
||||
|
||||
Environnement
|
||||
|
||||
Contexte d’évaluation d'une expression ou d'une fonction
|
||||
|
||||
Portée
|
||||
|
||||
La portée d'un identifiant (une variable) est sa condition d'utilisation dans un contexte donné
|
||||
(utilisation locale uniquement, ou bien globale, ou bien locale et globale)
|
||||
La portée d’une liaison est la portion du code dans laquelle cette
|
||||
liaison est valide (i.e. où un identifiant est lié à une expression).
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Que donne ce code ?
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# let x = 42 in
|
||||
let y = x - 1 in x - y ;;
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
- : int = 1
|
||||
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
let a = 3 (* première liaison pour l'identifiant a *)
|
||||
let b = 5 and c = 6
|
||||
let somme = a + b + c
|
||||
val somme : int = 14
|
||||
let a = 45 (* deuxième liaison pour l'identifiant a *)
|
||||
somme
|
||||
val a : int = 45
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Que donne ce code ?
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
let a = 3 and b = 4 and c = 8 ;;
|
||||
let somme = a + b + c ;;
|
||||
val somme : int = ???
|
||||
let a = 44
|
||||
let b = 5
|
||||
let c = 1
|
||||
somme
|
||||
- : int = ???
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
let a = 3 and b = 4 and c = 8 ;;
|
||||
- : int = 15
|
||||
let somme = a + b + c ;;
|
||||
val somme : int = 15
|
||||
let a = 44
|
||||
let b = 5
|
||||
let c = 1
|
||||
somme
|
||||
- : int = 15
|
||||
|
||||
Même code en python
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> a = 1
|
||||
>>> b = 2
|
||||
>>> c = 3
|
||||
>>> somme = a + b + c
|
||||
>>> somme
|
||||
6
|
||||
>>> a = 56
|
||||
>>> b = 5678
|
||||
>>> c = 56789
|
||||
>>> somme
|
||||
6
|
||||
>>>
|
||||
|
||||
Portée locale dans une expression
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# let a = 2 and b = 3 and c = 4 in
|
||||
let somme = a+b+c in
|
||||
somme
|
||||
- : int = 9
|
||||
# somme ;;
|
||||
Error: Unbound value somme
|
||||
# a ;;
|
||||
Error: Unbound value a
|
||||
|
||||
.. important::
|
||||
|
||||
L’ordre d’évaluation dans un let ... in ... est bien déterminé,
|
||||
sans grande importance dans un cadre purement fonctionnel, mais important
|
||||
en cas d’effets de bord
|
||||
|
||||
|
||||
Exemple de variable globale modifiée localement (**attention, mauvaise pratique** !) :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> a = 5
|
||||
>>> def print_a():
|
||||
... print("La variable a = {0}.".format(a))
|
||||
...
|
||||
>>> print_a()
|
||||
La variable a = 5.
|
||||
>>> a = 8
|
||||
>>> print_a()
|
||||
La variable a = 8.
|
||||
>>>
|
||||
|
||||
|
||||
|
||||
niveau
|
||||
|
||||
Le niveau d’une déclaration (de variable ou de procédure) est le nombre
|
||||
de procédures sous lesquelles elle est déclarée. Le programme principal
|
||||
a le niveau 0.
|
||||
|
||||
.. code-block:: python
|
||||
:linenos:
|
||||
|
||||
def _get_config(name):
|
||||
# return config value
|
||||
if not isfile(CONFIG_FILE):
|
||||
raise Exception("Fichier de configuration non existant")
|
||||
from ConfigParser import ConfigParser
|
||||
cfg = ConfigParser(allow_no_value=True)
|
||||
cfg.read(CONFIG_FILE)
|
||||
|
||||
if name == "SUBNETS":
|
||||
return eval(cfg.get('eole', 'subnets'))
|
||||
elif name == "LEASES_FILE":
|
||||
DHCP_PATH = cfg.get('eole', 'container_path_dhcp')
|
||||
return join('/', DHCP_PATH, 'var/lib/dhcp/dhcpd.leases')
|
||||
def get_routes(*args, **kwargs):
|
||||
"""
|
||||
Send list of reserved IP
|
||||
return list of tuple (id, machine name, IP, MAC Adress)
|
||||
"""
|
||||
cfg = creole_loader(load_extra=True, rw=False, owner=MODNAME,
|
||||
mandatory_permissive=False)
|
||||
return zip(cfg.dhcp.dhcp.id_dhcp.id_dhcp, cfg.dhcp.dhcp.id_dhcp.hostname,
|
||||
cfg.dhcp.dhcp.id_dhcp.ip, cfg.dhcp.dhcp.id_dhcp.macaddress)
|
||||
|
||||
On voit que l'objet `cfg` ligne 6 et 7 a le même nom que l'objet `cfg` ligne 19.
|
||||
C'est autorisé et les espaces de nommages sont différents.
|
||||
|
||||
|
||||
Description d'une fonction
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Une fonction renvoie une valeur et ne modifie pas l'état courant du programme
|
||||
en cours d'exécution ni ne réalise d'effets de bord. Elle renvoie
|
||||
**toujours** quelque chose (même la valeur ``None`` qui n'est pas rien)
|
||||
|
||||
- une procédure peut prendre des paramètres
|
||||
- elle modifie l'état courant du système
|
||||
|
||||
- Déclaration des paramètes
|
||||
- Déclaration du corps
|
||||
- Appel de la fonction
|
||||
|
||||
En programmation fonctionnelle, programme est un ensemble de définitions de fonctions,
|
||||
un résultat est l'application d’une fonction à une structure de données effective.
|
||||
|
||||
- composant de base : la fonction
|
||||
- opération de base : l’application
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Exemple de fonction}\label{fonction}
|
||||
\begin{algorithmic}[1]
|
||||
\Function{permuter}{$a,b$}{} \Comment{définition de la fonction}
|
||||
\BState \emph{parametres}: \Comment{déclaration (noms, types) des paramètres formels}
|
||||
\State $a: \textit{int}$
|
||||
\State $b: \textit{int}$
|
||||
\BState \emph{locales}: \Comment{déclaration (noms, types) des valeurs locales}
|
||||
\State $z: \textit{int}$
|
||||
\BState \emph{corps}:
|
||||
\State $z \gets a$
|
||||
\State $a \gets b$
|
||||
\State $b \gets z$
|
||||
\BState \emph{return}: \Comment{La valeur, le résulat renvoyé par la fonction}
|
||||
\EndFunction
|
||||
\State \Call{permuter}{10, 12} \Comment{appel de la fonction}
|
||||
\BState \emph{result}:
|
||||
\State (12, 10) \Comment{Le résultat effectif de la fonction après appel}
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : factoriser le code suivant
|
||||
::
|
||||
|
||||
Ecrire "Etes-vous marié ?"
|
||||
Rep1 <- ""
|
||||
TantQue Rep1 <> "Oui" et Rep1 <> "Non"
|
||||
Ecrire "Tapez Oui ou Non"
|
||||
Lire Rep1
|
||||
FinTantQue
|
||||
...
|
||||
Ecrire "Avez-vous des enfants ?"
|
||||
Rep2 <- ""
|
||||
TantQue Rep2 <> "Oui" et Rep2 <> "Non"
|
||||
Ecrire "Tapez Oui ou Non"
|
||||
Lire Rep2
|
||||
FinTantQue
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
|
||||
::
|
||||
|
||||
Fonction RepOuiNon() en caractère
|
||||
Truc <- ""
|
||||
TantQue Truc <> "Oui" et Truc <> "Non"
|
||||
Ecrire "Tapez Oui ou Non"
|
||||
Lire Truc
|
||||
FinTantQue
|
||||
Renvoyer Truc
|
||||
Fin
|
||||
|
||||
Ecrire "Etes-vous marié ?"
|
||||
Rep1 <- RepOuiNon()
|
||||
...
|
||||
Ecrire "Avez-vous des enfants ?"
|
||||
Rep2 <- RepOuiNon()
|
||||
|
||||
|
||||
Définition mathématique
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
fonction
|
||||
|
||||
Une fonction f d’un ensemble E vers un ensemble F est une
|
||||
correspondance qui associe à chaque élément de E au plus
|
||||
un élément de F.
|
||||
|
||||
- E est appelé le domaine de définition
|
||||
- F est appelé codomaine
|
||||
- la **signature** de la fonction : `E → F (int -> int = <fun>)`
|
||||
|
||||
|
||||
Exemple de signature d'une fonction
|
||||
|
||||
::
|
||||
|
||||
Fonction RepOuiNon(Msg en Caractère) en Caractère
|
||||
Ecrire Msg
|
||||
Truc <- ""
|
||||
TantQue Truc <> "Oui" et Truc <> "Non"
|
||||
Ecrire "Tapez Oui ou Non"
|
||||
Lire Truc
|
||||
FinTantQue
|
||||
Renvoyer Truc
|
||||
Fin Fonction
|
||||
|
||||
...
|
||||
Rep1 <- RepOuiNon("Etes-vous marié ?")
|
||||
...
|
||||
Rep2 <- RepOuiNon("Avez-vous des enfants ?")
|
||||
...
|
||||
|
||||
|
||||
curryfication
|
||||
|
||||
évaluation de l'application d'une fonction
|
||||
|
||||
- évaluter `(f x y)`
|
||||
- peut donner une **valeur fonctionnelle**
|
||||
- évaluation de la valeur fonctionnelle sur une valeur des types de base
|
||||
|
||||
::
|
||||
|
||||
let g = function n -> (function p -> p + 1) n;;
|
||||
|
||||
Typage d'une fonction
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# let f x y z = if x > 0 then y + x else z - x;;
|
||||
val f : int -> int -> int -> int = <fun>
|
||||
|
||||
c’est en fait une fonction à un argument qui retourne une fonction::
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
val f : int -> (int -> (int -> int)) = <fun>
|
||||
|
||||
application de f à trois valeurs
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# f 1 2 3;;
|
||||
- : int = 3
|
||||
|
||||
en programmation fonctionnelle,
|
||||
les fonctions sont des valeurs comme les autres
|
||||
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# fun x -> x * x;;
|
||||
- : int -> int = <fun>
|
||||
|
||||
Récursivité
|
||||
~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
let rec fact n =
|
||||
if n=0 then 1 else n * fact (n-1)
|
||||
|
||||
|
||||
équivalent impératif utilisant une boucle
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int fact(int n){
|
||||
int f = 1 ;
|
||||
int i = n ;
|
||||
while (i>0){
|
||||
f = f * i;
|
||||
i-- ;
|
||||
} ;
|
||||
return f ;
|
||||
}
|
||||
|
||||
Définitions par cas
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
let rec fact n =
|
||||
match n with
|
||||
0 -> 1
|
||||
| -> n * fact (n-1)
|
||||
|
||||
**exemple** : la fonction puissance
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
let rec puissance x n = match n with
|
||||
0 -> 1
|
||||
| -> x * puissance x (n-1)
|
||||
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Portée locale dans une fonction**
|
||||
Quelles sera la valeur de la variable `a` ?
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> a = 1
|
||||
>>> def myfunc():
|
||||
... a = 2
|
||||
... return a + 1
|
||||
...
|
||||
>>> a = myfunc() + a
|
||||
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
Correction:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> a = 1
|
||||
>>> def myfunc():
|
||||
... a = 2
|
||||
... return a + 1
|
||||
...
|
||||
>>> a = myfunc() + a
|
||||
>>> a
|
||||
4
|
||||
>>>
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Portée locale dans une fonction avec variable globale
|
||||
Quelles sera la valeur de la variable `a` ?
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> a = 1
|
||||
>>> def myfunc():
|
||||
... global a
|
||||
... a = 2
|
||||
... return a + 1
|
||||
...
|
||||
>>> a = myfunc() + 3
|
||||
>>>
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> a = 1
|
||||
>>> def myfunc():
|
||||
... global a
|
||||
... a = 2
|
||||
... return a + 1
|
||||
...
|
||||
>>> myfunc()
|
||||
3
|
||||
>>> a
|
||||
2
|
||||
>>> a = myfunc() + 3
|
||||
>>> a
|
||||
6
|
||||
>>>
|
@ -8,10 +8,6 @@ Introduction à l'algorithmique
|
||||
fondement
|
||||
langage
|
||||
programme
|
||||
fonctions
|
||||
donnees
|
||||
apercu
|
||||
modularite
|
||||
modules
|
||||
tp
|
||||
annexes/index
|
||||
|
@ -98,60 +98,6 @@ c'est-à-dire des phrases en langage naturel.
|
||||
|
||||
et ainsi de suite jusqu'à ce que toutes les phrases soient calculables.
|
||||
|
||||
Algorithme vague
|
||||
--------------------
|
||||
|
||||
L'algorithme vague, c'est quand on pense l'algorithme en se plaçant du côté de
|
||||
l'implémentation en premier. On a le nez dans le guidon, la vue d'ensemble est
|
||||
difficile.
|
||||
|
||||
Voici, tiré du monde réel, un exemple d'algorithme vague
|
||||
("ce que doit faire une fonction"), placé dans un bout de code
|
||||
(souvent la **docstring** d'une fonction).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def upsert_route(*args, **kwargs):
|
||||
"""
|
||||
Create or modify an existant DHCP route
|
||||
param tuple (id or null, machine name, IP, MAC Adress)
|
||||
return True or False with error message
|
||||
"""
|
||||
# si id présent alors modification sinon ajout
|
||||
# récupère la liste des réservations en cours
|
||||
# y cherche la variable sur la base de l'ID
|
||||
# modifie les valeurs
|
||||
# applique la nouvelle conf DHCP
|
||||
|
||||
return True
|
||||
|
||||
Voici un autre bout de code avec l'algorithme en commentaire,
|
||||
et l'implémentation effective de l'algorithme
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def del_route(*args, **kwargs):
|
||||
"""
|
||||
Delete an existant DHCP route
|
||||
param tuple (id, machine name, IP, MAC Adress)
|
||||
return True or False with error message
|
||||
"""
|
||||
# récupère la liste des réservations en cours
|
||||
# y cherche la variable sur l'id donné en paramètre
|
||||
# supprime l'entrée avec vérification que les données fournies
|
||||
# sont bien dans l'enregistrement à supprimer
|
||||
# applique la nouvelle conf DHCP
|
||||
route_to_del = (1, "host2","10.1.2.4","6E:FF:56:A2:AF:17")
|
||||
routes = get_routes()
|
||||
if route_to_del in routes:
|
||||
c = creole_loader(load_extra=True, rw=True)
|
||||
c_id = c.dhcp.dhcp.id_dhcp.id_dhcp.index(route_to_del[0])
|
||||
if c.dhcp.dhcp.id_dhcp.macaddress[c_id]==route_to_del[2]
|
||||
and c.dhcp.dhcp.id_dhcp.ip[c_id]==route_to_del[1]:
|
||||
c.dhcp.dhcp.id_dhcp.id_dhcp.pop(c_id)
|
||||
config_save_values(c, MODNAME)
|
||||
return True
|
||||
return False
|
||||
|
||||
Les deux grands paradigmes
|
||||
---------------------------
|
||||
|
@ -1,10 +1,32 @@
|
||||
Avant propos
|
||||
============
|
||||
|
||||
| "**Que nul n'entre ici s'il n'est géomètre**"
|
||||
| Maxime apposée au porche d'entrée de l'École de Platon
|
||||
|
||||
|
||||
- L'honnête programmeur d'aujourd'hui **doit** avoir eu une réflexion approndie sur la nature
|
||||
des objets. Tous les programmeurs les utilisent, peu savent vraiment de quoi il en retourne,
|
||||
et très peu nombreux savent définir le paradigme et les mécanismes objets correctement.
|
||||
|
||||
|
||||
|
||||
|
||||
Introduction
|
||||
~~~~~~~~~~~~
|
||||
|
||||
.. FIXME
|
||||
|
||||
.. FIXME : définir la position et les objectifs
|
||||
|
||||
FIXME
|
||||
|
||||
|
||||
Objectifs de ce cours
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Il s'agit de :
|
||||
|
||||
- maîtriser et concevoir des objets et des classes,
|
||||
- choisir une représentation appropriée des classes,
|
||||
- décomposer en sous-problèmes et affinements successifs à l'aide de la représenation objet,
|
||||
|
||||
.. FIXME
|
||||
|
@ -45,48 +45,6 @@ Par exemple, la ligne suivante est une expression effectuant une addition::
|
||||
|
||||
5 + 6
|
||||
|
||||
Expressions à partir de types de base
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Autres exemples d'expressions :
|
||||
|
||||
- 5 est une expression de type int
|
||||
- 4.5 est une expression de type float
|
||||
- 'c' est une expression de type char
|
||||
- true est une expression de type bool
|
||||
- print ('c') est une expression de type None
|
||||
- raw_input est une expression de type string
|
||||
|
||||
Les expressions se complexifient avec la complexification des données et des traitements,
|
||||
mais le principe de l'expressivité d'un langage reste le même.
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** :
|
||||
Le parenthésage et les opérateurs booléens::
|
||||
|
||||
Variables A, B, C, D, E en Booléen
|
||||
Variable X en Entier
|
||||
Début
|
||||
Lire X
|
||||
A <- X > 12
|
||||
B <- X > 2
|
||||
C <- X < 6
|
||||
D <- (A ET B) OU C
|
||||
E <- A ET (B OU C)
|
||||
Ecrire D, E
|
||||
Fin
|
||||
|
||||
**Que valent D et E si X = 3 ?**
|
||||
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** : D sera VRAI alors que E sera FAUX
|
||||
|
||||
|
||||
|
||||
|
||||
Les déclarations
|
||||
-----------------
|
||||
@ -204,143 +162,6 @@ Exemples dans la langue française :
|
||||
|
||||
Voir aussi :
|
||||
|
||||
- Les déclarations de types primitifs et conversions de type
|
||||
- Les types de base::
|
||||
|
||||
Octets (8 bits) byte
|
||||
Entiers courts (16 bits) short
|
||||
Entiers (32 bits) int
|
||||
Entiers longs (64 bits) long
|
||||
Réels (32 bits) float
|
||||
Réels longs (64 bits) double
|
||||
Caractères (16 bits) char
|
||||
Booléens boolean
|
||||
|
||||
- Déclarations par lots::
|
||||
|
||||
x1 = e1, x2 = e2, ... xn = en;
|
||||
|
||||
Exercices : algorithmes sur les affectations
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Calculs d'affectation::
|
||||
|
||||
Variables A, B, C en Entier
|
||||
Début
|
||||
A <- 3
|
||||
B <- 10
|
||||
C <- A + B
|
||||
B <- A + B
|
||||
A <- C
|
||||
Fin
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction**::
|
||||
|
||||
Après La valeur des variables est :
|
||||
A <- 5 A = 5 B = ?
|
||||
B <- 2 A = 5 B = 2
|
||||
A <- B A = 2 B = 2
|
||||
B <- A A = 2 B = 2
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Calculs d'affectation
|
||||
Quelles seront les valeurs des variables A et B après exécution des instructions suivantes ?
|
||||
::
|
||||
|
||||
Variables A, B en Entier
|
||||
Début
|
||||
A <- 5
|
||||
B <- 2
|
||||
A <- B
|
||||
B <- A
|
||||
Fin
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction**::
|
||||
|
||||
Après La valeur des variables est :
|
||||
A <- 5 A = 5 B = ?
|
||||
B <- 2 A = 5 B = 2
|
||||
A <- B A = 2 B = 2
|
||||
B <- A A = 2 B = 2
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : écrire un algorithme permettant d’échanger les valeurs
|
||||
de deux variables A et B, et ce quel que soit leur contenu préalable.
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction**::
|
||||
|
||||
Début
|
||||
A <- n
|
||||
B <- p
|
||||
C <- A
|
||||
A <- B
|
||||
B <- C
|
||||
Fin
|
||||
|
||||
Il faut passer par une variable dite temporaire (la variable C)
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** :
|
||||
Que produit l’algorithme suivant ?
|
||||
|
||||
::
|
||||
|
||||
Variables A, B, C de type entier
|
||||
Début
|
||||
A <- 423
|
||||
B <- 12
|
||||
C <- A + B
|
||||
Fin
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** : dans un prompt python
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> a = 423
|
||||
>>> b = 12
|
||||
>>> c = a + b
|
||||
>>> c
|
||||
435
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** :
|
||||
Que produit l’algorithme suivant ?
|
||||
|
||||
::
|
||||
|
||||
Variables A, B, C de type texte
|
||||
Début
|
||||
A <- "423"
|
||||
B <- "12"
|
||||
C <- A + B
|
||||
Fin
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** : dans un prompt python
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> a = '423'
|
||||
>>> b = '12'
|
||||
>>> c = a + b
|
||||
>>> c
|
||||
'42312'
|
||||
|
||||
Interaction avec l'utilisateur
|
||||
------------------------------
|
||||
|
||||
@ -421,18 +242,7 @@ Le prompt ipython::
|
||||
|
||||
In [1]:
|
||||
|
||||
Le prompt OCaml (utop)::
|
||||
|
||||
Type #utop_help for help about using utop.
|
||||
|
||||
─( 09:21:24 )─< command 0 >──
|
||||
utop #
|
||||
# let x = 1 in x + 2;;
|
||||
- : int = 3
|
||||
# let y = 1 + 2;;
|
||||
val y : int = 3
|
||||
# y * y;;
|
||||
- : int = 9
|
||||
Construire une boucle d'interaction avec l'utilisateur en python::
|
||||
|
||||
#!/usr/bin/env python3
|
||||
|
@ -1,101 +0,0 @@
|
||||
Travaux Pratiques
|
||||
=================
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**travaux pratiques :**
|
||||
|
||||
Ecrire un algorithme qui renvoie le résultat d’une mini-calculatrice. Cette
|
||||
méthode aura
|
||||
comme paramètre deux nombres et une chaîne de caractère qui vaudra « + », « -
|
||||
», « * »,
|
||||
« / ».
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**travaux pratiques :**
|
||||
|
||||
|
||||
Ecrire un algorithme qui renvoie si deux mots (chaîne de caractères) passés en
|
||||
paramètre
|
||||
sont des anagrammes l’un de l’autre. (Lettres identiques mais dans un ordre
|
||||
différent)
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**travaux pratiques :**
|
||||
|
||||
ascii art (ligne d'étoiles)
|
||||
|
||||
Concevoir un algorithme qui, pour un caractère imprimable et un nombre n
|
||||
donnés, imprime une barre
|
||||
horizontale de n de ces caractères.
|
||||
|
||||
``****************``
|
||||
|
||||
2. Modifier l’algorithme pour l’impression d’une barre double.
|
||||
|
||||
::
|
||||
|
||||
****************
|
||||
****************
|
||||
|
||||
3. Modifier l’algorithme pour l’impression d’une barre d’épaisseur quelconque
|
||||
donnée.
|
||||
4. (optionnel) Transformer les algorithmes ci-dessus en fonctions.
|
||||
5. Écrire un programme Java implémentant la dernière version de l’algorithme
|
||||
(épaisseur quelconque).
|
||||
|
||||
3.3
|
||||
Triangle de nombres
|
||||
Concevoir un algorithme qui imprime pour n donné::
|
||||
|
||||
1
|
||||
1 2
|
||||
1 2 3
|
||||
1 2 3 4
|
||||
1 2 3 4 5
|
||||
...........
|
||||
.............
|
||||
...............
|
||||
1 2 3 4 5 6 ... n
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**travaux pratiques :**
|
||||
|
||||
code de césar : faire un programme pour chiffrer et déchiffrer par décalage
|
||||
|
||||
exemples : Effectue une rotation de x caractères vers la droite::
|
||||
|
||||
>>> print(chiffre('bonjour', 3))
|
||||
erqmrxu
|
||||
>>> print(chiffre('Bonjour les amis!', 3))
|
||||
Erqmrxu ohv dplv!
|
||||
>>> print(chiffre('Erqmrxu ohv dplv!', 23))
|
||||
Bonjour les amis!
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**travaux pratiques :**
|
||||
|
||||
::
|
||||
|
||||
écrire “Entrer un numéro de mois”
|
||||
mois <- lire
|
||||
selon que mois est
|
||||
cas 1 : écrire “janvier (31 jours)”
|
||||
cas 2 : écrire “février (28 ou 29 jours)”
|
||||
cas 3 : écrire “mars (31 jours)”
|
||||
cas 4 : écrire “avril (30 jours)”
|
||||
cas 5 : écrire “mai (31 jours)”
|
||||
cas 6 : écrire “juin (30 jours)”
|
||||
cas 7 : écrire “juillet (31 jours)”
|
||||
cas 8 : écrire “août (31 jours)”
|
||||
cas 9 : écrire “septembre (30 jours)”
|
||||
cas 10 : écrire “octobre (31 jours)”
|
||||
cas 11 : écrire “novembre (30 jours)”
|
||||
cas 12 : écrire “décembre (31 jours)”
|
||||
défaut : écrire “numéro invalide”
|
||||
fselon
|
Loading…
Reference in New Issue
Block a user