debut du cours de poo

This commit is contained in:
gwen 2017-09-04 14:54:33 +02:00 committed by Benjamin Bohard
parent 9a03e5190d
commit baab6fdd1f
10 changed files with 24 additions and 1615 deletions

View File

@ -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
dun élément, suppression dun élément, accès à un élément, extraction dune 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 daccès, lecture et écriture de données numériques ou de type chaîne de caractères depuis ou vers un fichier.
On encourage lutilisation 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.

View File

@ -4,7 +4,6 @@ Annexes
.. toctree::
:maxdepth: 2
exercices
surete
agile
scrum

View File

@ -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 dun 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 sappuient sur un principe de sélection des individus dune population qui présen-
tent des caractéristiques se rapprochant au mieux de ce que lon 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 sagit
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}

View File

@ -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, sappelle un tableau, ou encore une liste, ou une variable indicée.
Le nombre qui, au sein dun tableau, sert à repérer chaque valeur sappelle lindice.
Chaque fois que lon doit désigner un élément du tableau, on fait figurer le nom du tableau, suivi de lindice 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 dun 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 dinsé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

View File

@ -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 dinstructions 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 dune 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::
Lordre dévaluation dans un let ... in ... est bien déterminé,
sans grande importance dans un cadre purement fonctionnel, mais important
en cas deffets 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 dune 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 dune fonction à une structure de données effective.
- composant de base : la fonction
- opération de base : lapplication
.. 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 dun 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>
cest 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
>>>

View File

@ -8,10 +8,6 @@ Introduction à l'algorithmique
fondement
langage
programme
fonctions
donnees
apercu
modularite
modules
tp
annexes/index

View File

@ -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
---------------------------

View File

@ -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

View File

@ -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 lalgorithme 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 lalgorithme 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

View File

@ -1,101 +0,0 @@
Travaux Pratiques
=================
.. ifconfig:: exercice
**travaux pratiques :**
Ecrire un algorithme qui renvoie le résultat dune 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 lun de lautre. (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 lalgorithme pour limpression dune barre double.
::
****************
****************
3. Modifier lalgorithme pour limpression dune 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 lalgorithme
(é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