Vous êtes sur la page 1sur 35

14 février 2016

Résumé + cours IPT MP

from numpy import ∗

Document en perpétuelle évolution. Tous les documents/TD/corrigés sont par ailleurs


disponibles sur la partie privée du site :
https: // sites. google. com/ site/ nimesmp/
sous les formats .pdf ou .ipynb

Table des matières


1 Commandes de base 3
1.1 Assigner/afficher/demander/aide . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Opérations/fonctions usuelles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Types Python 4
2.1 Zoom sur les listes/tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1.1 Fonctions/méthodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.2 Générer des listes/tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.3 Illustrations du slicing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 Matrices, opérations principales . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3 Zoom sur les chaı̂nes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3 Algorithmique 7
3.1 Test if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.2 Boucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.2.1 Boucles for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.2.2 Boucles while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.3 Théorie des boucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.3.1 Description d’une boucle : tableaux d’états . . . . . . . . . . . . . . . . . 9
3.3.2 Terminaison d’une boucle while : variants de boucles . . . . . . . . . . . 10
3.3.3 Validité d’une boucle : invariants de boucle . . . . . . . . . . . . . . . . . 11
3.3.4 Complexité . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.4 Fonctions def . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.5 Fonctions récursives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.5.1 Exemple 1 : la factorielle . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.5.2 Exemple 2 : la suite de Fibonacci . . . . . . . . . . . . . . . . . . . . . . . 16

1/35 (c) MP Lycée Alphonse Daudet


3.5.3 Exemple 3 : partitions d’un entier . . . . . . . . . . . . . . . . . . . . . . 18
3.5.4 Important : limiter le nombre d’appels récursifs . . . . . . . . . . . . . . . 19
3.6 Piles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.6.1 Présentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.6.2 Les quatre fonctions primitives . . . . . . . . . . . . . . . . . . . . . . . . 20
3.6.3 Exemples de programmations de piles . . . . . . . . . . . . . . . . . . . . 21
3.6.4 Exemple : examen de parenthésages . . . . . . . . . . . . . . . . . . . . . 21
3.7 Tris . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.8 Bases de données/SqL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

4 Compléments sur le cours de 2nde année 26


4.1 Générer de l’aléatoire/probabilités . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.2 Tracés 2d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.3 Autres tracés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.4 Mesurer le temps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.5 Manipulation de fichiers/répertoires . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.6 Traitement d’image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.6.1 Générer des images matricielles . . . . . . . . . . . . . . . . . . . . . . . . 30
4.6.2 Capturer/modifier/sauvegarder des images existantes . . . . . . . . . . . 32
4.6.3 Résumé des commandes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.6.4 Un exemple de traitement local d’image . . . . . . . . . . . . . . . . . . . 33
4.7 Programmation orientée objet (POO) . . . . . . . . . . . . . . . . . . . . . . . . 35
4.8 Calcul scientifique (HP) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

2/35 (c) MP Lycée Alphonse Daudet


1 Commandes de base
1.1 Assigner/afficher/demander/aide

Action Entrée Sortie


La variable x pointera
Assigner x=y
vers le contenu de la variable y
Assigner (multiple) a,b=0,1 Pareil que a=0 et b=1
Incrémenter x+=y Change x en x+y in place
Décrémenter x-=y Change x en x-y in place
Afficher
print("salut") Affichage de salut à l’écran (et c’est tout)
(sortie écran)
Stocke la réponse dans la variable age
age=input("Quel ^ age as tu ?")
Poser une question Bqui sera de type str
(question entre ”” optionnelle)
pour la convertir age=int(age)
Renvoie resultat
Renvoyer un résultat
return resultat (uniquement dans une fonction)
(sortie mémoire)
(=⇒ sortie de fonction)
Demander le type type(objet) type Python
Catalogue objet dir(objet) Liste fctions/méthodes relatives
Aide en ligne help(commande) Aide
Passe le reste de la ligne
Commentaires #
en mode commentaire

1.2 Opérations/fonctions usuelles

• Remarque : DE = ≪ division euclidienne ≫.

Action Python 2.7 Python 3+ Exemple


Addition + + 2+3 → 5
Multiplication ∗ ∗ 2 ∗ 3→6
Puissance ∗∗ ∗∗ 2 ∗∗ 3 → 8
Division décimaux Cf. remarque / 5/2 → 2.5 en Python 3
Quotient DE / // 7/3 → 2 en 2.7
Reste DE % % 7 % 3→1
Addition array([1,2])+array([2,3])
+ +
array → array([3,5])
Addition/concaténation
+ + [1,2]+[3,4] → [1,2,3,4]
list ou str
Multiplication/concaténation
∗ ∗ [1,2]*3 → [1,2,1,2,1,2]
list ou str
pas classique : sqrt(2) (racine)
Fonction usuelle Nom usuel Nom usuel floor(4.5) (partie entière)
abs(-3) (valeur absolue)

• Remarque :
➣(division décimale Python 2.7) ≪ / ≫ ne renverra le résultat attendu QUE si l’un des
acteurs est de type float, ce qu’il faut parfois préciser à Python. Par exemple pour ≪ 5 diviser
par 2 ≫ on tape 5./2 ou 5/2. ou float(5)/2.
➣on peut s’affranchir de cette particularité en validant from future import division qui
passer la division en mode Python 3.

3/35 MP 2015/2016 — (c) Florent Nicaise


2 Types Python

• Indexation des itérables :

Bl’indexation commence à zéro et pas un donc si truc=’Monty Python’ on accède à ’M’ par
truc[0].

Type Ex. maths Python Exemple Itérable


Booléen Vrai ou Faux bool True/False x
Entier 12 int 12 x
Décimal 1,2 float 1.2 x
Complexe 1 + 2i complex 1+2j x
Fonction f : x 7→ e−x function f = lambda x: exp(-x) x
Liste [1,2,3] list l=[1,2,3]  l[1] → 2
l[0] → [1,2]
Liste (de listes) [[1,2],[3,4]] list l=[[1,2],[3,4]]
l[1][1] → 4
Ensemble {1, 2, 3} set s={1,2,3} s[2] → 3
p-uplet t=(1,2,3) tuple t=(1,2,3) t[0]=1
Chaı̂ne
Texte normal str mot="Salut" mot(1)="a"
caractères     
1 2 3 T[1,1] → 5
Tableaux T =   array T=array([[1,2,3],[4,5,6]])
4 5 6 T[0:2,1] → [2,5]
Conversion Voir remarque

• Remarque :

1 (conversion d’un objet en un autre type) a nouveau=nouveautype(ancien). Exemples :

➣conversion ensemble → liste : a=list({1,2,3}) → a= [1,2,3] ;


➣conversion décimal → chaine de caractères : mot=str(12) → mot="12".

2 liste des objets vides : [] liste vide, { } ensemble vide, "" chaine vide.

2.1 Zoom sur les listes/tableaux

a. À l’exception de la conversion lst → tableau multi-dimensionnel, voir la commande reshape en section


2.1.2.

4/35 MP 2015/2016 — (c) Florent Nicaise


2.1.1 Fonctions/méthodes

Action Entrée Sortie


Longueur d’une liste len( [1,2,3] ) 3
Rajouter à une liste a.append(4) Rajoute 4 à la fin in place de a
Concaténer listes [1,2,3]+[4] [1,2,3,4]
Répéter liste [1,2] ∗ 3 [1,2,1,2,1,2]
Expulser un élément a.pop() Expulse le dernier élément de a in place
Trier a.sort() Trie a par ordre croissant in place
Symétrie centrale a.reverse() Inverse les éléments d’une liste in place
Tester l’appartenance 1 in [1,2,3] ou 5 in [1,2,3] True ou False
Format tableau tableau.shape tuple (nbre lgn, nbre col,etc.)
Extraire (sclicing) 1-d Si a=[0,1,2,3,4,5] a[0:3]→ [0,1,2]
Extraire tableau 2d Si a=array( [ [1,2,3] , [4,5,6] ] ) a[0:2,0:2] → [ [1,2],[4,5] ]
Compter apparition Si a=[1,1,2,3] a.count(1) → 2
Créer une copie de a b=a.copy() Crée un nouveau pointeur b
Tester égalité d’arrays list(a)==list(b) Càd convertir en listes

2.1.2 Générer des listes/tableaux

Action Entrée Sortie


[0,1,3,4,5] ou [1,2,3]
Générer liste d’entiers range(6) ou range(1,4) Bpas le dernier
par ex. range(a,b) → [[a, b[[
Générer subdivision de [0, 10]
linspace(0,10,3) array([ 0., 5., 10.])
à 3 pts
Génération par compréhension [i**2 for i in range(4)] [0,1,4,9]
[0,3]
Génération filtrée [i for i in range(6) if i%3 == 0]
ici filtre = reste de i par 3=0 ≫

Multiplication/concaténation [0]*3 ou [ [1,2]*2 ] [0,0,0] ou [[1,2],[1,2]]


Générer tableau de zéros zeros((2,3)) [ [0,0,0],[0,0,0] ]
Générer tableau
array( [lgn,col] ,dtype=x) Tableau lgn × col à data type x
contenant type x
Extraire (sclicing) 1-d Si a="python" a[0:3]→ "pyt"
Conversion liste → tableau reshape(liste,(3,2)) liste à 6 éléments → tableau 3 x 2

2.1.3 Illustrations du slicing

• Exemple sur un tableau 6x1 :

• Exemple sur un tableau 6x6 :

5/35 MP 2015/2016 — (c) Florent Nicaise


2.2 Matrices, opérations principales

• Les 
matrices peuvent
 être vus comme des tableaux 2-d, par exemple :
1 −1 2
M= devient M = array( [ [1,-1,2] ,[1,1,1] ] )
1 1 1
Alors :
➣on accède à l’élément ligne 0, colonne 1 par M[0,1] ou M[0][1] → -1 ;
➣on accède à la première ligne par M[0] → array( [ 1,-1,2] ). Ainsi, le nombre de colonnes
est len(M[0]) ;
➣on accède à la première colonne par M[:,0] → array( [1,1] ). Ainsi, le nombre de lignes
est len(M).
➣Bà la syntaxe du produit matriciel (voir ci-dessous).

Action Entrée Sortie


Format shape(M) Tuple ( lignes, colonnes )
Inverse linalg.inv(M) matrix([[ 0.5, 0.5], [-0.5, 0.5]])
Produit matriciel dot(A,B) Produit A × B
Déterminant, trace linalg.det(M),linalg.tr(M) 2,2
Matrice identité identity(3) I3
Matrice diagonale à
Générer diag(a, b, c) diag(liste)
coeff. formés par liste

• Méthodes avancées de calcul formel (donc HP, mais peut-être utile) :

Action Entrée Sortie


Puissance linalg.matrix power(M,3) Puissance 3ème
Résolution M X = Y linalg.solve(M,Y) Solution(s) X
Valeurs propres linalg.eigvals(M) Vecteur des VP (avec répétition)
Vecteur des VP
VP + Vecteur propres linalg.eig(M) + matrice constituée de V P unitaires
associés dans l’ordre aux VP

6/35 MP 2015/2016 — (c) Florent Nicaise


2.3 Zoom sur les chaı̂nes de caractères

Action Entrée Sortie


Longueur d’une chaı̂ne len("python") 6
Concaténer chaı̂nes "pyt"+"hon" "python"
Aller à la ligne " Salut \ n ça va ?" Va à la ligne à l’affichage
Répéter chaı̂ne "Ok" ∗ 3 "OkOkOk"
Tester l’inclusion "py" in "python" ou "pi" in "python" True ou False
Remplacer dans "python".replace("py","zz") "zzthon"
Découper selon si mot="a b c" alors mot.split(" ") liste ["a","b","c"]
Compter apparition si a="coco" a.count("o") → 2

3 Algorithmique

• Ceci n’est pas un précis d’algorithmique (il y aura un cours), juste un rappel de la rédaction
globale des principaux éléments d’algorithmiques accompagnés de quelques exemples basiques.

3.1 Test if

• Principe général :
1 if bool :
2 # le test crée une indentation
3 # - >[ instructions à éxécuter si bool == True ]
4 # la fin de l ’ indentation marque la fin du test
5 else : # sinon ( OPTIONNEL )
6 # - >[ instructions à exécuter si bool == False ]
7 # la fin de l ’ indentation marque la fin du else

Typiquement, bool est un booléen (càd une assertion vraie=True ou fausse=False) défini par
une condition de type :
➣a ==b (test d’égalité a ) entre deux éléments de même type ;
➣a !=b (test de différence) entre deux éléments de même type ;
➣a in b (test d’appartenance) pour savoir si a est un élément b de b ;
➣a <=b ou a >=b pour comparer deux éléments qui peuvent l’être ;
➣des liaisons and (et), or (ou), not (négation) entre une ou plusieurs des propositions précédentes.

• Exemple :

1 Exemples de booléens :
1 >>> 1 in [1 ,2 ,3]
2 True
3 >>> 1 in [ [0 ,1] ,[1 ,2] ] # Attention les éléments de cette liste ... sont des
listes
4 False
5 >>> [0 ,1] in [ [0 ,1] ,[1 ,2] ] # ça va aller mieux
6 True
7 >>> " bon " in " bonjour " and not 4 in [1 ,2 ,3]
8 True
9 >>>

a. L’égalité dans un test se rédige par DEUX symboles ≪ = ≫, pas naturel au début et source de beaucoup de
plantages...
b. Pour les str, teste si a est une sous-chaine de b, par exemple "bon" in "bonjour" est True.

7/35 MP 2015/2016 — (c) Florent Nicaise



2 Exemples de test :
1 >>> a =23
2 >>> if a %5==3: # rappel % = reste division entiers
3 print ( ’ le reste de la division de ’+ str ( a ) + ’ par 5 est 3 ’)
4 else :
5 print ( ’ le reste de la division de ’+ str ( a ) + ’ par 5 est pas 3 ’)
6
7 # cela donne :
8
9 le reste de la division de 23 par 5 est 3

3.2 Boucles

• On peut forcer la sortie d’un boucle à tout moment en s’offrant un break.

3.2.1 Boucles for

• Principe général :
1 for compteur in iterable :
2 # les deux points creent une indentation
3 # - >[ taper les instructions a exécuter pour chaque valeur de l ’ iterable ]
4 # revenir sur l ’ indentation marque la fin de la boucle


1 Typiquement, l’itérable est un ensemble d’entiers [[a ; b]]=range(a,b+1) ou une liste ;

2 Pour parcourir les indices d’une liste, on écrit for compteur in range(len(liste)) :

3 L’instruction break, si elle est rencontrée, provoque une sortie forcée de la boucle ;

• Exemple :

1 afficher a2 pour a dans [[0 ; 4]] :
1 >>> for a in range (5) :
2 print ( a **2)
3
4 0
5 1
6 4
7 9
8 16

Ici, le compteur est a qui décrit l’itérable est la liste range(5)=[0,1,2,3,4] de type liste.

2 Compter a le nombre de ”o” dans ”bonjour” :
1 >>> mot , valeur = ’ bonjour ’ ,0
2 >>> for lettre in mot :
3 if lettre == ’o ’:
4 valeur +=1
5 >>> valeur
6 2

Ici, le compteur est lettre qui décrit l’itérable mot="bonjour" de type str.
a. Peut se faire directement avec la méthode count.

8/35 MP 2015/2016 — (c) Florent Nicaise


3.2.2 Boucles while

• Principe général :
1 while bool :
2 # les deux points creent une indentation
3 # - >[ instructions a executer tant que bool est True ]
4 # ATTENTION s ’ assurer que bool sera False au bout d ’ un moment ...
5 # ... sinon boucle infinie et plantage .

• Exemple : pour une suite définie par u0 = 0, on définit un+1 = u2n + 1 et on veut déterminer
le plus petit indice n tel que un > 50.
1 valeur , indice =0 ,0
2 while valeur <50: # tant que [ NEGATION DE CE QUE L ’ ON VEUT ]
3 indice +=1
4 valeur = valeur **2+1
5 print ( ’ Rang ’+ str ( indice ) + ’ , suite = ’+ str ( valeur ) )
6 # ce qui suit sera execute en sortie de boucle vu l ’ indentation :
7 print ( ’ Le premier rang ou l on depasse 50 est ’+ str ( indice -1) )
8 # cela donne :
9 Rang 1 , suite = 1
10 Rang 2 , suite = 2
11 Rang 3 , suite = 5
12 Rang 4 , suite = 26
13 Rang 5 , suite = 677
14 Le premier indice ou l on depasse 50 est 4

C’est la variable valeur qui prend les valeurs successives de la suite, à ne pas confondre avec la
variable indice qui joue ici le rôle de n.

3.3 Théorie des boucles

• Voici les points fondamentaux relatifs à l’étude des boucles :



1 Description de son fonctionnement : permet de comprendre ce qu’elle fait (si elle ne vient
pas de nous) ;

2 Terminaison : s’assurer qu’on finit toujours par sortir de la boucle(pour les boucles while) ;

3 Validité : s’assurer qu’elle donne le bon résultat ;

4 Complexité : évaluer le temps qu’elle va demander, pour éventuellement choisir entre deux
algorithmes concurrents.
Chacun des points va être étudié dans les sections qui suivent.

3.3.1 Description d’une boucle : tableaux d’états

• Si l’on étudie une boucle qui affecte certaines variables, on peut faire un tableau d’états
reflétant les valeurs successives de ces variables au cours de la boucle, sur des exemples concrets.
Cela permet d’expliquer et de visualiser des variants/invariants.

• Exemple : étude d’une fonction mystere...


1 def mystere (a , b ) :
2 assert a >=0 # genere un message d ’ erreur si a n ’ est pas positif
3 assert b >0 # idem
4 q , r =0 , a
5 while r >= b :
6 r =r - b
7 q +=1
8 return q , r

9/35 MP 2015/2016 — (c) Florent Nicaise


On distingue :
➣deux entrées fournies par l’utilisateur : a,b ;
➣deux variables locales modifiées dans la boucle : q,r, initialisées à la ligne 4.
➣il est habituel de noter alors qk , rk les valeurs de ces deux variables à l’issue de la k-ème
itération dans la boucle a et de présenter l’évolution à partir d’exemples concret sous forme de
tableau (ici on a choisi a,b=43,10) :

Itération k 0 1 2 3 4
qk 0 1 2 3 4 → sortie de boucle après 4 itérations car r4 < b
rk 43 33 23 13 3

Au cas où l’on n’aurait pas compris... Les variables q,r qui, en sortie de boucle, valent q4 =
4, r4 = 3 sont comme par hasard le quotient/reste de la division euclidienne de a = 43 par
b = 10...

• Remarque : dans la présentation ci-dessus, on est pas obligé de noter la dépendance en k


des variables.

3.3.2 Terminaison d’une boucle while : variants de boucles

• On doit s’assurer qu’une boucle while finit toujours par s’arrêter b . Pour cela, on essaie d’isoler
un variant de boucle , càd une quantité ≪ de type entier ≫ :
➣ qui reste positive tant qu’on est dans la boucle ;

➣ qui décroit strictement à chaque itération


Ainsi, on ne peut rester indéfiniment dans la boucle.

• Remarque : sans être un entier, un variant de boucle peut être plus largement un booléen :

➣dont la vérité permet l’itération de la boucle ;


➣mais qui sera toujours faux en un temps fini, provoquant ainsi une sortie de la boucle.

• Exemple : isoler un variant de boucle dans la fonction


1 def mystere (a , b ) :
2 assert a >=0 # genere un message d ’ erreur si a n ’ est pas positif
3 assert b >0 # idem
4 q , r =0 , a
5 while r >= b :
6 r =r - b
7 q +=1
8 return q , r

est facile, il s’agit de la quantité r-b dont la positivité est toujours vraie dans la boucle, et qui
décroit strictement (de b>0) à chaque itération.

• Remarque : on peut aussi rédiger avec les notations de la partie précédente, en observant
que
0 6 rk 6 a − k · b
dans la boucle, avec le membre de droite strictement négatif à partir d’un certain rang, qui
provoque la sortie.
a. Par convention, q0 , r0 sont les valeurs avant d’entrer dans la boucle.
b. Sinon, on parle de boucle infinie → plantage du programme et chauffage des processeurs :(

10/35 MP 2015/2016 — (c) Florent Nicaise


3.3.3 Validité d’une boucle : invariants de boucle

• Un invariant de boucle est égalité ou plus largement une propriété qui est :
➣ vraie avant l’entrée dans la boucle (initialisation) ;

➣ invariante (càd inchangée) à chaque itération (hérédité) ;


➣et dont on va pouvoir déduire le résultat.
Très souvent, on isole des invariants de boucles par des récurrences.

• Exemple : comment prouver définitivement que la fonction


1 def mystere (a , b ) :
2 assert a >=0 # genere un message d ’ erreur si a n ’ est pas positif
3 assert b >0 # idem
4 q , r =0 , a
5 while r >= b :
6 r =r - b
7 q +=1
8 return q , r

effectue bien la division euclidienne de a par b ?


➣on peut compléter le tableau d’état correspondant à a,b=43,10 avec ce que l’on devine inva-
riant :

Itération k 0 1 2 3 4
qk 0 1 2 3 4
rk 43 33 23 13 3
b · qk + rk 43 43 43 43 43

L’invariant de boucle est ici la propriété :

P (k) = [b · qk + rk = a]

➣vraie pour k = 0 ;
➣si P (k) est vraie, à l’itération d’après si elle a lieu :

qk+1 = qk + 1 P (k)
=⇒ b · qk+1 + rk+1 = b · qk + b + rk − b = a
rk+1 = rk − b

D’où la preuve de l’invariant par réccurence et, en sortie de boucle comme on a 0 6 rk < b et
toujours :
a = qk · b + rk ,
les valeurs de q,r en sortie de boucle sont bien celles de la division euclidienne.

3.3.4 Complexité

• Remarque : nous abordons la notion de complexité en temps a au niveau des boucles, mais
elle s’étudie pour tout type d’algorithme.

• On appelle opération élémentaire toute :


➣assignation (du type a=quelquechose) ;
➣comparaison ;
a. En mémoire : pas au programme.

11/35 MP 2015/2016 — (c) Florent Nicaise


➣ou calcul élémentaire (+, × ou évaluation d’une fonction arithmétique).
Toutes ces opérations sont considérées comme équivalentes en temps de traitement, et chacune
forme donc une unité de temps ≪ de base ≫propre à chaque machine.

• Exemple : la ligne de code if a<b: a=b**2+1 coûte : 1 comparaison + 1 assignation + 1


calcul de b2 = b × b + 1 addition = 4 opérations élémentaires.

• Remarque : r+=1 (incrémentation) est comptée comme 1 opération élémentaire a alors que
r=r+1 compte b

• Evaluer la complexité d’un algorithme c’est évaluer, ligne par ligne, le nombre d’opérations
élémentaires nécessaire pour mener à bien sa tâche, tout en étant conscient :
➣qu’il faut prévoir le pire des cas (en cas de test par exemple) ;
➣que les lignes présentes dans les indentations de boucles interviendront autant de
fois qu’il y aura d’itérations, et qu’il faut donc toujours essayer de prévoir le nombre de ces
itérations.

• Les résultats seront donnés sous forme de O(données) (≪ grand O ≫), càd du type cte× données
sans chercher détailler la constante (on la majore par la pire situation), on parle (du meilleur
au pire) :
➣de complexité logarithmique si on a un O(données) = cte × ln(données) ;
➣de complexité linéaire si on a un O(données) = cte × données ;
➣de complexité quadratique si on a un O(données2 ) = cte × données 2 ;
➣de complexité exponentielle si on a un O(exp(données)) (le pire des trois).

• Exemple :

1 Calculer une puissance bn :
1 def puissance (b , n ) :
2 res =1
3 for i in range ( n ) :
4 res = res * b
5 return res

On a :
➣1 assignation ligne 2 ;
➣[1 assignation + 1 calcul ligne 4] ×n (boucle ligne 3).
En conclusion, on a une complexité c 2 + 2n = O(n) (linéaire).

2 Compter le nombre de 1 dans une matrice n × n :
1 def compter ( M ) :
2 resultat =0
3 for i in range ( n ) :
4 for i in range ( n ) :
5 if M [ i ][ j ]==1:
6 resultat +=1
7 return resultat

On a :
➣1 assignation ligne 2 ;
a. Modification in place : directement dans la case mémoire pointée par r sans création d’une nouvelle.
b. Doit créer une nouvelle case mémoire pour faire le calcul, et refait pointer r vers cette nouvelle case : c’est
à la fois plus lent et surtout, plus gourmand en mémoire que la modification in place.
c. Peut être grandement améliorée par l’algorithme d’exponentiation rapide.

12/35 MP 2015/2016 — (c) Florent Nicaise


h i
➣ [1 test ligne 5 + 1 incrémentation ligne 6] ×n (boucle ligne 4) ×n (boucle ligne 3).
En conclusion, on a une complexité 1 + [2 × n] × n = O(n2 ) (quadratique) dans le pire des
cas (où la ligne 6 est toujours effectuée).

3 Avec une boucle while : il faut alors pouvoir estimer, ou majorer le nombre d’itérations
comme le montre l’exemple suivant.
1 def division_ eu c li d i en n e (a , b ) :
2 assert a >=0 # genere un message d ’ erreur si a n ’ est pas positif
3 assert b >0 # idem
4 q , r =0 , a
5 while r >= b :
6 r =r - b
7 q +=1
8 return q , r

On a :
➣2 tests lignes 2 et 3 ;
➣2 assignation ligne 4 :
➣[1 test ligne 5 + (1 calcul + 1 assignation ligne 6) + 1 incrémentation ligne 7] ×k
itération, avec k à estimer en fonction des données a,b.

• Remarque : avec les notations de la partie 3.3.1 page 9, on peut montrer par récurrence
que rk = r0 − kb = a − kb et que :
a
➣à l’itération k de sortie rk < b =⇒ < k + 1 ;
b
a
➣donc à l’itération d’avant rk−1 > b =⇒ > k.
b
a
Ainsi : k 6 < k + 1 donc k = E[a/b] (partie entière) et, à l’arrivée une complexité de
b
4 + 4E[a/b] = O(E[a/b]).

3.4 Fonctions def

• Principe général.
1 >>> def nom_fonction ( entrees ) :
2 # les deux points créent une indentation
3 # - >[ instructions à exécuter ]
4 # la procédure s ’ arr^
e te au premier return
5 return ( sortie )

Schématiquement, la fonction est la flèche dans le schéma suivant :

Effectue les instructions


Entrées return résultat
dans l’indentation

résultat

• Remarque :

1 Ble programme sort de la fonction dès qu’il tombe sur un return, ce qui peut donner
des surprises s’ils sont mal placés dans les indentations ;

13/35 MP 2015/2016 — (c) Florent Nicaise



2 les variables autres que celles de l’entrée intervenant dans la procédure sont des variables
dites locales : utilisée de manière interne à la procédure, effacées à la sortie (on parle de
portée locale). Si l’on veut conserver l’état d’une variable x (n’existant pas ailleurs dans le
programme) après la sortie on la déclare comme globale dans la procédure par un global
x situé juste après la première indentation.

• Exemple :

1 Fonction f définie par :
➣Entrée : une variable x ;
➣Sortie : la valeur x+1.
1 >>> def f ( x ) : # Ici l ’ entrée se résume à une variable x
2 return ( x +1) # Ici la sortie se résume à une variable ( contenant x +1)
3
4 >>> f (4)
5 5

• Remarque : peut aussi être défini par la lambda-fonction f = lambda x : x+1



2 Fonction test définie par :
➣Entrée : une liste notée... liste ;
➣Sortie : un booléen resultat qui est True si la liste est réversible (càd se lit pareil dans
les deux sens), False sinon.
1 >>> def test ( liste ) :
2 resultat = True
3 longueur , indice = len ( liste ) ,0
4 while resultat == True and indice <= len ( liste ) /2 -1:
5 if liste [ indice ]!= liste [ longueur -1 - indice ]:
6 resultat = False
7 indice +=1
8 return resultat
9
10 >>> test ([1 ,2 ,2 ,1]) , test ([1 ,2 ,3 ,1])
11 ( True , False )

• Remarque : vu sa sortie, cette fonction est dite booléenne et peut intervenir dans un
test, par exemple dans un ≪ if test(liste): ≫.

3 Fonction recherche définie par :
➣Entrées : deux chaı̂nes de caractères mot et lettres ;
➣Sortie : la liste (éventuellement vide) des indices i où la lettre i de mot vaut lettre.
1 >>> def recherche ( mot , lettre ) : # ici deux entrées
2 sites =[] # liste vide
3 for indice in range ( len ( mot ) ) : # pour parcourir tous les indices
4 if mot [ indice ]== lettre :
5 sites . append ( indice ) # on rajoute l ’ indice à
6 # la liste des sites
7 return ( sites ) # la procédure s ’ arr^e te , avec sortie = sites
8
9 >>> recherche ( ’ marseille ’ , ’e ’)
10 [4 , 8]
11 # oui il y a bien un e aux emplacements 4 et 8

14/35 MP 2015/2016 — (c) Florent Nicaise


3.5 Fonctions récursives

• Un algorithme est dit itératif quand il répète un groupe d’instruction un certains nombre de
fois, elle est en général basée sur une boucle for ou while.

• Il est dit récursif s’il s’appelle lui-même avec d’autres entrées pendant son exécution, pos-
sibilité offerte par tous les langages évolués. Dans l’esprit, il est adapté à toute propriété
mathématique se prouvant par récurrence. A noter que la récursivité n’exclut pas l’itérativité
(on peut avoir des boucles dans une structure récursive).

• En général : la simplicité a est du côté du récursif mais la complexité en temps du côté itératif.

• Les algorithmes récursifs posent les mêmes problèmes que les algorithmes classiques : Des-
cription (les arbres d’appel remplacent les tableaux d’état), terminaison, validité, complexité :
les preuves par récurrences sont naturellement adaptées à ces questions théoriques sur les pro-
grammes récursifs.

3.5.1 Exemple 1 : la factorielle

• Deux versions, l’une itérative, l’autre récursive, de l’implémentation d’une fonction factorielle :
1 def facto_iterat if ( n ) :
2 res =1
3 for i in range (2 , n +1) :
4 res *= i
5 return res
6
7 def facto_recurs if ( n ) :
8 if n ==1: # Initialisatio n
9 return 1
10 else :
11 return n * facto_recurs if (n -1) # Heredite

➣Description :
on peut écrire que :

f r(4) = 4 ∗ f r(3) = 4 ∗ 3 ∗ f r(2) = 4 ∗ 3 ∗ 2 ∗ f r(1) = 4!


11 11 11 9

ou alors on peut représenter graphiquement les appels par un arbre d’appels partant d’une
entrée donnée (par ex. 4) pour décrire les appels successif (pour simplifier, fr=fonction recursive) :

profondeur d’appel

étage −1 étage −2 étage −3

fr(4): fr(3): fr(2): fr(1):


return 4*fr(3) return 3*fr(2) return 2*fr(1) return 1

3x2x1 2x1 1

4x3x2x1 appels en profondeur


retours
a. Voir en TD la résolution du problème des tours de Hanoı̈.

15/35 MP 2015/2016 — (c) Florent Nicaise


➣Terminaison : il faut isoler un variant d’appel , une quantité de type entier, positive,
strictement décroissante à chaque appel.
Ici, n fonctionne clairement : positif tout au long des appels, perdant -1 à chaque appel donc
on est sûr d’arriver à l’initialisation (n = 1) en un temps fini.
comme pour les boucles, on peut noter nk la valeur de n après le k-ème appel et observer
que 1 6 nk = n − k dans l’arbre d’appel, ce qui provoque le retour.
➣Complexité : vérifie une relation de récurrence. Ici, si l’on note C(n) le coût de l’appel à
l’ordre n, alors :
C(n) = 1 + 1 + C(n − 1)
car on a un test (ligne 8), un produit (ligne 11) avant l’appel de C(n−1). Soit C(n) = 2+C(n−1)
(arithmétique) donc
C(n) = C(1) + 2(n − 1) = O(n).

➣Validité : se prouve par récurrence en posant :

P (n) = [f acto recursif (n) = n!]

Initialisation : P (1) vraie par l’initialisation de notre programme.


Hérédité : supposons P (n−1) alors facto recursif (n) renvoie n fois facto recursif(n-1)
= n(n − 1)! = n! par P (n − 1), d’où P (n) DLRR.

3.5.2 Exemple 2 : la suite de Fibonacci

• C’est la suite récurrente linéaire définie par u0 = 0, u1 = 1 et :

∀n dans N, un+2 = un+1 + un .

1 # iteratif
2 def fibo_i ( n ) :
3 if n ==0 or n ==1:
4 return 1 if n ==1 else 0
5 else :
6 a , b =0 ,1 # a joue le role de u_n , b joue le r A~ ´le de u_n +1
7 for i in range (n -1) :
8 a , b =b , a + b # assignation multiple
9 return b
10
11 # recursif
12 def fibo_r ( n ) :
13 if n ==0: # initialisatio n
14 return 0
15 elif n ==1:
16 return 1 # initialisati on
17 else :
18 return fibo_r (n -1) + fibo_r (n -2) # Heredite

• On s’aperçoit sur l’exemple étudié de l’avantage du récursif : simplicité d’écriture, clarté (même
si la possibilité d’assignations multiples allège bien la version itérative)

16/35 MP 2015/2016 — (c) Florent Nicaise


➣Description : on fait un arbre d’appel par exemple pour n = 4 :

2+1=3
fr(3)+fr(2)
1+0
1+1
fr(2)+fr(1) fr(1)+fr(0)
1 0
1+0 1

fr(1)+fr(0) return 1 return 1 return 0


0
1

return 1 return 0

C’est une représentation simplifiée par rapport à l’arbre précédent, on note :


une profondeur de 3 appels récursifs ;
le fait qu’on calcule plusieurs fois par exemple fr(1) (2 fois à l’étage -1, 1 fois à l’étage -2) : ces
redondances font en général très vite exploser les complexités des récursivités comme on le verra.
La programmation dynamique a permet de redresser ce défaut fréquent des fonctions récursives.
➣Terminaison : il faut vérifier qu’il y a un nombre fini d’appels (càd que la taille ou profondeur
de l’arbre d’appels est finie). On isole le variant d’appel constitué de l’entier n qui décroit
strictement (de 1 ou 2) à chaque appel et provoque la sortie (retour dans l’arbre) si n 6 1.
➣Complexité : Si C(n) est le coût d’appel pour obtenir un , on a

C(n) = 3 + C(n − 1) + C(n − 2),

c’est à dire que dans ce cas la suite (C(n))n des complexités est-elle même une suite de Fibonacci.
le cours b nous apprend qu’il existe x, y, z constantes telles que :
√ !n √ !n √ !n
1+ 5 1− 5 1+ 5
C(n) = x · +y· +z ∼x· = x · exp(n · cte)
2 2 2

On remarque que la complexité est géométrique, càd exponentielle, ce qui est énorme.
➣Validité, se fait par récurrence en notant P (n) : [l’appel sur n donne bien le résultat attendu]
sur deux rangs, avec :
Initialisation : P (0) et P (1) vrais.
Hérédité : supposons P (n) et P (n + 1) on obtient P (n + 2).

• Remarque : on peut comparer les efficacités des deux programmes en comparant les temps
d’exécution, grâce au module time :
a. HP
b. Le programme ne permet pas de traiter la relation avec z 6= 0, mais dans ce cas l’idée et qu’une solution est
la somme : d’une solution homogène (càd avec z = 0 : couvert par le cours) + une solution particulière (cherchée
sous la forme d’une constante qui va bien).

17/35 MP 2015/2016 — (c) Florent Nicaise


1 from time import *
2 from matplotlib . pyplot import *
3
4 rapports =[]
5 for n in range (2 ,10) :
6 a = clock ()
7 fibo_i ( n )
8 b = clock ()
9 fibo_r ( n )
10 c = clock ()
11 temps_iterat if =b - a
12 temps_recurs if =c - b
13 rapports . append ( temps_iterat if / temps_recurs if )
14
15 xlabel ( " n " )
16 ylabel ( " temps iteratif / temps recursif " )
17 plot ([ i for i in range (2 ,10) ] , rapports , marker = " o " )

1.4

1.2
temps iteratif/temps recursif

1.0

0.8

0.6

0.4

0.2

0.0
2 3 4 5 6 7 8 9
n

On voit que l’itératif devient très vite + rapide que le récursif (complexité linéaire vs. complexité
exponentielle).

3.5.3 Exemple 3 : partitions d’un entier

• Un exemple plus subtil, où la structure récursive ne se découvre que dans l’analyse du
problème.

• Soit n dans N∗ . On appelle une n-partition toute liste d’entiers non nuls [u1 , . . . , up ] telle que :
p
X
n= ui .
i=1

On souhaite implémenter une fonction partition qui, à une entrée n, renvoie la liste des n-
partitions, par exemple partition(3) doit retourner :

[[1, 1, 1], [1, 2], [2, 1], [3]]

• Remarque : on construit une 4-partition de la manière suivante :


➣on décide qu’elle commence par i dans [[1 ; 3]], puis on rajoute une 4 − i partition ;

18/35 MP 2015/2016 — (c) Florent Nicaise


➣cas particulier : ne pas oublier la 4-partition formée par [4].
Le résultat pour n = 4 se construit à partir des résultats pour k dans [[1 ; 3]] (récurrence forte)
d’où l’idée du programme récursif :
1 def partition ( n ) :
2 if n ==1: # initialisat io n
3 return [ [1] ]
4 else :
5 res =[]
6 for i in range (1 , n ) :
7 for part in partition (n - i ) : # Heredite
8 res . append ([ i ]+ part )
9 res . append ([ n ])
10 return res

3.5.4 Important : limiter le nombre d’appels récursifs

• Une maladresse possible en récursivité est de déclencher plus d’appels récursifs que nécessaire,
augmentant inutilement la complexité.

• Les deux codes qui suivent, destinés à retourner le n-ième terme d’une suite récurrente définie
par u0 = 1 et :
∀n dans N∗ , un = un−1 exp(−un−1 ),
semblent analogues pourtant leurs complexités n’ont rien à voir :
1 def code1 ( n ) :
2 if n ==0:
3 return 1
4 else :
5 return code1 (n -1) * exp ( - code1 (n -1) )
6
7 def code2 ( n ) :
8 if n ==0:
9 return 1
10 else :
11 c = code2 (n -1)
12 return c * exp ( - c )

• Les deux sont récursifs, mais :


➣pour code1, C(n) vaut :
ligne 2 : 1 test ;
ligne 5 : 1 multiplication + 2 C(n − 1) car on appelle code1(n-1) deux fois.
À l’arrivée : C(n) = 2 + 2C(n − 1) donc (arithmético-géométrique : voir section 3.5 page 15)
C(n) = O(2n ) : géométrique = énorme.
➣pour code2, C(n) vaut :
ligne 8 : 1 test ;
ligne 11 : 1 assignation ;
ligne 12 : 1 multiplication + 1 calcul exp + C(n − 1)
À l’arrivée : C(n) = 4 + C(n − 1) donc (arithmétique) C(n) = O(n) : linéaire = très respectable.

• Ainsi, il vaut mieux stocker le résultat d’un appel récursif dans une variable (coût=une
opération élémentaire) plutôt que l’appeler plusieurs fois (coûts= BIG)...

19/35 MP 2015/2016 — (c) Florent Nicaise


3.6 Piles
3.6.1 Présentation

• Un des principaux problèmes en informatique est le stockage des données avec un choix per-
manent entre deux structures de données classiques :
➣la structure de tableau=array : les données sont stockées dans un tableau tab de taille a fixe,
on peut consulter/modifier à tout moment n’importe quelle donnée en appelant tab[i].
➣la structure de pile=stack : on stocke des données dont le nombre est variable, en ne s’autorisant
que deux actions :
⊲ push(L,X) : empiler la donnée L à la fin de la pile L ;
⊲ pop(L) : dépiler, càd enlever le dernier élément de la pile L.

push(L,X)
a g z t X

push 0 1 2 3 4
L
a g z t

0 1 2 3
pop pop(L) valeur du pop
a g z t

0 1 2

• Remarque : chaque appel de ces commandes provoque une modification in place de la pile.

• L’analogue de la structure de pile est une pile d’assiette : on ne peut qu’ajouter une assiette
ou enlever la dernière. Les anglais parlent de LIFO = Last In, First Out.
➣Avantage des tableaux : un accès rapide à toutes les données ;
➣Avantage des piles : rapidité et simplicité d’accès dans tout problème de stockage privilégiant la
dernière information dans l’historique : fonctions undo/redo dans un éditeur, étude d’un problème
de parenthésage (voir section 3.6.4 page 21) ou recherche d’un chemin dans un labyrinthe par
exemple.

• Concrètement, nous stockerons tableaux et piles dans le même type list de Python.

3.6.2 Les quatre fonctions primitives

• Connaı̂tre l’implémentation des 4 fonctions primitives :


1 def push (L , a ) : # fonction push
2 L . append ( a ) # modifie L " in place "
3
4 def pop ( L ) : # fonction pop
5 return L . pop () # L . pop () modifie " in place " et renvoie l ’ element extrait
6
7 def longueur ( L ) : # on peut simplement utiliser len ( L ) avec Python
8 return len ( L )
9
10 def testvide ( L ) :
11 return L ==[]

a. Python autorise cependant des ≪ tableaux de taille variable ≫ avec le type list.

20/35 MP 2015/2016 — (c) Florent Nicaise


• Résoudre un problème à l’aide de piles, c’est proposer un algorithme de résolution n’utilisant
que ces quatres fonctions primitives (plus les structures classiques de programmation : tests,
boucles).

3.6.3 Exemples de programmations de piles

• Voici les implémentations :


➣d’une fonction vide(L) qui vide une pile L : pas de return, mais l’argument L est vidé in
place ;
➣une fonction renverse(L) qui retourne la pile inverse : par exemple renverse([1,2,3]) →
[3,2,1]. Belle aura le défaut de vider la pile sur laquelle elle est appelée ;
➣d’une fonction renverse2(L) qui corrige le défaut de la fonction précédente.
1 def videpile ( L ) :
2 while not testvide ( L ) :
3 pop ( L )
4
5 def renverse ( L ) :
6 Q =[] # creation d ’ une liste vide
7 while len ( L ) !=0: # alternative a testvide
8 push (Q , pop ( L ) ) # attention : le pop depile l ’ argument L dans la fonction
9 return Q
10
11 from numpy import * # permet d ’ utiliser la commande copy ( creation d ’ une copie
independante d ’ un objet )
12
13 def renverse2 ( L ) :
14 Q =[] # creation d ’ une liste vide
15 M = list ( copy ( L ) ) # on cree une copie de L sur laquelle on pourra travailler
sans modifier L
16 while len ( M ) !=0:
17 push (Q , pop ( M ) ) # c ’ est M qu ’ on depile , par l ’ argument L
18 return Q

3.6.4 Exemple : examen de parenthésages

• Un parenthésage est une chaı̂ne de caractères constituée de parenthèses ouvrantes ( ou fer-


mantes ). On dit qu’il est bon ssi :
➣à chaque ouvrante répond par la suite une unique fermante ;
➣et vice-versa.
Ainsi, "(()())" est un bon parenthésage alors que "(()()))" ne l’est pas (dernière fermante
isolée).

• Nous voulons rédiger une fonction parenthesage(mot) qui, pour un argument mot comme
ci-dessus retourne :
➣False si l’on n’a pas un bon parenthésage (sinon True) ;
➣affiche les tuples (j,i) correspondant aux sites (ouvrante,fermante) associés.
012 34 5
Ainsi, parenthesage("( ( ) ( ) )") doit afficher (1,2),(3,4),(0,5) puis True.

• Nous allons parcourir mot en faisant évoluer une pile L au début vide :
➣où l’on empilera les sites où il y a des ouvrantes ;
➣que l’on dépilera à chaque site où il y a une fermante, en renvoyant un affichage.
Ceci donnerait avec par exemple "(()())" le tableau d’états :

21/35 MP 2015/2016 — (c) Florent Nicaise


Site i Valeur mot[i] Action sur la pile L
0 "(" [0] ← push(L,0)
1 "(" [0,1] ← push(L,1)
2 ")" [0] → pop(L) et affiche (pop(L),2)
3 "(" [0,3] ← push(L,3)
4 ")" [0] → pop(L) et affiche (pop(L),5)
5 ")" [] → pop(L) et affiche (pop(L),0)

Voici l’implémentation :
1 def parenthesage ( mot ) :
2 L =[]
3 i =0
4 for i in range ( len ( mot ) ) :
5 if mot [ i ]== " ( " :
6 push (L , i ) # on empile les sites ou il y a des ouvrantes
7 else : # dans ce cas on est sur un site avec une fermante
8 if L ==[]: # s ’ il n ’y a plus d ’ ouvrante a refermer
9 return False
10 else :
11 print ( pop ( L ) ,i ) # on depile et on affiche le couple site
ouvrant , site fermant
12 i +=1
13 if not testvide ( L ) : # s ’ il reste des ouvrantes non refermees
14 return False
15 else :
16 return True

C’est un exemple où seule le sommet de la liste est intéressant, d’où la programmation utilisant
les fonctions primitives sur les piles.

3.7 Tris

• Algorithmes by Nicolas Chireux : les complexités sont à maı̂triser :


1 from math import *
2 import sys
3 import random
4 from time import time
5
6 # Generation d ’ un tableau aleatoire
7 def tab_alea (n , mini =0 , maxi =10**6) :
8 return [ random . randint ( mini , maxi ) for k in range ( n ) ]
9
10 t= tab_alea (100 ,0 ,1000)
11 print ( t )
12
13 # Tri a bulle
14 def tri_bulle ( t ) :
15 perm = True
16 while perm :
17 perm = False
18 for j in range ( len ( t ) -1) :
19 if t [ j ] > t [ j +1]:
20 t [ j ] , t [ j +1]= t [ j +1] , t [ j ]
21 perm = True
22 return ( t )
23 t0 = time ()
24 print ( " Tri a bulle \ n " , tri_bulle ( tab_alea (1000 ,0 ,10000) ) )
25 t1 = time ()
26 print ( " Temps d ’ execution : %.20 f " %( t1 - t0 ) )
27
28 # Tri par selection

22/35 MP 2015/2016 — (c) Florent Nicaise


29 def indice_mini (m ,i , j ) :
30 " " " Renvoie le plus petit indice k dans [ i , j [ tel que m [ k ]= min ( t [ i : j ]) " " "
31 i_min = i
32 for k in range ( i +1 , j ) :
33 if m [ k ] < m [ i_min ]:
34 i_min = k
35 return i_min
36
37 def tri_selection ( t ) :
38 for i in range ( len ( t ) ) :
39 i_m = indice_mini (t ,i , len ( t ) )
40 t [ i ] , t [ i_m ]= t [ i_m ] , t [ i ]
41 return t
42
43 t2 = time ()
44 print ( " Tri par selection \ n " , tri_selection ( tab_alea (1000 ,0 ,10000) ) )
45 t3 = time ()
46 print ( " Temps d ’ execution : %.20 f " %( t3 - t2 ) )
47
48 # Tri par insertion
49 def place (x , m ) :
50 " " " Renvoie l ’ indice auquel inserer l ’ element x dans la liste m pour que m
reste triee " " "
51 ind =0
52 while ind < len ( m ) and x > m [ ind ]:
53 ind +=1
54 return ind
55
56 def tri_insertion ( t ) :
57 t_triee =[]
58 for elt in t :
59 t_triee . insert ( place ( elt , t_triee ) , elt )
60 return t_triee
61
62 t4 = time ()
63 print ( " Tri par insertion \ n " , tri_insertion ( tab_alea (1000 ,0 ,10000) ) )
64 t5 = time ()
65 print ( " Temps d ’ execution : %.20 f " %( t5 - t4 ) )
66
67 # Tri par insertion en place
68 def t r i _ i n s e r t i o n _ e n _ p l a c e( t ) :
69 for k in range (1 , len ( t ) ) :
70 i=k
71 while i >0 and t [ i ] < t [i -1]:
72 t [ i ] , t [i -1]= t [i -1] , t [ i ]
73 i -=1
74 return t
75
76 t6 = time ()
77 print ( " Tri par insertion en place \ n " , t r i _ i n s e r t i o n _ e n _ p l a c e( tab_alea
(1000 ,0 ,10000) ) )
78 t7 = time ()
79 print ( " Temps d ’ execution : %.20 f " %( t7 - t6 ) )
80
81 # Tri par fusion
82 def fusionne ( t1 , t2 ) :
83 " " " Renvoie la fusion de deux listes triees l1 et l2 " " "
84 m =[]
85 ind1 =0
86 ind2 =0
87 while ind1 < len ( t1 ) and ind2 < len ( t2 ) :
88 if t1 [ ind1 ] < t2 [ ind2 ]:
89 m . append ( t1 [ ind1 ])
90 ind1 +=1
91 else :
92 m . append ( t2 [ ind2 ])

23/35 MP 2015/2016 — (c) Florent Nicaise


93 ind2 +=1
94 return m + t1 [ ind1 :]+ t2 [ ind2 :]
95
96 def tri_fusion ( t ) :
97 n = len ( t )
98 if n <=1:
99 return t # critere de sortie de l ’ appel recursif
100 return ( fusionne ( tri_fusion ( t [: n //2]) , tri_fusion ( t [ n //2:]) ) )
101
102 t8 = time ()
103 print ( " Tri par fusion \ n " , tri_fusion ( tab_alea (1000 ,0 ,10000) ) )
104 t9 = time ()
105 print ( " Temps d ’ execution : %.20 f " %( t9 - t8 ) )
106
107 # Quicksort
108 def quicksort ( t ) :
109 if len ( t ) <=1:
110 return t # critere de sortie de l ’ appel recursif
111 pivot = t [0] # le pivot est le premier element
112 # creation des listes gauche ( elements plus petits que pivot ) , listes gauche (
elements egaux au pivot ) , listes droite ( elements plus grands que pivot )
113 tg , t_pivots , td =[] ,[] ,[]
114 for elt in t :
115 if elt < pivot :
116 tg . append ( elt )
117 elif elt == pivot :
118 t_pivots . append ( elt )
119 else :
120 td . append ( elt )
121 return quicksort ( tg ) + t_pivots + quicksort ( td )
122
123 t10 = time ()
124 print ( " Quicksort \ n " , quicksort ( tab_alea (1000 ,0 ,10000) ) )
125 t11 = time ()
126 print ( " Temps d ’ execution : %.20 f " %( t11 - t10 ) )
127
128 # Quicksort en place
129 def partitionne (m , debut , fin , ind_pivot ) :
130 pivot = m [ ind_pivot ]
131 i , j = debut +1 , fin -1
132 m [ ind_pivot ] , m [ debut ]= m [ debut ] , m [ ind_pivot ]
133 while i <= j :
134 if m [ i ] <= pivot :
135 i +=1
136 else :
137 m [ i ] , m [ j ]= m [ j ] , m [ i ]
138 j -=1
139 m [i -1] , m [ debut ]= m [ debut ] , m [i -1]
140 return i -1
141
142
143 def quicksort2 ( t ) :
144 def quicksort_ e n_ p la c e (t ,d , f ) :
145 if (f -d >1) :
146 ind_pivot = partitionne (t ,d ,f , d )
147 quicksort_e n _p l ac e (t ,d , ind_pivot )
148 quicksort_e n _p l ac e (t , ind_pivot +1 , f )
149 quicksort_ en _ pl a ce (t ,0 , len ( t ) )
150 return t
151
152
153 t12 = time ()
154 print ( " Quicksort en place \ n " , quicksort2 ( tab_alea (1000 ,0 ,10000) ) )
155 t13 = time ()
156 print ( " Temps d ’ execution : %.20 f " %( t13 - t12 ) )
157

24/35 MP 2015/2016 — (c) Florent Nicaise


158
159
160 def mediane (t , milieu ) :
161 n = len ( t )
162 place = partitionne (t ,0 , n ,0)
163 if place == milieu :
164 print ( t [ place ])
165 return ( t [ place ])
166 else :
167 if place > milieu :
168 mediane ( t [0: place ] , milieu )
169 else :
170 mediane ( t [ place +1:] , milieu - place )
171
172 tt =[7 ,1 ,8 ,2 ,4 ,9 ,3 ,12 ,18 ,25 ,26 ,5 ,0 ,51 ,4]
173 print ( mediane ( tt , len ( tt ) //2) )

3.8 Bases de données/SqL

• Remarque : By Nicolas Chireux.

• Une requête SQL classique se présente sous la forme SELECT ...(3) FROM ...(1) WHERE
...(2)
➣Le champ (1) du FROM se complète en premier en répondant à la question suivante : dans
quelles relations sont les attributs dont j’ai besoin ?
➣Le champ (2) du WHERE se complète ensuite en répondant aux questions : ai-je des condi-
tions sur les valeurs d’attributs exprimées dans ma requête ? ai-je plusieurs relations
dans ma clause FROM ? Si oui, quelles sont les conditions de jointure(s) ? Si toutes
les réponses sont négatives la clause WHERE n’apparaitra pas.
➣Enfin le champ (3) du SELECT se complète en dernier en répondant à la question : quel
résultat souhaite voir l’utilisateur (schéma du résultat) ?

N Instruction Argument Résultat


6 SELECT liste et/ou expressions attributs Aj Projection de l’ensemble obtenu en
et/ou fonctions sur attributs Ap (5) sur les Aj , calcul des expressions,
calcul des fonctions (appliquées aux
groupes s’il y en a) sur Ap
1 FROM liste de relations Ri Produit cartésien des relations Ri
2 WHERE conditions sur les tuples Ci Sélection de tuples de (1) respectant
la condition Ci
3 GROUP BY liste d’attributs Ak ⊇ Aj Partitionnement de l’ensemble ob-
tenu en (2) suivant les valeurs Ak
4 HAVING conditions sur groupes-fonctions C2 Sélection de groupes de (3) vérifiant
C2
5 ORDER BY liste d’attributs A1 ou numéro Tri des tuples obtenus en suivant les
d’ordre dans le SELECT valeurs A1

Les conditions de recherche dans le WHERE (sélection de tuples) ou le HAVING (sélection de


groupes) peuvent être élémentaires ou composées par les opérateurs AND, OR et NOT. Elles
doivent obligatoirement être VRAIES ou FAUSSES.

Les conditions élémentaires sont :


• une comparaison Attribut/Valeur ou Attribut/Attribut du type =, <, <=, >, <=, <>
• l’appartenance à un intervalle : BETWEEN

25/35 MP 2015/2016 — (c) Florent Nicaise


• l’identité à une chaı̂ne de caractères : LIKE. Les ”jokers” sont % qui remplace un nombre
variable de caractères et qui remplace un seul caractère.
• la nullité (pas d’entrée) : IS NULL
• l’appartenance à un domaine : IN
• la quantification : EXISTS, ANY, ALL

• Domaines. Les domaines utilisés dans les bases de données sont conformes aux types classi-
quement utilisés dans les langages de programmation, à savoir :
• Entier : INTEGER
• Décimal : DECIMAL (m,n)où m est le nombre de chiffres et n le nombre de chiffres après la
virgule. Ainsi DECIMAL(4,2) peut représenter des chiffres comme 99,99
• Réel flottant : FLOAT
• Chaı̂ne de caractères : CHAR (n) et VARCHAR(n). Les CHAR font systématiquement n
caractères (les chaı̂nes plus courtes sont complétées par des espaces, les VARCHAR sont
taillés au plus juste dans la limite des n caractères
• Date : DATE (dans la norme SQL2 !). Ce type normalisé très tard possède une manipulation
sensible. Il faut bien connaı̂tre le format d’expression de la date et sa langue.Le 1er janvier
2010 peut par exemple s’exprimer en ’2010-01-01’ ou ’01-JAN-2010’ ou ’1/1/10’ ...
• il n’y a pas de type booléen en SQL2

• Création d’un schéma de relation. L’ordre de création de relation minimale suit la syntaxe
suivante :
CREATE TABLE Nom
( Attribut 1 Type,
...,
Attribut N Type) ;

4 Compléments sur le cours de 2nde année


4.1 Générer de l’aléatoire/probabilités

• Tout vient du package random : from random import ∗

Action Entrée Sortie


Entier aléatoire ds [1; 5[ randint(1,5) 3
Flottant aléatoire dans [0, 1[ random() 0.243
Génération tableau 3 x 2
random.randint(1,5,(3,2)) [[2,3,1],[1,1,4]]
d’entiers aléatoires ds [[1 ; 4]]
4 tirages suivant
random.rand(4) [0.23423,...]
une loi uniforme sur [0, 1]
4 tirages suivant
random.randn(4) [-2.124,...]
une loi normale N (0, 1)
50 tirages suivant
random.binomial(n,p,50) [4,34,...]
une loi binomiale B(n, p)
25 tirages suivant
random.geometric(1/2,25) [2, 5, ...]
une loi géométrique G (p)
25 tirages suivant
random.poisson(1/2,25) [ 6, 9, ...]
une loi de Poisson P(10)

• Remarque : pour une matrice aléatoire, on génère d’abord une liste que l’on reshape (voir
section 2.1.2 page 5).

26/35 MP 2015/2016 — (c) Florent Nicaise


• Exemple : histogramme de 100 tirages a=random.binomial(50,1/2,100) par hist(a) puis
show() :

4.2 Tracés 2d
a
from matplotlib.pyplot import ∗

• Principe général d’un tracé :

plot( [x1 ,...,xn ] , [y1 ,...,yn] )


trace la ligne brisée joignant les points M1 (x1 , y1 ), . . . , Mn (xn , yn )

• Remarque :

1 typiquement (voir exemple ci-dessous) la liste des abscisses est générée comme dans la
section 2.1.2 page 5, avec un linspace et celle des ordonnées est une λ-fonction de la
première ;

2 Bles graphiques ne s’affichent qu’à la commande show().

Commandes Syntaxe
Générer une légende axe des x (ou y) xlabel("texte")
Générer une grille grid()
Générer une ligne brisée de sommets plot(list abscisses,list ordonnées,options)
d’abscisse/ordonnées connues voir plus bas pour les options de tracé
Générer un tracé de y = f (x) sur x dans [a, b] x=linspace(a,b,20)
discrétisé à 20 points plot(x,f(x),options)
Réglages axes axis([xmin,xmax,ymin,ymax])
Afficher les tracés show()
Histogramme d’une liste liste hist(liste)
Vider les tracés générés clf() (clear figure)

• Options de tracé :
a. Des fonctions/types présentées dans ce document font partie de ce module qu’il faudra charger. La syn-
taxe présentée active automatiquement les fonctions/types. En cas de problème, on pourra toujours taper
import matplotlib.pyplot as pl, np étant une abréviation arbitraire. Les fonctions/types associés devront
impérativement être précédées du préfixe pl, par exemple plot deviendra pl.plot.

27/35 MP 2015/2016 — (c) Florent Nicaise


Options syntaxe
Epaisseur ligne linewidth="4" pour 4 pixels
Style tiret ou pointillés linestyle="dashed" ou "dotted"
Couleur color="blue"
label="Texte" (faire legend(loc=0)
Associer une légende
avant pour un bon emplacement
Désactiver lignes linestyle="none"
marker="o",markersize=choix
Activer marqueurs aux sommets
autres marqueurs ∗, x

• Un petit exemple :
1 # -* - coding : utf -8 -* -
2
3 from numpy import *
4 from matplotlib . pyplot import *
5 f = lambda x : sin ( x ) # declaration fonction
6 # #### BEL EMPLACEMENT DE LEGENDES
7 legend ( loc =0)
8 # #### LEGENDES SUR LES AXES
9 xlabel ( " x " )
10 ylabel ( " y " )
11 # #### GENERATION D ’ UN TRIANGLE A (0 ,0) ,B ( pi ,0) ,C ( pi /2 ,1)
12 absc =[0 , pi , pi /2 ,0]
13 ordo =[0 ,0 ,1 ,0]
14 triangle = plot ( absc , ordo , linestyle = " dashed " , marker = " o " , label = " Triangle " )
15 # #### GENRATION y = f ( x )
16 abscisses = linspace (0 ,2* pi ,50) # discretisati on A~ 50 pts
17 ordonnees = f ( abscisses ) # generation ordonnees
18 graphe_sinus = plot ( abscisses , ordonnees , linewidth = " 3 " , label = " sinus " )
19 # #### ET MAINTENANT ON AFFICHE
20 show ()

donne :

4.3 Autres tracés


On peut copier/coller/adapter des codes à partir de la page :
http://matplotlib.org/gallery.html

28/35 MP 2015/2016 — (c) Florent Nicaise


4.4 Mesurer le temps

• Tout vient du package time : from time import ∗

• Peu de choses à savoir :


(i) a=clock() : stocke dans a le temps indiqué par l’horloge interne ;
(ii) on écrit un [bloc] d’instructions ;
(iii) b=clock() : pareil ;
La différence b-a donne alors le temps qui s’est écoulé entre les lignes (i) et (iii) à l’exécution,
soit le temps de calcul demandé par le [bloc] (ii).

• Exemple : voir section 3.5.2 page 16.

4.5 Manipulation de fichiers/répertoires

• Gestion du répertoire courant avec le module import os .

• Remarque : dans les fichiers, le symbole \n désigne un retour à la ligne.

Action Entrée Sortie


Refermer/sauvegarder truc.close() Comme dit
Gérer répertoire courant import os Charge le module adéquat
Liste fichiers ds répertoire courant os.listdir() Comme dit
Afficher répertoire courant os.getcwd() Comme dit
Déplace le répertoire courant
Changer répertoire courant os.chdir("C:\skynet\Document\")
à l’adresse indiquée

Bil y a parfois un bug sur la donnée des chemins ; par exemple "C:\Users\Documents\" peut
poser problème. L’explication est que le groupe \U est une commande reconnue et automatique-
ment executée par l’éditeur/encodeur (qui bugge car elle est hors-propos). Le bug se résout en
rajoutant un ≪ r ≫ au début du chemin, en l’ocurrence en changeant en :
r"C:\Users\Documents\"

Action Entrée Sortie


Stockage dans fichier
Charger en mode lecture fichier=open("chemin","r")
en mode ”Read”
Charger fichier en Stockage dans fichier
truc=open("fichier","w")
mode écriture (Befface contenu) en mode ”Write”
"Salut !\n"
Lire la prochaine ligne fichier.readline()
(un \n est un retour à la ligne)
Génère la liste ["Salut !\n","Ca va ?"]
fichier.readlines()
de toutes les lignes (un \n est un retour à la ligne)
Stocker ligne ligne=fichier.readlines()[0] Sauvegarde 1ère ligne
Sépare selon espaces
Séparer ligne en mots ligne.split(" ")
(ou autre)
Rajoute "Youpi !" dans truc
Écrire dans fichier fichier.write("Youpi !")
Bpenser à refermer
Sauvegarde
Sauver fichier fichier.close()
le répertoire courant
Sauvegarde la figure dans
Sauver figure savefig("nom fichier") le répertoire courant
(format .png)

29/35 MP 2015/2016 — (c) Florent Nicaise


• Exemple : récupération des phrases dans un fichier, création de la liste des premiers mots.
1 import os # permettant de gerer le repertoire . Les commandes relatives
2
3 os . chdir ( r ’C :\ Users \ Skynet II \ Documents \ Cours 2014 -2015\ Info ’)
4
5 fichier = open ( ’ texte . txt ’ , ’r ’) # ouverture mode lecture
6 lignes = fichier . readlines () # Creation de la liste des lignes
7
8 premiersmots =[]
9 for ligne in lignes :
10 ligne = ligne . split ( " " ) # séparation de la phrase en mots , on coupe aux
espaces
11 premiersmots . append ( ligne [0])

4.6 Traitement d’image

• On commencera tous les documents par l’en-tête chargeant les modules nécessaires :
1 from numpy import *
2 from pylab import *
3 import os # module gerant le repertoire
4 from skimage import * # module gerant les images
5 from skimage import io # module permettant de gerer les niveaux de gris
6
7 os . chdir ( " mettez l ’ adresse de votre repertoire " ) # modifie le repertoire courant
8 # si la ligne precedente bugge , mettez un r devant l ’ adresse
9 # par exemple " C :\ User [...]" devient r " C :\ User [...]

4.6.1 Générer des images matricielles

• Créer une image matricielle.


➣En niveaux de gris. On génère une image matricielle (remplies de 0 ou 1) de taille dx × dy
comme un tableau tab=zeros((dx,dy) tab=ones((dx,dy)) initialement rempli de 0=noir ou
de 1=blanc. L’élément ligne i colonne j est un pixel est donc l’intensité de gris est le flottant a
de [0, 1] égal à tab[i,j]. On peut, à tout moment :
➣modifier l’intensité de gris d’un ou plusieurs pixels (slicing comme dans l’exemple ci-dessous) ;

➣afficher le résultat via la commande io.imshow(tab) qui affiche en niveau de gris.

a. Sur la bibliothèque PIL la plus connue, l’intensité est un entier variant de 0=noir à 255=blanc.

30/35 MP 2015/2016 — (c) Florent Nicaise


0 1 2 j 4 0 1 2 3 4
dy dy
0 0

1 1

i 2

3 3

4 4

dx tab[0,4]=0.5
tab=ones((5,5)) tab[2:4,1:4]=0

tab[i,j] = flottant entre 0=noir et 1=blanc

➣En couleurs. Même principe, mais la couleur de chaque pixel tabi,j est une liste [R,G,B] =
intensité Red/Blue/Green dans [0,1]. Pour créer un tel tableau de taille dx × dy, par exemples
remplis de pixels blancs = [1,1,1], on utilise tab=ones((dx,dy,3)).

Le format d’un tableau tab par tab.shape, dans l’exemple ci-dessus on obtiendra (5,5).
0 1 2 j 4 0 1 2 3 4
dy dy
0 0

1 1

i 2

3 3

4 4

dx tab[0,4]=[0,0,1]
tab=ones((5,5)) tab[2:4,1:4]=[1,0,0]

tab[i,j]=[R,G,B] : intensités Red/Green/Blue dans [0,1]

L’affichage peut se faire à tout moment avec imshow(tab) mais BPython a tendance à faire des
fondus d’affichages entre les pixels voisins, qui peuvent mener à bien d’autres figures que celle
que vous attendez. On annule ces corrections via imshow(tab,interpolation="nearest").

31/35 MP 2015/2016 — (c) Florent Nicaise


4.6.2 Capturer/modifier/sauvegarder des images existantes
Par défaut, nous travaillerons avec des images au format a .png, que nous pouvons convertir en
tableau de pixel comme ci-dessus pour les modifier :
➣tab=io.imread("fete.png",as grey="True") pour une capture en niveaux de gris ;
➣tab=imread("fichier.png") pour une capture en couleurs.
La conversion se fait en un tableau modifiable du type précédent :

0 j
dy

dx


 [x, y, z] avec x,y,z intensités RGB dans [0, 1]
tab[i, j] = ou
x dans [0, 1] : intensité de gris

• Remarque :

1 immédiatement demander tab.shape pour voir le format dx × dy de l’image, et si elle est
codée en couleurs ou pas ;

2 il est souvent commode de créer une copie indépendante du tableau initial pour le modifier,
via copie=copy(tab) ;

3 après modification, on sauvegarde le résultat avec savefig("nom que vous voulez.png").

4.6.3 Résumé des commandes

• Commandes utiles :
a. C’est la seule extension qui marchera sur toutes les machines, mais normalement tous les formats sont
accessibles.

32/35 MP 2015/2016 — (c) Florent Nicaise


Action Entrée Sortie
Générer tableau blanc RGB tab=ones((dx,dy,3)) Tableau d’intensité [0,0,0]=noir
Générer tableau blanc NG tab=ones((dx,dy)) Tableau d’intensité 0=noir
Générer tableau noir RGB tab=zeros((dx,dy,3)) Tableau d’intensité [0,0,0]=noir
Générer tableau noir NG tab=zeros((dx,dy)) Tableau d’intensité 0=noir
Convertir .png → tableau RGB tab=imread("fichier.png") tab devient un array
tab=io.imread("fichier.png"
Convertir .png RGB → tableau NG tab devient un array
,as grey=True)
Générer copie tab2=copy(tab) Crée une copie modifiable
[dx,dy, 3] pour RGB
Format tableau tab.shape
[dx,dy] pour NG
Sont les deux 1ères coord
Trouver dx, dy dx,dy=tab.shape[0:2]
de a.shape
Slicing tableau part=tab[debx:finx,deby:finy] Crée un sous-tableau part
imshow(tab) avec option
Afficher un tableau RGB interpolation="nearest" Ouverture ds une fenêtre
si nécessaire
io.imshow(tab) avec option
Afficher un tableau NG interpolation="nearest" Ouverture ds une fenêtre
si nécessaire
Sauvegarde figure →.png savefig("image.png") Dans rép. courant
Réinitialiser figure clf() Vide l’image courante

4.6.4 Un exemple de traitement local d’image

• Principe général d’un traitement d’image connue sous forme d’un tableau tab. En
général, mais ce n’est pas obligatoire :

1 on repère le format dx,dy=tab.shape[0:2] ;

2 on crée une copie copie ;

3 on parcourt la copie à l’aide de deux boucles imbriquées, en modifiant copie[i,j] ;

4 on retourne et/ou on affiche copie dans le mode désiré.

1 def traitement ( tab ) :


2 dx , dy = tab . shape [0:2]
3 cop = copy ( tab )
4 for i in range ( dx ) :
5 for j in range ( dy ) :
6 cop [i , j ]= # la on fait ce qu ’ on veut
7 imshow ( cop ) # si on veut afficher en couleurs
8 io . imshow ( cop ) # si on veut afficher en NB
9 return cop # si on veut retourner quelque chose

• Exemple : floutage d’une image. Nous travaillons, pour simplifier, avec des images en
niveaux de gris. L’idée du floutage est de :
➣travailler sur une copie copie de l’image tab ;
➣remplacer l’intensité de chaque pixel copie[i,j] par la somme des intensités immédiatement
voisines + la sienne, toutes pondérées par 1/9 pour en faire la moyenne : la matrice 3x3 associée
est appelé filtre du traitement d’image.

33/35 MP 2015/2016 — (c) Florent Nicaise


j j

1/9 1/9 1/9


111
000
000
111
i 1/9 1/9 1/9 000
111
000
111
i
0000000000000
1111111111111
000
111
0000000000000
1111111111111
1/9 1/9 1/91111111111111
0000000000000
0000000000000
1111111111111
0000000000000
1111111111111

tab copie

• Exemple : sur l’image en niveaux de gris, de format (397, 595) :

50

100

150

200

250

300

350

0 100 200 300 400 500

Le floutage donne :

50

100

150

200

250

300

350

0 100 200 300 400 500

34/35 MP 2015/2016 — (c) Florent Nicaise


4.7 Programmation orientée objet (POO)

• Voici un exemple de definition d’une classe ≪ vecteurs ≫, dont les instances (=représentants)
ont trois attributs : abscisse, ordonnée et nom.
1 class vecteur : # nom de la classe
2
3 def __init__ ( self ,a ,b , c ) : # " methode constructeur " : self designe l ’
instance de la classe ( non negociable ) , ici d A~ finiec par trois attributs
notes arbitrairem en t a , b , c
4 self . coord = [a , b ] # creation d ’ un attribut " coord "
5 self . nom = c # nomination du troisieme
6
7 def __repr__ ( self ) : # " methode representati on "
8 return " Vecteur " + self . nom + " =[ " + str ( self . coord [0]) + " ," + str ( self . coord
[1]) + " ] " # le retour doit etre une str
9
10 def scalaire ( self , t ) : # methode speciale modifiant les attributs de l ’
instance self en argument
11 self . coord [0]= self . coord [0]* t # modification de la premiere coordonnee
12 self . coord [0]= self . coord [0]* t # modification de la seconde
13 # pas besoin de retour
14
15 def somme ( self , self2 ) : # methode speciale construisant une instance de la
classe sans modifier les instances appelees
16 x , y = self . coord
17 n = self . nom
18 xp , yp = self2 . coord
19 np = v . nom
20 return vecteur ( x + xp , y + yp , n + " + " + np ) # retour d ’ une instance
21
22 u= vecteur (1 ,2 , ’u ’) # exemple creation d ’ une instance de la classe vecteur
23 u # provoque l ’ appel de la methode de representati o n
24 u. scalaire (2) # exemple d ’ application d ’ une methode speciale a l ’ instance

BLes méthodes spéciales à une classe doivent être appelées avec le nom de la classe en préfixe
càd que pour une instance v de la classe vecteur :
➣Python ne comprendra pas scalaire(v,2) pour appliquer une méthode spéciale à la classe ;

➣mais vecteur.scalaire(v,2) ;
➣autre syntaxe acceptable : v.scalaire(2).

4.8 Calcul scientifique (HP)

• Les commandes qui suivent sont HP mais peuvent être pratiques :

Action Entrée Sortie


Valeur approchée > import scipy.integrate as spi
Z b Valeur approchée
> f = lambda x : exp(-x) Tuple
f Majoration de l’erreur
a
> spi.quad(f,0,Infinity)
Résolutions Eq. diff. COMING SOON COMING SOON

35/35 MP 2015/2016 — (c) Florent Nicaise

Vous aimerez peut-être aussi