Polycop Python

publicité
ENSTA Bretagne
2, rue François Verny
29806 BREST cedex
FRANCE
Tel +33 (0)2 98 34 88 00
www.ensta-bretagne.fr
Support de cours
Formation
Continue
Avril 2014
Python
de la calculatrice à la programmation
structurée
Arnaud Coatanhay et Christophe Osswald
[email protected]
1. Python : langage informatique
2. Une calculatrice polyvalente
3. Structures algorithmiques
4. Bibliothèques
5. Langage objet
6. Pour aller plus loin
Index
Bibliographie
5
11
50
74
87
96
105
109
Table des matières
Le Python, c’est bon
Remerciements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
4
1 Python : quelle place parmi les langages informatiques
1.1 Histoire du langage . . . . . . . . . . . . . . . . . . . . . .
1.2 Caractéristiques du langage . . . . . . . . . . . . . . . . .
1.3 Python et les autres langages . . . . . . . . . . . . . . . .
1.4 Développer avec Python(x,y) . . . . . . . . . . . . . . . .
1.5 Développer sans Python(x,y) . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
5
6
6
7
9
2 Une calculatrice polyvalente
2.1 Manipuler des nombres . . .
2.2 La bibliothèque Numpy . .
2.3 Définition des matrices . . .
2.4 Manipulation des matrices .
2.5 Tracer des courbes . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
11
11
17
21
25
33
.
.
.
.
.
.
.
50
51
53
55
58
60
68
69
.
.
.
.
74
74
74
75
82
.
.
.
.
.
.
.
.
.
.
3 Structures algorithmiques
3.1 Types de données dynamiques .
3.2 Boucles et conditionnelles . . .
3.3 Définition de fonction . . . . .
3.4 Lancement d’un programme . .
3.5 Algorithmes de tri . . . . . . .
3.6 Modules . . . . . . . . . . . . .
3.7 Simulations numériques . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4 Bibliothèques de haut niveau
4.1 Gestion du temps par time . . . . .
4.2 Utilisation des fichiers en mode texte
4.3 PIL : traitement d’image . . . . . . .
4.4 Sympy . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5 Langage objet
87
5.1 Variables d’instance . . . . . . . . . . . . . . . . . . . . . . . . 88
5.2 Méthodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
2
5.3
5.4
5.5
5.6
5.7
5.8
Constructeur . . . . . . . . . . . .
Destructeur : ramasse-miette . . .
Surcharge d’opérateur . . . . . . .
Documention et interrogation . . .
Héritage . . . . . . . . . . . . . . .
Exemple : géométrie par les objets
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
88
89
90
90
91
92
6 Pour aller plus loin
6.1 Analyse de texte par expressions régulières
6.2 Interrogation du web et format HTML . . .
6.3 Interaction avec le système d’exploitation .
6.4 Utilisation de fichiers par pickle . . . . . .
6.5 Bases de données . . . . . . . . . . . . . . .
6.6 Passage de Python 2.x à Python 3.x . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
96
. 96
. 97
. 98
. 98
. 99
. 100
Index
105
Bibliographie
109
3
Le Python, c’est bon
Sommaire
Remerciements
4
C
e fascicule s’adresse à des scientifiques – avec une certaine aisance
en mathématiques – plus qu’à des développeurs – qui connaîtraient
déjà d’autres langages que Python. C’est pourquoi le second chapitre
traite de la représentation des nombres en Python comme des matrices par
numpy et va jusqu’au tracé des fonctions par une bibliothèque de haut niveau,
matplotlib.
Il est construit pour suivre sensiblement le même ordre que les quatre
demies journées du stage de formation : le troisième chapitre fait passer de la
calculatrice à la programmation, et le quatrième présente des fonctionnalités
de Python de haut niveau qui seront utilisées dans le cadre du stage
Le cinquième chapitre permet d’entrer dans la programmation objet, incoutournable lorsque le projet dépasse le millier de lignes. Le sixième présente
des fonctionnalités qui sont utiles dans de nombreuses situations, mais un peu
moins durant ces deux jours.
Remerciements
Les auteurs tiennent à remercier Irvin Probst, qui a conduit une large
part des étudiants de l’ENSTA Bretagne à pratiquer l’analyse numérique et le
traitement de données en Python. Une grande partie de ce document n’aurait
pas pu voir le jour sans ses conseils avisés.
Les auteurs remercient Rodéric Moitié, longtemps en charge de l’enseignement de l’algorithmique et de la recherche opérationnelle à l’ENSTA Bretagne,
et qui a contribué largement à la section sur les tris.
Les auteurs remercient également les participants des éditions précédentes
pour leur enthousiasme et leurs questions avisées.
4
1
Python : quelle place parmi les langages
informatiques
Sommaire
1.1
1.2
1.3
1.4
1.5
1.1
Histoire du langage
Caractéristiques du langage
Python et les autres langages
Développer avec Python(x,y)
Développer sans Python(x,y)
5
6
6
7
9
Histoire du langage
L
a première version de Python date de 1991, développée par Guido Van
Rossum. Le nom du langage est un hommage au Monty Python’s Flying
Circus.
Il utilise une syntaxe très légère, inspirée d’ABC. Le langage dispose de très
peu de types de données, mais est riche en structures de données dynamiques,
bien intégrées à la syntaxe.
La license sous laquelle il est distribué se stabilise en 2001 sur une licence
libre compatible avec la GPL 1 . Il s’agit d’un logiciel libre : vous pouvez modifier votre interpréteur Python et distribuer cette version modifiée. Toutefois,
cette licence n’entraîne aucune contrainte quant à la licence qui régit les programmes écrits en Python.
Le modèle objet est unifié avec la version 2.2 : les types de base (int,
float, bool) deviennent des objets comme les autres. Ils ont des méthodes,
et il est possible d’en hériter. La dernière version de cette branche est la 2.7.6
de novembre 2013.
La version 3.0 vise à éliminer des redondances dans les fonctionnalités de
Python. Il s’agit de diminuer le nombre de façons de réaliser une même opération, et donc la complexité du langage comme de sa machine virtuelle. Une
conséquence est que la version 3.0 n’est pas compatible avec les versions précédentes : elle ne peut pas exécuter du code Python 2.x. Certaines bibliothèques
1. La GNU General Public License est le plus importante des licenses sous lesquelles sont
distribués les logiciels libres ; elle est écrite par la Free Software Foundation. La license de
Python est la Python Software Foundation License (PSFL), inspirée de la licence BSD de
Berkeley.
5
scientifiques n’ont pas encore fait cette transition et la dernière version de
Python(x,y) utilise actuellement Python 2.7.6. Il existe un script, 2to3, qui
permet de transformer automatiquement du code de Python 2.x en Python 3.
1.2
Caractéristiques du langage
Python est un langage objet, où tout est objet, y compris ce qui est communément appelé type de base : entiers, réels, booléens. Il permet l’héritage
multiple.
Python est un langage de haut niveau, où nombre de structures de données dynamiques (listes et tables de hachages notamment) sont intégrées à
la syntaxe du langage. De nombreuses bibliothèques fournissent des fonctions
évoluées. Il n’est pas prévu de contrôler finement le comportement du processeur ou du compilateur avec ce langage 2 .
Python est un langage à typage dynamique. Le développeur n’a pas à déclarer les variables avant de leur affecter une valeur : la création de la variable
se fait au moment où elle est utile. Il n’a pas non plus à déclarer son type : lors
de son utilisation, les opérateurs (qui sont en fait des méthodes des opérandes)
en testent le type pour vérifier s’ils sont dans leurs conditions d’utilisation.
Python est un langage à typage fort : lorsqu’un opérateur reçoit deux
opérandes incompatibles, une exception est levée et l’opération n’est pas exécutée. Un langage à typage faible aurait tenté une conversion de l’un des
opérandes vers un type compatible et effectué l’opération, au risque d’avoir
un résultat inattendu (4+"2" doit-il fournir la chaîne "42", l’entier 6 ou une
erreur ?)
Python permet la glue logicielle, et peut notamment appeler des fonctions
présentes dans des fichiers .o issus de programmes C. Des bindings permettent
la traduction des données du C en objets Python, et inversement.
Python est un langage à ramasse-miette : de l’espace mémoire est réservé
pour les objets lorsqu’ils sont créés, et la machine virtuelle se charge de libérer
cet espace lorsqu’elle se rend compte que l’objet ne peut plus être utilisé par le
programme. Cela libère le programmeur de la gestion de la mémoire, au risque
parfois d’en consommer trop (si les miettes ne sont pas identifiées comme telles)
et un surcoût de temps d’exécution.
1.3
Python et les autres langages
C, Fortran, Ada, Pascal/Delphi sont des langages compilés : un compilateur doit transformer un fichier source, généralement assez indépendant
de la plate-forme matérielle, en un code exécutable, adapté au processeur
et à l’architecture voulus.
Java est un langage semi-compilé : un compilateur vérifie la syntaxe du fichier
source et le transforme en un byte-code indépendant de la machine, et une
machine virtuelle, spécifique à chaque architecture, exécute le byte-code.
Matlab, tcsh, bash et les autres shells sont des langages interprétés : le
fichier source est exécuté ligne par ligne. Il n’y a pas d’étape intermédiaire
entre l’écriture du code et son exécution. Le programme qui se charge
d’exécuter chacune des lignes est l’interpréteur.
2. Pas d’équivalent des register ou inline du C, donc.
6
Perl est un langage interprété précompilé, dont la syntaxe est proche du shell :
l’interpréteur vérifie d’abord que le programme est syntaxiquement correct, puis l’exécute.
Python est un langage objet interprété précompilé. Une première passe du
programme python sur le script vérifie la grammaire du code et crée un
fichier .pyc. Cette forme précompilée est sauvegardée lors de l’exécution
du script. Dans un deuxième temps ce code précompilé est exécuté par
la composante de python qui joue le rôle de machine virtuelle.
1.4
Développer avec Python(x,y)
L’environnement de développement intégré Python(x,y) regroupe la plupart des bibliothèques mathématiques de Python et l’éditeur de texte spyder
(Scientific PYthon Development EnviRonment). Il inclut par défaut les bibliothèques scientifiques numpy, scipy et matplotlib, ainsi que le vérificateur
de code pylint. Il gère l’installation de plusieurs autres bibliothèques, comme
sympy, dédiée au calcul symbolique.
Figure 1.1 – Fenêtre spyder au démarrage
Sous Windows, il suffit de télécharger l’installeur sur le site de Python(x,y) :
http://code.google.com/p/pythonxy/ et de sélectionner éventuellement des
modules additionnels. L’interpréteur Python est récupéré automatiquement.
7
Sous Linux 3 il suffit de sélectionner le paquet spyder : l’interpéteur python
ainsi que les bibliothèques numpy, scipy et matplotlib en dépendent et seront
installées également. Il peut être utile de sélectionner les autres bibliothèques
souhaitées, comme sympy.
La partie de gauche est l’éditeur de code source. L’éditeur affecte une
couleur au texte en fonction de son rôle dans le programme : bleu pour les
mots-clés du langage, violet pour les fonctions et les constantes, noir pour
les opérateurs et les variables, gris pour les commentaires et vert pour la
documentation. Le terme surligné en jaune est sélectionné à la souris : on voit à
quels endroits du code il est utilisé. La ligne du curseur est surlignée en rose. La
position exacte du curseur (ligne 12, colonne 12) est rappelée en pied de fenêtre.
On peut exécuter le fichier en cours d’édition par Menu/Exécution/Exécution
ou simplement par F5.
La partie en haut à droite permet d’afficher de la documentation sur des
fonctions existantes ou de contrôler le contenu des variables du programme.
La partie en bas à droite est un interpréteur en mode interactif : le code
python qui y est tapé est immédiatement exécuté. C’est cette partie qui permet
d’utiliser Python comme une calculatrice. L’interpréteur Python de spyder est
configuré pour rendre immédiatement disponibles les bibliothèques les plus
courantes :
>>> import numpy as np
>>> import scipy as sp
# NumPy ( multidimensional arrays , linear
algebra , ...)
# SciPy ( signal and image processing
library )
>>> import matplotlib as mpl
# Matplotlib ( 2D / 3D plotting
library )
>>> import matplotlib . pyplot as plt # Matplotlib ’s pyplot :
MATLAB - like syntax
>>> from pylab import *
# Matplotlib ’s pylab
interface
>>> ion ()
# Turned on Matplotlib ’s
interactive mode
Les trois chevrons >>> constituent l’invite de commande. Ce qui suit est la
ligne de code à exécuter. Si la ligne est un début de bloc, l’invite de commande
devient ... jusqu’à la fin du bloc (une ligne vide), lequel est alors exécuté.
>>>
>>>
>>>
...
...
...
...
>>>
>>>
...
...
...
2 3
N = 100
premiers = [ x for x in range (0 , N ) ]
for n in range (2 , int ( N ** 0 . 5 ) ) :
if premiers [ n ] ! = 0 :
for i in range ( 2 *n , N , n ) :
premiers [ i ] = 0
premiers [ 1 ] = 0
for i in premiers :
if premiers [ i ] ! = 0 :
print i ,
5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83
89 97
3. Ubuntu, Debian ou Mint utilisent des paquets .deb gérés par synaptic. Les architectures issues de Redhat utilisent des paquets .rpm ; la procédure peut varier.
8
1.5
Développer sans Python(x,y)
À partir du moment où Python est installé sur un ordinateur (Linux, Windows ou MacOS), taper “python” dans un terminal donne accès à l’interpréteur interactif de Python. Il ne dispose toutefois pas des bibliothèques mathématique, il faut les importer (cf. liste de import de la page 8). On peut alors
utiliser Python comme une calculatrice évoluée, à la manière d’un octave en
ligne de commande.
On peut également lancer un programme Python écrit dans un fichier texte
simulation.py par :
python simulation.py
Le répertoire contient maintenant un nouveau fichier : simulation.pyc.
Il s’agit d’un fichier binaire, qu’on ne peut pas éditer à la main. On pourrait
même mesurer qu’une seconde exécution se fait plus rapidement : l’étape de
précompilation n’a pas à être faite.
Si un programme nécessite des paramètres, on pourra les lui passer par la
ligne de commande :
python eratosthene.py 200
1
import sys
2
3
4
5
6
7
8
9
10
11
12
N = int(sys.argv[1])
premiers =[x for x in range(0,N)]
for n in range(2,int(N**0.5)):
if premiers[n] !=0:
for i in range(2*n, N, n):
premiers[i]=0
premiers[1]=0
for i in premiers:
if premiers[i] !=0:
print i,
Figure 1.2 – Crible d’Ératosthène, nécessite un paramètre entier
D’autres éditeurs ou environnements de développement permettent d’écrire
du Python, voire de traquer les bogues dans un programme Python :
eclipse/PyDev : L’IDE eclipse permet d’écrire du code dans de nombreux
langages. Il fournit une coloration syntaxique, de l’indentation automatique, de la complétion automatique, et un contrôle de l’exécution pour
le débogage. Il gère les ensembles de fichier sources sous la forme de
projet et est adapté aux développements de grands logiciels en équipe.
Initialement écrit pour Java (en Java), le module PyDev permet de l’utiliser pour Python. Il s’agit de l’IDE le plus utilisé ces dernières années,
et de nombreuses Écoles l’ont adopté. Il est disponible sur toutes les
plate-formes.
GNU emacs est un éditeur de code informatique universel 4 , adapté à tous
les langages. Son interface est essentiellement sous forme de texte, et il
4. Le code LaTeX de ce fascicule est écrit sous emacs, ainsi qu’une large part des codes
Python.
9
s’appuie fortement sur des raccourcis clavier qui lui sont spécifiques. Il
est disponible sur toutes les plate-formes, mais mieux intégré au monde
linux. Avant l’arrivée d’éclipse, il s’agissait de l’éditeur le plus utilisé
dans la plupart des Écoles.
gedit : éditeur de texte de Gnome, gestionnaire de fenêtre linux. Il gère la
coloration syntaxique pour de nombreux langages, mais pas la complétion automatique ou l’exécution. Il a l’avantage d’être léger et intuitif.
Il faut ensuite exécuter le fichier produit en ligne de commande. Sur la
distribution Mint, c’est son proche cousin pluma qui est disponible. Pour
de petits programmes (cas typiques de l’initiation à l’informatique) ce
peut être l’éditeur le plus adapté.
10
2
Une calculatrice polyvalente
Sommaire
2.1
2.2
2.3
2.4
2.5
2.1
Manipuler des nombres
2.1.1 Types numériques
2.1.2 Opérations sur les nombres
La bibliothèque Numpy
2.2.1 Importation d’une bibliothèque
2.2.2 Les types sous Numpy
2.2.3 Quelques fonctions numériques sous Numpy
Définition des matrices
2.3.1 Structures de base
2.3.2 Le type matrix sous Numpy
2.3.3 Le type array sous Numpy
Manipulation des matrices
2.4.1 Les bases
2.4.2 Construction des matrices
2.4.3 Matrices particulières
2.4.4 Opérations
2.4.5 Sous-bibliothèque linalg
2.4.6 Fonctions numériques de Numpy sur les matrices
2.4.7 La bibliothèque Scipy
Tracer des courbes
2.5.1 Première approche
2.5.2 Des graphiques plus élaborés
11
12
15
17
17
18
19
21
21
23
23
25
25
27
29
30
31
32
32
33
33
45
Manipuler des nombres
E
en première approche, le langage Python peut être vu comme un ensemble de commandes simples à utiliser. En ce sens, il peut jouer le rôle
d’une calculatrice scientifique classique. Pour s’en convaincre il suffit
de lancer la séquence triviale suivante :
>>> a = 1
>>> b = 2
>>> c = a + b
Pour avoir le résultat de l’opération, on prolongera simplement par :
>>> print c
3
11
ou encore plus simplement par :
>>> c
3
2.1.1
Types numériques
En mathématiques, les nombres appartiennent à des ensembles tels que N,
Z, Q, R ou C. En Python (comme dans beaucoup de langages informatiques)
les nombres seront du type :
int (integer) correspond à un entier (N ou Z) stocké sur une partie limitée de la mémoire de l’ordinateur. Il ne peut donc pas être aussi petit
(négatif) ou aussi grand que l’on veut. Pour une machine (dépend du
microprocesseur et du système d’exploitation) de 32 bits (4 octets), un
entier sera compris entre −231 et 231 − 1 (soit entre -2 147 483 648 et 2
147 483 647). Pour une machine de 64 bits, un entier sera compris entre
−263 et 263 − 1 (soit entre -9 223 372 036 854 775 808 et 9 223 372 036
854 775 807).
long (long integer) le type entier long est équivalent au type entier sauf
qu’il n’est pas limité à nombre d’octets (ou de bits prédéterminé). À
l’extrême, un nombre peut prendre la quasi totalité de la mémoire de
l’ordinateur. Il est clair alors que ce nombre peut être considérable.
float le type flottant permet de représenter des nombres à virgule. Il est
codé en mémoire sur 8 octets (64 bits). Il est représenté sous la forme
nombre = ±1.mantisse∗2±exposant . La mantisse est écrite avec 52 chiffres
binaires, et l’exposant avec 10 ; il y a deux bits de signe. La précision
maximale est donc de l’ordre de 2 × 10−16 . Des valeurs spéciales permettent de représenter −∞, +∞ et Nan, not a number, souvent issu d’une
forme indéterminée.
complex le type complexe correspond à une structure naturellement composée de deux flottants (partie réelle et imaginaire) sur 2 x 8 = 16 octets.
bool le type booléen correspond à l’algèbre booléenne et ne prend que deux
valeurs : True/False. Il est codé sur un bit.
En pratique, pour des applications basiques, le typage est la plupart du
temps transparent pour l’utilisateur car Python interprète dynamiquement le
type des variables. Par exemple sur une machine 32bits, on peut lancer la
séquence :
>>> a = 2147483647
>>> a
2147483647
>>> b = a + 1
>>> b
2147483648L
>>> print b
2147483648
Le nombre a est de type entier, mais il atteint le maximum possible pour
des entier (à adapter pour une machine 64 bits). Si on ajoute 1 à la variable a,
on est obligé de stoker le résultat dans une variable de type long. On constate
qu’à la fin du nombre porté par la variable b qu’il y a un L (ce qui indique le
type long). On remarquera que l’information de type (le L) n’apparaît pas avec
12
la commande print : print utilise str(b) pour convertir l’entier en chaîne
de caractère ; écrire directement b fait appel à repr(b).
Si on retire 1 à b il conserve le type long, mais si on ajoute 1 à la variable
a, cette variable change dynamiquement de type.
>>> b = b - 1
>>> b
2147483647L
>>> a = a + 1
>>> a
2147483648L
On peut aussi créer un nombre entier énorme qui sera bien évidemment de
type long (remarque : ** est l’opérateur de mise à la puissance) :
>>> c = 2 ** 10000
>>> c
19950631168807583848837421626835850838234968318861924548520089498
52943883022194663191996168403619459789933112942320912427155649134
94137811175937859320963239578557300467937945267652465512660598955
20550086918193311542508608460618104685509074866089624888090489894
83800925394163325785062156830947390255691238806522509664387444104
67598716269854532228685381616943157756296407628368807607322285350
91641476183956381458969463899410840960536267821064621427333394036
52556564953060314268023496940033593431665145929777327966577560617
25820314079941981796073782456837622800373028854872519008344645814
54650557929601414833921615734588139257095379769119277800826957735
67444412306201875783632550272832378927071037380286639303142813324
14016241956716905740614196543423246388012488561473052074319922596
11796250130992860241708340807605932320161268492288496255841312844
06153673895148711425631511108974551420331382020293164095759646475
60104058458415660720449628670165150619206310041864222759086709005
74606417856951911456055068251250406007519842261898059237118054444
78807290639524254833922198270740447316237676084661303377870603980
34131971334936546227005631699374555082417809728109832913144035718
77524768509857276937926433221599399876886660808368837838027643282
77517227365757274478411229438973381086160742325329197481312019760
41782819656974758981645312584341359598627841301281854062834766490
88690521047580882615823961985770122407044330583075869039319604603
40497315658320867210591330090375282341553974539439771525745529051
02123109473216107534748257407752739863482984983407569379556466386
21874569499279016572103701364433135817214311791398222983845847334
44027096418285100507292774836455057863450110085298781238947392869
95408343461588070439591189858151457791771436196987281314594837832
02081474982171858011389071228250905826817436220577475921417653715
68772561490458290499246102863008153558330813010198767585623434353
89554091756234008448875261626435686488335194637203772932400944562
46923254350400678027273837755376406726898636241037491410966718557
05075909810024678988017827192595338128242195402830275940844895501
46766683896979968862416363133763939033734558014076367418777110553
84225739499110186468219696581651485130494222369947714763069155468
21768287620036277725772378136533161119681128079266948188720129864
36607685516398605346022978715575179473852463694469230878942659482
17008051120322365496288169035739121368338393591756418733850510970
27161391543959099159815465441733631165693603112224993796999922678
17323580231118626445752991357581750081998392362846152498810889602
32244362173771618086357015468484058622329792853875623486556440536
96262201896357102881236156751254333830327002909766865056855715750
55167275188991941297113376901499161813151715440077286505731895574
50920330185304847113818315407324053319038462084036421763703911550
63978900074285367219628090347797453332046836879586858023795221862
91200807428195513179481576244482985184615097048880272747215746881
13
31594750409732115080498190455803416826949787141316063210686391511
68 17 74 304 79 25 96 709 37 6L
Pour les booléens (| et & indiquent respectivement ou et et), on peut lancer
la séquence :
>>> a = True
>>> b = False
>>> a | b
True
>>> a & b
False
Pour les nombres complexes, on peut tester :
>>> a = 1 . 5 + 3 . j
>>> b = 1 . 5
>>> a - b
3j
>>> a * b
( 2 . 25 + 4 . 5j )
>>> c = 1 . + 1 . j
>>> a * c
( - 1 . 5 + 4 . 5j )
>>> ( 1 + 4j ) ** ( 1 / ( 2 + 3j ) )
( 1 . 67585169460166 - 0 . 20706889169199882j )
>>> 1j * complex (0 , 1 )
( - 1 + 0j )
En réalité, il possible d’utiliser la structure des nombres complexes de façon
plus évoluée. Par exemple :
>>> a = 1 . 5 + 3 . j
>>> a . real
1.5
>>> a . imag
3.0
>>> a . conjugate ()
( 1 . 5 - 3j )
Enfin, il est possible de modifier explicitement le type des variables en
utilisant les fonctions de conversion :
int(a)
long(a)
float(a)
complex(a)
complexe(a,b)
Conversion
Conversion
Conversion
Conversion
Conversion
de a
a en
a en
a en
de a
en type entier
type entier long
type flottant
type complexe a+0j
et de b en type complexe a+bj
Sous Python, il existe la fonction type() qui donne le type d’une variable.
Par exemple :
>>> a = 1
>>> type ( a )
< type ’ int ’>
>>> a = 1 .
>>> type ( a )
< type ’ float ’>
>>> a = 2 ** 10000
>>> type ( a )
< type ’ long ’>
>>> a = 3 . + 4 . j
14
>>> type ( a )
< type ’ complex ’>
2.1.2
Opérations sur les nombres
Opérateurs arithmétiques
Python ne possède que très peu d’opérations arithmétiques pour manipuler
les nombres. À ce stade, Python principalement se résume à une calculatrice
élémentaire :
+
−
∗
/
//
%
∗∗
Addition
Soustraction
Multiplication
Division
Division entière
Division modulaire
Puissance
La nature des opérations arithmétiques dépend du type des variables. Voici
une séquence Python lancée sous une fenêtre de commande :
>>>
>>>
>>>
>>>
1
>>>
>>>
3.0
>>>
>>>
2.0
>>>
1.5
>>>
1.0
a=3
b=2
c=a/b
print c
a=3.
print a
b=2.0
print b
a/b
a // b
L’opérateur // tronque la valeur obtenue à l’entier inférieur. Il renvoie un
float ou un entier (int ou long) selon le type des opérandes.
Avec des entiers, la division / devient une division entière. Il est important
de souligner que dans les versions Python 3.*, l’opérateur / est systématiquement une vraie division. Sur des entiers, / et // ont le même comportement
en Python 2.*.
Attention, il est possible de modifier ce fonctionnement par défaut. Par
exemple, la même séquence lancée sous spyder donne :
>>>
>>>
>>>
>>>
1.5
a=3
b=2
c=a/b
print c
On parle alors de vraie division.
15
Raccourcis pour les opérateurs arithmétiques
Dans une séquence de code, on peut affecter une variable à une valeur,
effectuer une opération arithmétique sur cette variable et finalement affecter
la nouvelle valeur obtenue à la variable. Par exemple :
>>>
>>>
>>>
>>>
2
a=1
b=1
a=a+b
print a
En Python, il est possible d’écrire l’opération arithmétique de façon plus
compacte :
>>>
>>>
>>>
>>>
2
a=1
b=1
a+=b
print a
Ceci est également vrai pour les autres opérateurs arithmétiques :
a+=b
a-=b
a*=b
a/=b
a**=b
a%=b
a=a+b
a=a-b
a=a*b
a=a/b
a=a**b
a=a%b
Quelques fonctions supplémentaires
De base, Python fournit quelques fonctions numériques autres que les
opérations arithmétiques :
abs(a)
max(...)
min(...)
round(a,n)
cmp(a,b)
Valeur absolue de a
Plus grande valeur d’une suite de nombres
Plus petite valeur d’une suite de nombres
Arrondi de la variable a au niveau
de la ne décimale



−1 si a < b
Comparaison de a et de b : 0
si a = b


1
si a > b
Par exemple :
>>> a = - 1
>>> abs ( a )
1
>>> a = 1
>>> b = 3 . 4
>>> c = 10
>>> max (a ,b , c )
10
>>> min (a ,b , c )
1
>>> a = 3 . 141592654
>>> round (a , 4 )
3 . 1416
16
>>> round (a , 2 )
3 . 14
>>> round (a , 0 )
3.0
Opérateurs de comparaison
Python peut aussi vérifier si une comparaison entre deux nombres est vraie
ou fausse ce qui renvoie une valeur booléenne. Les opérateurs standards de
comparaison sont :
<
>
<=
>=
==
!=
Plus petit que
Plus grand que
Plus petit que ou égal à
Plus grand que ou égal à
Égal à
Pas égal à
Par exemple :
>>> a = 5
>>> b = 4 . 9999
>>> a < b
False
>>> b > a
False
>>> a > b
True
>>> a = = b
False
>>> a ! = b
True
2.2
La bibliothèque Numpy
Il est impossible de donner une liste exhaustive de toutes les bibliothèques
relatives à Python. Toutefois, pour les applications scientifiques, la bibliothèque Numpy apparaît incontournable.
2.2.1
Importation d’une bibliothèque
L’importation d’une bibliothèque se fait grâce à la commande import.
Pour accéder à une fonction particulière de la bibliothèque, on peut taper
nom_de_la_bibliothèque.nom_de_la_fonction(). Par exemple pour la fonction sin() :
>>> import numpy
>>> numpy . sin ( 3 . 141592654 )
- 4 . 1020685703470686e - 10
Pour éviter de retaper le nom complet de la bibliothèque (qui dans certain
peut être assez long), on peut modifier le nom de la bibliothèque en utilisant
le terme as. Par exemple, ici on renomme numpy par np :
>>> import numpy as np
>>> np . sin ( 3 . 141592654 )
- 4 . 1020685703470686e - 10
17
On peut se passer complètement du rappel du nom de la bibliothèque, en
spécifiant directement les fonctions qu’on désire importer avec le terme from :
>>> from numpy import sin
>>> sin ( 3 . 141592654 )
- 4 . 1020685703470686e - 10
On peut même importer directement toutes les fonctions d’une bibliothèque avec le symbole * :
>>> from numpy import *
>>> sin ( 3 . 141592654 )
- 4 . 1020685703470686e - 10
A priori, la dernière solution semble la plus simple car elle évite des écritures répétitives. D’ailleurs par défaut, la fenêtre console de spyder effectue
directement l’importation de toutes les fonctions de la bibliothèque numpy.
Ainsi, sous spyder, on peut sans import explicite lancer la commande suivante :
>>> sin ( 1 . 5 )
0 . 99749498660405445
Toutefois, l’import systématique de fonction est à déconseiller fortement
pour deux raisons. La première est que l’on importe en général une grande
quantité de fonctions dont on ne se sert pas réellement. La seconde est qu’en
Python, on est amené à importer un nombre conséquent de bibliothèques, dont
certaines fonctions peuvent porter le même nom.
Par exemple, la bibliothèque math existe et possède également la fonction
sin(). D’après la séquence de code suivante, les deux fonctions sin() semblent
se comporter de la même façon sur un nombre, mais on constatera qu’elles sont
très différentes dès lors qu’elles s’appliquent sur une liste :
>>> import numpy as np
>>> import math as m
>>> a = 3 . 14
>>> np . sin ( a )
0 . 0015926529164868282
>>> m . sin ( a )
0 . 0015926529164868282
>>> b = [ 1 .5 , 3 . 14 ]
>>> np . sin ( b )
array ( [ 0 . 99749499 , 0 . 00159265 ] )
>>> m . sin ( b )
Traceback ( most recent call last ) ~ :
File " < stdin > " , line 1 , in < module >
TypeError ~ : a float is required
2.2.2
Les types sous Numpy
L’importation de la libraire Numpy augmente le nombre des types de possible. En plus des entiers classiques (int), on peut considérer les entiers positifs
(uint). On peut aussi spécifier le nombre de bits utilisé pour le codage. La liste
des types devient alors :
bool : True ou False ; toute valeur numérique différente de 0 est assimilée à
True ;
18
int : le type entier par défaut de Python ; sa taille n’est pas définie par la
norme, et peut correspondre à int32 ou int64 selon les architectures.
En cas de dépassement, il est automatiquement remplacé par un long.
Sous Python 3.* les types int et long sont fusionnés ;
int8 : de -128 à 127,
int16 : de -32 768 à 32 767,
int32 : de -2 147 483 648 à 2 147 483 647,
int64 -9 223 372 036 854 775 808 à 9 223 372 036 854 775 807,
uint8 : de 0 à 255,
uint16 : de 0 à 65 535,
uint32 : de 0 à 4 294 967 295,
uint64 : de 0 à 18 446 744 073 709 551 615,
float64, float : nombre à virgule flottante sur 8 octets ; correspond au type
double du C.
float32 : nombre à virgule flottante sur 4 octets ; correspond au type float
du C.
float16 : nombre à virgule flottante sur 2 octets ; il ne correspond à aucun
type du microprocesseur : il permet de gagner de l’espace de stockage,
mais pas de vitesse de calcul ;
complex128, complex : nombre complexe dont la partie réelle et la partie
imaginaire sont des float64, c’est-à-dire des float
complex64 : nombre complexe dont la partie réelle et la partie imaginaire
sont des float32.
2.2.3
Quelques fonctions numériques sous Numpy
La listes des fonctions numériques définies dans numpy est extrêmement
importante. On peut ici donner une liste non exhaustive des fonctions les plus
classiques (remarque : les termes entre [ et ] sont des paramètres optionnels).
Trigonométrie
sin(x[, out])
cos(x[, out])
tan(x[, out])
arcsin(x[, out])
arccos(x[, out])
arctan(x[, out])
hypot(x1, x2[, out])
arctan2(x1, x2[, out])
degrees(x[, out])
radians(x[, out])
unwrap(p[, discont, axis])
deg2rad(x[, out])
rad2deg(x[, out])
Sinus
Cosinus
Tangente
Arcsinus
Arccosinus
Arctangente
Hypothénuse en fonction des deux autres cotés
Arctangente du rapport x1/x2
(quadrant selon x1 et x2)
Conversion de radians vers degrés
Conversion de degrés vers radians
Déroulement de la phase
Conversion de degrés vers radians
Conversion de radians vers degrés
19
Trigonométrie hyperbolique
sinh(x[, out])
cosh(x[, out])
tanh(x[, out])
arcsinh(x[, out])
arccosh(x[, out])
arctanh(x[, out])
Sinus hyperbolique
Cosinus hyperbolique
Tangente hyperbolique
Arcsin hyperbolique
Arccosinus hyperbolique
Arcsinus hyperbolique
Arrondis
around(a[, decimals, out])
rint(x[, out])
fix(x[, y])
floor(x[, out])
ceil(x[, out])
trunc(x[, out])
Arrondi à une décimale près
Entier le plus proche
Arrondi à 0 décimale
Arrondi à la valeur inférieure
Arrondi à la valeur supérieure
Arrondi à l’entier le plus proche de zéro
Exponentielles et logarithmes
exp(x[, out])
expm1(x[, out])
exp2(x[, out])
log(x[, out])
log10(x[, out])
log2(x[, out])
log1p(x[, out])
Exponentielle
Exponentielle moins 1
Exponentielle de base 2
Logarithme naturel
Logarithme de base 10
Logarithme de base 2
Logarithme de x + 1
Fonctions spéciales
i0(x)
sinc(x)
Bessel modifiée de première espèce d’ordre 0
Sinus cardinal
Beaucoup d’autres fonctions spéciales existent dans Numpy mais elles appartiennent à des sous-librairies (voir sections 3.6, 3.7.2 à 3.7.4, et chapitre 4).
Autres fonctions
signbit(x[, out])
copysign(x1, x2[, out])
frexp(x[, out1, out2])
ldexp(x1, x2[, out])
Indication de la présence d’un bit de signe
Copie du signe de x2 sur x1
Décomposition x = out1 ∗ 2out2
Calcul x1 ∗ 2x2
20
Arithmétique
add(x1, x2[, out])
reciprocal(x[, out])
negative(x[, out])
multiply(x1, x2[, out])
divide(x1, x2[, out])
power(x1, x2[, out])
subtract(x1, x2[, out])
true_divide(x1, x2[, out])
floor_divide(x1, x2[, out])
fmod(x1, x2[, out])
mod(x1, x2[, out])
modf(x[, out1, out2])
remainder(x1, x2[, out])
Addition
Inversion (Attention cas entier)
Opposé
Multiplication
Division
Puissance x1x2
Soustraction
Vraie division (même entiers)
Quotient division entière (même flottants)
Reste division entière
Reste division entière
Partie décimale et partie entière
Reste division entière
Nombres complexes
angle(z[, deg])
real(val)
imag(val)
conj(x[, out])
Argument
Partie réelle
Partie imaginaire
Conjugué
Divers
sqrt(x[, out])
square(x[, out])
absolute(x[, out])
fabs(x[, out])
sign(x[, out])
maximum(x1, x2[, out])
minimum(x1, x2[, out])
nan_to_num(x)
real_if_close(a[, tol])
Racine carrée
Mise au Carré
Valeur absolue
Valeur absolue
Signe (-1,0,1)
Maximum
Minimum
Remplacement de nan et de inf
Élimination des petites parties imaginaires
Remarque. numpy.nan (Not A Number) et numpy.inf (Infini) sont définis dans
la bibliothèque Numpy.
2.3
Définition des matrices
2.3.1
Structures de base
En partant des types fondamentaux, il est possible de créer des matrices
et des vecteurs en utilisant le concept de liste (cette notion sera détaillée en
section 3.1).
Une liste se crée en utilisant [ ] :
>>>
>>>
1.3
>>>
2.0
>>>
7.6
a = [ 1 .3 , 2 .0 , 7 . 6 ]
a[0]
a[1]
a[2]
21
On notera que pour une liste de taille n, l’indice varie de 0 à n − 1.
Pour créer une matrice, il est possible de créer une liste de liste :
>>> b = [ [1 ,2 , 3 ] ,[4 ,5 , 6 ] ,[7 ,8 , 9 ] ]
>>> print b
[ [1 , 2 , 3 ] , [4 , 5 , 6 ] , [7 , 8 , 9 ] ]
>>> b [ 1 ]
[4 , 5 , 6 ]
>>> b [ 1 ] [ 2 ]
6
Deux fonctions très utiles pour les listes de nombres :
range() la fonction range() permet de générer une liste de nombres entiers
avec un pas régulier. Tous les paramètres doivent être des entiers.
len() donne la longueur d’une liste.
Ces deux fonctions peuvent donner lieu à la séquence suivante :
>>> range ( 10 )
[0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]
>>> range (6 , 9 )
[6 , 7 , 8 ]
>>> range ( 1 .2 , 5 )
Traceback ( most recent call last ) ~ :
File " < stdin > " , line 1 , in < module >
TypeError ~ : range () integer start argument expected , got float .
>>> range (1 , 10 , 2 )
[1 , 3 , 5 , 7 , 9 ]
>>> range ( 10 ,1 , - 2 )
[ 10 , 8 , 6 , 4 , 2 ]
>>> a = range (4 , 8 )
>>> len ( a )
4
>>> b = [ [1 ,2 ,3 , 4 ] ,[5 ,6 ,7 , 8 ] ,[9 , 10 , 11 , 12 ] ]
>>> print b
[ [1 , 2 , 3 , 4 ] , [5 , 6 , 7 , 8 ] , [9 , 10 , 11 , 12 ] ]
>>> len ( b )
3
Quoi qu’il en soit, il ne sera pas possible de travailler sur des listes ou des
listes de listes de façon algébrique. Par exemple, le produit direct de listes
conduit à une erreur :
>>> a = [ 1 .3 , 2 .0 , 7 . 6 ]
>>> b = [ [1 ,2 , 3 ] ,[4 ,5 , 6 ] ,[7 ,8 , 9 ] ]
>>> print b
[ [1 , 2 , 3 ] , [4 , 5 , 6 ] , [7 , 8 , 9 ] ]
>>> b * a
Traceback ( most recent call last ) ~ :
File " < stdin > " , line 1 , in < module >
TypeError ~ : can ’t multiply sequence by non - int of type ’ list ’
Pour réaliser des opérations algébriques, nous sommes condamnés à reprogrammer les opérations fondamentales de l’algèbre linéaire. En ajoutant le
fait qu’en Python de base les opérations arithmétiques et fonctions numériques
sont limitées, l’emploi de bibliothèques mathématiques est indispensable pour
des applications scientifiques.
22
2.3.2
Le type matrix sous Numpy
En plus des types de nombre et des fonctions numériques vues précédemment, la bibliothèque numpy apporte également de nouvelles structures. En
particulier, il existe la structure matrix qui n’est pas une simple liste. Ainsi,
le calcul algébrique suivant :
 
1
 
~v = 2
3


1 0 0


A = 0 −1 0
0 0 2
~u = A · ~v
peut se traduire sous Python par la séquence :
>>> v = np . matrix ( [1 ,2 , 3 ] )
>>> print v
matrix ( [ [1 , 2 , 3 ] ] )
>>> A = np . matrix ( [ [1 ,0 , 0 ] ,[0 , -1 , 0 ] ,[0 ,0 , 2 ] ] )
>>> print A
matrix ( [ [ 1 , 0 , 0 ] ,
[ 0 , -1 , 0 ] ,
[ 0, 0, 2]])
>>> A * v
Traceback ( most recent call last ) ~ :
File " < stdin > " , line 1 , in < module >
File " / usr / lib / python2 . 7 / dist - packages / numpy / matrixlib /
defmatrix . py " , line
330 , in __mul__
return N . dot ( self , asmatrix ( other ) )
ValueError ~ : objects are not aligned
>>> vt = np . transpose ( v )
>>> print vt
matrix ( [ [ 1 ] ,
[2],
[3]])
>>> A * vt
matrix ( [ [ 1 ] ,
[-2],
[ 6]])
L’avantage de la structure matrix de numpy est que l’opérateur * a le
même sens que la multiplication au sens des matrices et que les opérations
algébriques deviennent transparentes.
Par ailleurs, il existe un grand nombre de fonctions applicables au type
matrix : transpose, trace, diagonal, reshape, . . .
Par exemple, pour transposer une matrice. On peut écrire sous Python :
>>> import numpy as np
>>> A = np . matrix ( [ [1 ,2 , 3 ] ,[4 ,5 , 6 ] ,[7 ,8 , 9 ] ] )
>>> np . transpose ( A )
matrix ( [ [1 , 4 , 7 ] ,
[2 , 5 , 8 ] ,
[3 , 6 , 9 ] ] )
Toutefois, nous ne développerons pas plus les traitements mathématiques
avec le type matrix de numpy. En effet, ce type possède de sérieuses limitations.
En particulier, il n’est pas possible de travailler en dimension supérieure à 2.
2.3.3
Le type array sous Numpy
Le type array est plus général. Il permet de travailler en dimension quelconque et c’est la structure qui est privilégiée sous numpy. C’est la structure
23
que nous adopterons également lors de la formation.
Avec le type array, il est possible de réaliser quasiment les mêmes opérations que nous avons précédemment réalisées avec le type matrix. Toutefois,
si nous réécrivons la même séquence que précédemment en utilisant le type
array, nous noterons certaines différences :
>>> import numpy as np
>>> v = np . array ( [1 ,2 , 3 ] )
>>> print v
[1 2 3]
>>> v
array ( [1 , 2 , 3 ] )
>>> A = np . array ( [ [1 ,0 , 4 ] ,[0 , -1 , 0 ] ,[0 ,0 , 2 ] ] )
>>> print A
[[ 1 0 4]
[ 0 -1 0]
[ 0 0 2]]
>>> A
array ( [ [ 1 , 0 , 4 ] ,
[ 0 , -1 , 0 ] ,
[ 0, 0, 2]])
>>> A * v
array ( [ [ 1 , 0 , 12 ] ,
[ 0 , -2 , 0 ] ,
[ 0, 0, 6]])
>>> vt = np . transpose ( v )
>>> A * vt
array ( [ [ 1 , 0 , 12 ] ,
[ 0 , -2 , 0 ] ,
[ 0, 0, 6]])
>>> A * A
array ( [ [ 1 , 0 , 16 ] ,
[ 0, 1, 0],
[ 0, 0, 4]])
>>> v2 = np . array ( [ [ 1 ,2 , 3 ] ] )
>>> v2
array ( [ [1 , 2 , 3 ] ] )
>>> np . transpose ( v2 )
array ( [ [ 1 ] ,
[2],
[3]])
>>> A * v2
array ( [ [ 1 , 0 , 12 ] ,
[ 0 , -2 , 0 ] ,
[ 0, 0, 6]])
>>> A * np . transpose ( v2 )
array ( [ [ 1 , 0 , 4 ] ,
[ 0 , -2 , 0 ] ,
[ 0, 0, 6]])
>>> A . dot ( v2 )
Traceback ( most recent call last ) :
File " < stdin > " , line 1 , in < module >
ValueError : objects are not aligned
>>> A . dot ( np . transpose ( v2 ) )
array ( [ [ 13 ] ,
[-2],
[ 6]])
>>> print A . shape , v . shape , v2 . shape , v2 . transpose () . shape
(3 , 3 ) (3 ,) (1 , 3 ) (3 , 1 )
Dans l’exemple précédent, A est une matrice 3 × 3, v est un vecteur à
une dimension, donc un array dont la forme (shape) est (3), alors que v2
24
est un vecteur ligne, mais un array à deux dimensions, dont la forme est
(1,3). Lorsqu’un vecteur mono-dimensionnel est utilisé dans un contexte où il
faudrait deux dimensions, il est en général considéré comme un vecteur ligne.
La transposée de v est vt qui est identique à v, alors que la transposée de
v2 est bien un vecteur colonne de forme (3,1).
L’opérateur de multiplication * réalise une multiplication terme à terme ;
c’est ainsi que les termes de A*A sont les a2i,j . Les multiplications par v, vt
ou v2, qui sont tous des vecteurs ligne, multiplient la ie colonne de A par le
ie terme du vecteur. La multiplication par np.transpose(v2) multiplie la ie
ligne de la matrice par le terme correspondant du vecteur.
Le produit matriciel classique s’obtient par la méthode dot, qui impose au
paramètre d’être de la bonne forme : on ne peut pas multiplier A par v2, mais
juste par sa transposée.
2.4
Manipulation des matrices
À partir de maintenant nous travaillerons (sauf mention explicite) avec le
type array de numpy et nous admettrons que l’importation de la bibliothèque
numpy est réalisée par :
import numpy as np
2.4.1
Les bases
Les matrices de type array peuvent se construire à partir des listes de
Python.
>>> a = np . array ( [1 , 4 , 5 , 8 ] , float )
>>> a
array ( [ 1 . , 4 . , 5 . , 8 . ] )
>>> type ( a )
< type ’ numpy . ndarray ’>
Un array peut être multidimensionnel (ici dimension 3).
>>> a = np . array ( [ [ [1 , 2 ] ,[1 , 2 ] ] ,[ [1 , 2 ] ,[1 , 2 ] ] ] )
>>> a
array ( [ [ [1 , 2 ] ,
[1 , 2 ] ] ,
[ [1 , 2 ] ,
[1 , 2 ] ] ] )
>>> type ( a )
< type ’ numpy . ndarray ’>
>>> a [1 ,1 , 1 ]
2
On peut manipuler les matrices en travaillant sur les indices (par défaut
les indices commencent à 0). Il est important de comprendre la notion d’affectation pour les matrices : les variables a et b regardent – avec des perceptions
différentes – une même zone en mémoire.
>>> a = np . array ( [1 , 2 , 3 , 4 , 5 ] )
>>> b = a [ 1 : 3 ]
>>> b
array ( [2 , 3 ] )
>>> b [ 1 ] = 0
25
>>> a # a est modifi é
array ( [1 , 2 , 0 , 4 , 5 ] )
La copie, qui doit être explicite, est différente de l’affectation. La mémoire
utilisée par b après l’appel à la fonction copy() est séparée de la zone mémoire
de a. .
>>> a = np . array ( [1 , 2 , 3 , 4 , 5 ] )
>>> b = np . copy ( a [ 1 : 3 ] )
>>> b
array ( [2 , 3 ] )
>>> b [ 1 ] = 0
>>> a
array ( [1 , 2 , 3 , 4 , 5 ] )
>>> b
array ( [2 , 0 ] )
Pour la copie, nous avons utilisé une fonction Numpy. Il est possible de
faire autrement car un array est une structure bien plus complexe que de
simples listes. Un array possède en réalité une structure objet (cf. chapitre
5). En plus des données, à chaque array est associé un ensemble de fonctions
(on parlera alors de méthodes) qu’il est possible d’appeler.
>>> a = np . array ( [1 , 2 , 3 , 4 , 5 ] )
>>> b = a [ 1 : 3 ] . copy ()
>>> b [ 1 ] = 0
>>> b
array ( [2 , 0 ] )
>>> a
array ( [1 , 2 , 3 , 4 , 5 ] )
Manipulation sur les indices et fonction arange() :
>>> a = np . arange ( 10 )
>>> a
array ( [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] )
>>> a [ 2 : 9 : 3 ] # [ d é but : fin : pas ]
array ( [2 , 5 , 8 ] )
>>> a [ 2 : 8 : 3 ] # le dernier é l é ment n ’ est pas inclus
array ( [2 , 5 ] )
>>> a [ : 5 ]
# le dernier é l é ment n ’ est pas inclus
array ( [0 , 1 , 2 , 3 , 4 ] )
>>> a [ 8 : 2 : - 3 ] # les pas n é gatifs sont autoris é s ; l ’ ordre du
tableau est invers é
array ( [8 , 5 ] )
Un pas négatif inversera l’ordre du tableau. Un indice négatif est considéré
comme le nombre d’éléments précédant le dernier élément du tableau. Ainsi
a[-2::1] comme a[-2:] extraient l’avant-dernier et le dernier élément.
Pour un tableau bi-dimensionnel, on peut bien sûr jouer avec les deux
indices. La fonction eye() permet de créer des matrices avec des 1 sur la
diagonale et des 0 ailleurs :
>>> a = np . eye (5 , 5 )
>>> print a
[[ 1. 0. 0. 0.
[ 0. 1. 0. 0.
[ 0. 0. 1. 0.
[ 0. 0. 0. 1.
[ 0. 0. 0. 0.
>>> a [ :3 , : 4 ] = 4
0.]
0.]
0.]
0.]
1.]]
26
>>> a [ : :3 , : : 4 ] = 5
>>> a [ : ,2 ] = 6
>>> print a
[[ 5. 4. 6. 4.
[ 4. 4. 6. 4.
[ 4. 4. 6. 4.
[ 5. 0. 6. 1.
[ 0. 0. 6. 0.
5.]
0.]
0.]
5.]
1.]]
Les indices peuvent aussi être des listes. La fonction reshape() permet de
modifier la taille des matrices :
>>> a = np . array ( [2 ,4 ,6 , 8 ] , float )
>>> b = np . array ( [0 ,0 ,1 ,3 ,2 , 1 ] , int )
>>> a [ b ]
array ( [ 2 . , 2 . , 4 . , 8 . , 6 . , 4 . ] )
>>> a = a . reshape (2 , 2 )
>>> a
array ( [ [ 2 . , 4 . ] ,
[ 6., 8.]])
>>> b = np . array ( [0 ,0 ,1 ,1 , 0 ] , int )
>>> c = np . array ( [0 ,1 ,1 ,1 , 1 ] , int )
>>> a [b , c ]
array ( [ 2 . , 4 . , 8 . , 8 . , 4 . ] )
On peut aussi convertir une matrice de type array en type matrix :
>>> a = np . array ( [1 , 2 , 4 ] )
>>> np . mat ( a )
matrix ( [ [1 , 2 , 4 ] ] )
2.4.2
Construction des matrices
Construction de matrices avec la fonction arange() :
>>> np . arange ( 10 ) # entiers ( < 10 ) en partant de 0
array ( [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] )
>>> np . arange (2 , 10 , dtype = np . float ) # flottants ( < 10 ) dont le
premier est 2 .
array ( [ 2 . , 3 . , 4 . , 5 . , 6 . , 7 . , 8 . , 9 . ] )
>>> np . arange (2 , 3 , 0 . 1 ) # pas non entier
array ( [ 2 . , 2 .1 , 2 .2 , 2 .3 , 2 .4 , 2 .5 , 2 .6 , 2 .7 , 2 .8 , 2 . 9 ] )
>>> np . arange ( 3 )
array ( [0 , 1 , 2 ] )
>>> np . arange ( 3 . 0 )
array ( [ 0 . , 1 . , 2 . ] )
Construction de matrices avec la fonction linspace() :
>>> np . linspace ( 1 . , 4 . , 6 ) # 6 flottants r é guli è rement r é partis
de 1 . à 4 . ( inclus )
array ( [ 1 . , 1 .6 , 2 .2 , 2 .8 , 3 .4 , 4 . ] )
Utilisation de la fonction reshape() (Attention à respecter le nombre d’éléments) :
>>> a = np . arange ( 16 )
>>> a
array ( [ 0 , 1 , 2 , 3 ,
>>> a . reshape (4 , 4 )
array ( [ [ 0 , 1 , 2 ,
4,
5,
6, 7, 8,
, 15 ] )
3],
27
9 , 10 , 11 , 12 , 13 , 14
[ 4, 5, 6, 7],
[ 8 , 9 , 10 , 11 ] ,
[ 12 , 13 , 14 , 15 ] ] )
>>> a . reshape (2 , 8 )
array ( [ [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ,
[ 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ] ] )
>>> a . reshape ( -1 , 3 )
Traceback ( most recent call last ) :
File " < stdin > " , line 1 , in < module >
ValueError : total size of new array must be unchanged
>>> a . reshape ( -1 , 2 )
array ( [ [ 0 , 1 ] ,
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[ 10 , 11 ] ,
[ 12 , 13 ] ,
[ 14 , 15 ] ] )
>>> a . reshape (2 , -1 , 4 )
array ( [ [ [ 0 , 1 , 2 , 3 ] ,
[ 4, 5, 6, 7]],
[ [ 8 , 9 , 10 , 11 ] ,
[ 12 , 13 , 14 , 15 ] ] ] )
Il est possible de remplacer une dimension par -1 pour compléter avec de
quoi stocker toutes le données. Il faut toutefois que le produit des dimensions
imposées divise le nombre total d’éléments. a.reshape(-1, 1) organise les
données en un vecteur colonne, et a.reshape(1,-1) en un vecteur ligne.
Il existe aussi la fonction flatten() transforme une matrice en un vecteur,
et crée ce vecteur (on fait une copie de l’objet). La méthode ravel() est
équivalente à un reshape vers un vecteur monodimensionnel : a.reshape(-1)
ou a.ravel().
Il est possible de concaténer avec la fonction concatenate() des matrices
verticalement ou horizontale selon la valeur de axis.
>>> a = np . arange ( 4 ) . reshape (2 , 2 )
>>> b = 4 + np . arange ( 4 ) . reshape (2 , 2 )
>>> b
array ( [ [4 , 5 ] ,
[6 , 7 ] ] )
>>> c = ( np . arange ( 4 ) + 6 ) [ newaxis ,~ : ]
>>> np . concatenate (( a , b ) )
array ( [ [0 , 1 ] ,
[2 , 3 ] ,
[4 , 5 ] ,
[6 , 7 ] ] )
>>> np . concatenate (( a , b ) , axis = 0 )
array ( [ [0 , 1 ] ,
[2 , 3 ] ,
[4 , 5 ] ,
[6 , 7 ] ] )
>>> np . concatenate (( a , b ) , axis = 1 )
array ( [ [0 , 1 , 4 , 5 ] ,
[2 , 3 , 6 , 7 ] ] )
>>> np . concatenate (( c ,c , np . concatenate (( a , b ) , axis = 1 ) ) )
array ( [ [6 , 7 , 8 , 9 ] ,
[6 , 7 , 8 , 9 ] ,
[0 , 1 , 4 , 5 ] ,
[2 , 3 , 6 , 7 ] ] )
28
La fonction arange() génére un vecteur (dimension 1) qui est différent
d’une matrice à une ligne ou une colonne (dimension 2). Pour transformer un
vecteur en matrice, il faut ajouter une dimension avec np.newaxis :
>>> c = ( np . arange ( 4 ) + 6 )
>>> c
array ( [6 , 7 , 8 , 9 ] )
>>> c = ( np . arange ( 4 ) + 6 ) [ np . newaxis ,~ : ]
>>> c
array ( [ [6 , 7 , 8 , 9 ] ] )
Pour travailler sur les indices, il existe les fonctions take() et sa réciproque
put() :
>>> a = np . arange ( 16 ) . reshape (4 , 4 )
>>> a . take ( [0 , 3 ] , axis = 1 )
array ( [ [ 0 , 3 ] ,
[ 4, 7],
[ 8 , 11 ] ,
[ 12 , 15 ] ] )
>>> a . take ( [0 , 3 ] )
array ( [0 , 3 ] )
>>> a . take ( [0 , 3 ] , axis = 0 )
array ( [ [ 0 , 1 , 2 , 3 ] ,
[ 12 , 13 , 14 , 15 ] ] )
>>> a . take ( [0 ,3 ,2 ,2 , 2 ] , axis = 0 )
array ( [ [ 0 , 1 , 2 , 3 ] ,
[ 12 , 13 , 14 , 15 ] ,
[ 8 , 9 , 10 , 11 ] ,
[ 8 , 9 , 10 , 11 ] ,
[ 8 , 9 , 10 , 11 ] ] )
>>> a = np . array ( [0 , 1 , 2 , 3 , 4 , 5 ] , float )
>>> b = np . array ( [9 ,8 , 7 ] , float )
>>> a . put ( [0 , 3 ] ,b )
>>> a
array ( [ 9 . , 1 . , 2 . , 8 . , 4 . , 5 . ] )
2.4.3
Matrices particulières
zeros(n), zeros((n,p))
ones(n), ones((n,p))
empty((n,p))
eye(n), eye(n,p)
diag(v)
diag(v,k)
Vecteur ou matrice de 0
Vecteur ou matrice de 1
Matrice à contenu non initialisé
Diagonale de 1 et 0 ailleurs
Matrice dont la diagonale est le vecteur v
Matrice diag(v) mais diagonale décalée de k
La fonction empty ne garantit pas le contenu du tableau : on retrouve
le contenu de la mémoire utilisée. Il convient de l’utiliser s’il est certain que
toutes cases du tableau seront écrites avant d’être lues.
>>> np . empty (( 2 , 3 ) )
array ( [ [ 9 . 04197745e - 266 ,
[ - 2 . 39052760e - 043 ,
2 . 19578687e - 314 ,
6 . 35862486e - 321 ,
)
>>> np . diag ( np . ones ( 3 ) ,1 )
array ( [ [ 0 . , 1 . , 0 . , 0 . ] ,
29
4 . 25943278e - 265 ] ,
7 . 00258611e - 313 ] ]
[ 0.,
[ 0.,
[ 0.,
0.,
0.,
0.,
1.,
0.,
0.,
0.],
1.],
0.]])
>>> v = np . ones ( 5 )
>>> v
array ( [ 1 . , 1 . , 1 . , 1 . , 1 . ] )
>>> np . diag (v , 2 )
array ( [ [ 0 . , 0 . , 1 . , 0 . , 0 . ,
[ 0., 0., 0., 1., 0.,
[ 0., 0., 0., 0., 1.,
[ 0., 0., 0., 0., 0.,
[ 0., 0., 0., 0., 0.,
[ 0., 0., 0., 0., 0.,
[ 0., 0., 0., 0., 0.,
>>> np . diag (v , - 1 )
array ( [ [ 0 . , 0 . , 0 . , 0 . , 0 . ,
[ 1., 0., 0., 0., 0.,
[ 0., 1., 0., 0., 0.,
[ 0., 0., 1., 0., 0.,
[ 0., 0., 0., 1., 0.,
[ 0., 0., 0., 0., 1.,
0.,
0.,
0.,
1.,
0.,
0.,
0.,
0.],
0.],
0.],
0.],
1.],
0.],
0.]])
0.],
0.],
0.],
0.],
0.],
0.]])
On peut aussi générer des vecteurs ou des matrices aléatoires (distribution
uniforme) de nombres entre 0 et 1 avec la fonction rand(). Mais cette fonction
appartient à une sous bibliothèque random, que l’on peut appeler comme cela :
>>> np . random . rand ( 4 )
array ( [ 0 . 67059949 , 0 . 17947019 , 0 . 7217041 , 0 . 7823382 ] )
>>> np . random . rand (4 , 2 )
array ( [ [ 0 . 17309785 , 0 . 82626591 ] ,
[ 0 . 7911254 , 0 . 19542556 ] ,
[ 0 . 45654595 , 0 . 92389837 ] ,
[ 0 . 74930928 , 0 . 40855282 ] ] )
>>> from numpy . random import rand # alternative pour importer la
fonction rand
>>> rand ( 2 )
array ( [ 0 . 22220557 , 0 . 02390764 ] )
>>> rand (2 , 3 )
array ( [ [ 0 . 17719008 , 0 . 78686815 , 0 . 89788023 ] ,
[ 0 . 00363013 , 0 . 2147351 , 0 . 47286765 ] ] )
2.4.4
Opérations
On peut additionner deux vecteurs ou deux matrices de même dimensions
avec l’opérateur +. On peut aussi additionner ou multiplier un scalaire par
un vecteur ou une matrice par exemple 2.+a ou 2.*a. De même a**3 passe
chaque élément de a au cube et 1/a calcule l’inverse de chaque élément de a :
>>> a = np . random . rand (2 , 2 ) + np . ones (( 2 , 2 ) )
>>> a
array ( [ [ 1 . 59691955 , 1 . 2573431 ] ,
[ 1 . 17175816 , 1 . 70118795 ] ] )
>>> 1 / a
array ( [ [ 0 . 62620562 , 0 . 79532786 ] ,
[ 0 . 85341842 , 0 . 58782453 ] ] )
L’opérateur * entre deux vecteurs ou deux matrices de même dimension
effectue une multiplication terme à terme. Entre une matrice et un vecteur de
dimension compatible, l’opérateur * effectue une multiplication terme à terme
30
sur chaque ligne et non une multiplication algébrique (contrairement au type
matrix) :
>>> a = 3 . * np . ones (( 2 , 2 ) )
>>> a * a
array ( [ [ 9 . , 9 . ] ,
[ 9., 9.]])
>>> v = np . arange (1 , 3 )
>>> v
array ( [1 , 2 ] )
>>> a * v
array ( [ [ 3 . , 6 . ] ,
[ 3., 6.]])
Le produit algébrique se réalise avec la fonction dot() :
>>> a = np . arange ( 4 ) . reshape (2 , 2 )
>>> v = np . array ( [ -3 , 2 ] )
>>> np . dot (a , v )
array ( [2 , 0 ] )
>>> np . dot (v , a )
array ( [4 , 3 ] )
>>> w = np . concatenate (( v , v ) )
>>> w
array ( [ -3 , 2 , -3 , 2 ] )
>>> dot (a , w )
Traceback ( most recent call last ) ~ :
File " < stdin > " , line 1 , in < module >
ValueError ~ : objects are not aligned
On peut aussi réaliser le produit scalaire de 2 vecteurs avec la fonction
vdot(). Il existe aussi le produit de Kronecker avec kron() :
>>> a = np . arange (4 , dtype = float ) . reshape (2 , 2 )
>>> b = np . arange (5 , dtype = float )
>>> print a , b
[[ 0. 1.]
[ 2. 3.]] [ 0. 1. 2. 3. 4.]
>>> np . kron (a , b )
array ( [ [ 0 . ,
0.,
0.,
0.,
0.,
0.,
.],
[ 0.,
2.,
4.,
6.,
8.,
0.,
.]])
>>> np . kron (b , a )
array ( [ [ 0 . ,
0.,
0.,
1.,
0.,
2.,
.],
[ 0.,
0.,
2.,
3.,
4.,
6.,
.]])
>>> a = np . arange (5 , dtype = float )
>>> b = np . ones (( 1 , 5 ) )
>>> np . kron (a , b . transpose () )
array ( [ [ 0 . , 1 . , 2 . , 3 . , 4 . ] ,
[ 0., 1., 2., 3., 4.],
[ 0., 1., 2., 3., 4.],
[ 0., 1., 2., 3., 4.],
[ 0., 1., 2., 3., 4.]])
1.,
2.,
3.,
4
3.,
6.,
9.,
12
0.,
3.,
0.,
4
6.,
9.,
8.,
12
La fonction rank() calcule le rang d’une matrice.
2.4.5
Sous-bibliothèque linalg
La sous-bilbiothèque linalg permet l’inversion (inv()), la résolution de
systèmes linéaires (solve()), le calcul du déterminant (det()), le calcul des
31
vecteurs et valeurs propres (eig()), ou sa décomposition en valeur singulières
(svd()) :
>>> a = np . array ( [2 ,4 ,6 , 8 ] , float ) . reshape (2 , 2 )
>>> np . linalg . inv ( a )
array ( [ [ - 1 . , 0 . 5 ] ,
[ 0 . 75 , - 0 . 25 ] ] )
>>> a = np . array ( [2 ,4 ,6 , 8 ] , float ) . reshape (2 , 2 )
>>> b = np . array ( [1 , 4 ] , float )
>>> np . linalg . solve (a , b )
array ( [ 1 . , - 0 . 25 ] )
>>> b = np . array ( [ [1 , 1 ] ,[4 , - 4 ] ] , float )
>>> np . linalg . solve (a , b )
array ( [ [ 1 . , - 3 . ] ,
[ - 0 . 25 , 1 . 75 ] ] )
>>> a = np . array ( [2 ,4 ,6 , 8 ] , float ) . reshape (2 , 2 )
>>> np . linalg . eig ( a )
( array ( [ - 0 . 74456265 , 10 . 74456265 ] ) , array ( [ [ - 0 . 82456484 , - 0 .
41597356 ] ,
[ 0 . 56576746 , - 0 . 90937671 ] ] ) )
>>> (U , S , V ) = np . linalg . svd ( a )
>>> print " U : " ,U , " \ nS : " , S , " \ nV : " , V
U : [ [ - 0 . 40455358 - 0 . 9145143 ]
[ - 0 . 9145143
0 . 40455358 ] ]
S : [ 10 . 92997141
0 . 73193238 ]
V : [ [ - 0 . 57604844 - 0 . 81741556 ]
[ 0 . 81741556 - 0 . 57604844 ] ]
2.4.6
Fonctions numériques de Numpy sur les matrices
Toutes les fonction numériques de numpy s’appliquent aussi à des vecteurs
ou des matrices élément par élément :
>>> a = np . arange ( 5 )
>>> a
array ( [0 , 1 , 2 , 3 , 4 ] )
>>> np . square ( a )
array ( [ 0 , 1 , 4 , 9 , 16 ] )
2.4.7
La bibliothèque Scipy
La bibliothèque numpy ne contient pas toutes les fonctions envisageables.
Pour la compléter, il existe la bibliothèque scipy qui s’appuie sur numpy et
qui contient des fonctions de plus haut niveau.
Par exemple, la fonction numérique exp() appliquée à une matrice travaille élément par élément. Pour calculer l’exponentielle d’une matrice, il faut
utiliser les fonctions expm() (approximation de Padé), expm2() (diagonalisation) ou expm3() (série de taylor) contenues dans la sous-bibliothèque linalg
de scipy.
>>> a = np . arange ( 16 )
>>> a
array ( [ 0 , 1 , 2 , 3 ,
4,
5,
6, 7, 8,
, 15 ] )
>>> a . reshape (( 4 , 4 ) )
array ( [ [ 0 , 1 , 2 , 3 ] ,
32
9 , 10 , 11 , 12 , 13 , 14
[ 4, 5, 6, 7],
[ 8 , 9 , 10 , 11 ] ,
[ 12 , 13 , 14 , 15 ] ] )
>>> a
array ( [ 0 ,
1,
2,
3,
4,
5,
6, 7, 8,
, 15 ] )
9 , 10 , 11 , 12 , 13 , 14
>>> a = a . reshape (( 4 , 4 ) )
>>> np . exp ( a )
array ( [ [ 1 . 00000000e + 00 ,
2 . 71828183e + 00 ,
7 . 38905610e + 00 ,
2 . 00855369e + 01 ] ,
[ 5 . 45981500e + 01 ,
1 . 48413159e + 02 ,
4 . 03428793e + 02 ,
1 . 09663316e + 03 ] ,
[ 2 . 98095799e + 03 ,
8 . 10308393e + 03 ,
2 . 20264658e + 04 ,
5 . 98741417e + 04 ] ,
[ 1 . 62754791e + 05 ,
4 . 42413392e + 05 ,
1 . 20260428e + 06 ,
3 . 26901737e + 06 ] ] )
>>> import scipy . linalg as spl
# importation de la sous
biblioth è que linalg de Scipy
>>> spl . expm ( a )
array ( [ [ 6 . 20364637e + 12 ,
7 . 14131081e + 12 ,
8 . 07897526e + 12 ,
9 . 01663970e + 12 ] ,
[ 1 . 79304209e + 13 ,
2 . 06405557e + 13 ,
2 . 33506906e + 13 ,
2 . 60608254e + 13 ] ,
[ 2 . 96571954e + 13 ,
3 . 41398007e + 13 ,
3 . 86224059e + 13 ,
4 . 31050111e + 13 ] ,
[ 4 . 13839700e + 13 ,
4 . 76390456e + 13 ,
5 . 38941212e + 13 ,
6 . 01491968e + 13 ] ] )
La bibliothèque scipy propose également des fonctions de quadrature
numérique, d’intégration numérique d’équations différentielles, de résolution
numérique de systèmes d’équation, d’optimisation numérique, . . . (cf. section
3.7)
2.5
Tracer des courbes
Il existe différentes bibliothèques qui permettent de tracer des courbes. Ces
bibliothèques sont plus ou moins complètes, se caractérisent par un certain
niveau de facilité à la mise en œuvre et ont une qualité graphique donnée.
Parmi toutes celles possibles, la bibliothèque MatPlotLib présente un excellent
compromis et est d’usage extrêmement fréquent.
Sur le web, il est très simple de trouver des présentations de l’utilisation
de la bibliothèque MatPlotLib avec les codes en open source. Ici, cette section
reprend en grande partie la présentation faite par Nicolas P. Rougier sur son
site [Rou12]
2.5.1
Première approche
Voici un premier exemple très simple utilisant la sous-bibliothèque pyplot
qui permet de tracer une courbe et ouvre une fenêtre graphique avec un certain
nombre de fonctionnalités (à tester) :
1
2
3
4
5
6
# -*- coding: utf-8 -*import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages # Pour sauvegarder
en pdf
plt.plot([1,2,3,4])
plt.xlabel(’Abscisses’)
33
7
plt.ylabel(unicode(’Ordonnées’, ’utf-8’))
8
9
10
# Pour sauvegarder la figure sous forme d’image
#plt.savefig("../img/mpl_first.png",dpi=72)
11
12
13
14
15
# Pour sauvegarder la figure en pdf
pp = PdfPages("../img/mpl_first.pdf")
pp.savefig()
pp.close()
16
17
plt.show()
4.0
3.5
Ordonnées
3.0
2.5
2.0
1.5
1.00.0
0.5
1.0
1.5
Abscisses
2.0
2.5
3.0
Une autre possibilité pour obtenir un résultat équivalent est d’utiliser la
sous-bibliothèque pylab. C’est la solution que nous adopterons. Les fonctions
de pylab ressemblent beaucoup aux fonctions graphiques d’autres langages
comme Matlab ou Scilab. Nous privilégierons cette solution dans la suite.
1
2
3
4
5
# -*- coding: utf-8 -*import numpy as np
from pylab import *
# Pour sauvegarder en pdf :
from matplotlib.backends.backend_pdf import PdfPages
6
7
8
9
10
11
""" essai"""
n = 256
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
plot(X,C),plot(X,S)
12
13
14
# Pour sauvegarder la figure sous forme d’image
# plt.savefig("../img/mpl_basic.png",dpi=72)
15
16
17
18
19
# Pour sauvegarder la figure en pdf
pp = PdfPages("../img/mpl_basic.pdf")
pp.savefig()
pp.close()
20
21
show()
34
1.0
0.5
0.0
0.5
1.0 4
3
2
1
0
1
2
3
4
Une version équivalente du programme précédent, mais avec plus de détails :
1
2
3
4
# -*- coding: utf-8 -*import numpy as np
from pylab import *
from matplotlib.backends.backend_pdf import PdfPages
5
6
7
# Create a new figure of size 8x6 inches, using 80 dots per inch
figure(figsize=(8,6), dpi=80)
8
9
10
# Create a new subplot from a grid of 1x1
subplot(111)
11
12
13
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
14
15
16
# Plot cosine using blue color with a continuous line of width 1 (point)
plot(X, C, color="blue", linewidth=1.0, linestyle="-")
17
18
19
# Plot sine using green color with a continuous line of width 1 (point)
plot(X, S, color="green", linewidth=1.0, linestyle="-")
20
21
22
# Set x limits
xlim(-4.0,4.0)
23
24
25
# Set x ticks
xticks(np.linspace(-4,4,9,endpoint=True))
26
27
28
# Set y limits
ylim(-1.0,1.0)
29
30
31
# Set y ticks
yticks(np.linspace(-1,1,5,endpoint=True))
32
33
34
# To save into a png picture
#plt.savefig("../img/mpl_basic2.png",dpi=72)
35
36
37
# Pour sauvegarder la figure en pdf
pp = PdfPages("../img/mpl_basic2.pdf")
35
38
39
pp.savefig()
pp.close()
40
41
42
# Show result on screen
show()
On peut modifier la couleur, le style et l’épaisseur des courbes. À noter
qu’un pouce inch mesure 2.54cm et qu’un point typographique mesure 1/72
de pouce soit un peu plus d’un tiers de millimètre.
1
2
3
4
# -*- coding: utf-8 -*import numpy as np
from pylab import *
from matplotlib.backends.backend_pdf import PdfPages
5
6
7
figure(figsize=(8,5), dpi=80)
subplot(111)
8
9
10
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
11
12
13
plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plot(X, S, color="red", linewidth=2.5, linestyle="--")
14
15
16
xlim(-4.0,4.0)
xticks(np.linspace(-4,4,9,endpoint=True))
17
18
19
ylim(-1.0,1.0)
yticks(np.linspace(-1,1,5,endpoint=True))
20
21
22
# Pour sauvegarder la figure sous forme d’image
#plt.savefig("../img/mpl_basic3.png",dpi=72)
23
24
25
26
27
# Pour sauvegarder la figure en pdf
pp = PdfPages("../img/mpl_basic3.pdf")
pp.savefig()
pp.close()
28
29
show()
1.0
0.5
0.0
0.5
1.0 4
3
2
1
0
1
On peut modifier les limites des abscisses :
1
# -*- coding: utf-8 -*-import numpy as np
36
2
3
4
2
3
4
import numpy as np
from pylab import *
from matplotlib.backends.backend_pdf import PdfPages
5
6
7
figure(figsize=(8,5), dpi=80)
subplot(111)
8
9
10
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
11
12
13
plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plot(X, S, color="red", linewidth=2.5, linestyle="--")
14
15
16
xlim(X.min()*1.1, X.max()*1.1)
ylim(C.min()*1.1,C.max()*1.1)
17
18
19
# Pour sauvegarder la figure sous forme d’image
#plt.savefig("../img/mpl_basic4.png",dpi=72)
20
21
22
23
24
# Pour sauvegarder la figure en pdf
pp = PdfPages("../img/mpl_basic4.pdf")
pp.savefig()
pp.close()
25
26
show()
1.0
0.5
0.0
0.5
1.0
3
2
1
0
1
2
On peut modifier le pas des abscisses :
1
2
3
4
# -*- coding: utf-8 -*import numpy as np
from pylab import *
from matplotlib.backends.backend_pdf import PdfPages
5
6
7
figure(figsize=(8,5), dpi=80)
subplot(111)
8
9
10
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
11
12
13
plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plot(X, S, color="red", linewidth=2.5, linestyle="--")
14
15
xlim(X.min()*1.1, X.max()*1.1)
37
3
16
xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi])
17
18
19
ylim(C.min()*1.1,C.max()*1.1)
yticks([-1, 0, +1])
20
21
22
# Pour sauvegarder la figure sous forme d’image
#plt.savefig("../img/mpl_basic5.png",dpi=72)
23
24
25
26
27
# Pour sauvegarder la figure en pdf
pp = PdfPages("../img/mpl_basic5.pdf")
pp.savefig()
pp.close()
28
29
show()
1
0
1
3.14159265
1.57079633
0.00000000
38
1.57079633
3.14159265
Les abscisses avec du texte Latex :
1
2
3
4
# -*- coding: utf-8 -*import numpy as np
from pylab import *
from matplotlib.backends.backend_pdf import PdfPages
5
6
7
figure(figsize=(8,5), dpi=80)
subplot(111)
8
9
10
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
11
12
13
plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plot(X, S, color="red", linewidth=2.5, linestyle="--")
14
15
16
17
xlim(X.min()*1.1, X.max()*1.1)
xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
[r’$-\pi$’, r’$-\pi/2$’, r’$0$’, r’$+\pi/2$’, r’$+\pi$’])
18
19
20
21
ylim(C.min()*1.1,C.max()*1.1)
yticks([-1, 0, +1],
[r’$-1$’, r’$0$’, r’$+1$’])
22
23
24
# Pour sauvegarder la figure sous forme d’image
#plt.savefig("../img/mpl_basic6.png",dpi=72)
25
26
27
28
29
# Pour sauvegarder la figure en pdf
pp = PdfPages("../img/mpl_basic6.pdf")
pp.savefig()
pp.close()
30
31
show()
+1
0
−1
−π
−π/2
0
39
+ π/2
+π
On peut modifier le cadre et la position des axes :
1
2
3
4
# -*- coding: utf-8 -*import numpy as np
from pylab import *
from matplotlib.backends.backend_pdf import PdfPages
5
6
7
figure(figsize=(8,5), dpi=80)
subplot(111)
8
9
10
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
11
12
13
plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plot(X, S, color="red", linewidth=2.5, linestyle="--")
14
15
16
17
18
19
20
21
ax = gca()
ax.spines[’right’].set_color(’none’)
ax.spines[’top’].set_color(’none’)
ax.xaxis.set_ticks_position(’bottom’)
ax.spines[’bottom’].set_position((’data’,0))
ax.yaxis.set_ticks_position(’left’)
ax.spines[’left’].set_position((’data’,0))
22
23
24
25
xlim(X.min()*1.1, X.max()*1.1)
xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
[r’$-\pi$’, r’$-\pi/2$’, r’$0$’, r’$+\pi/2$’, r’$+\pi$’])
26
27
28
29
ylim(C.min()*1.1,C.max()*1.1)
yticks([-1, 0, +1],
[r’$-1$’, r’$0$’, r’$+1$’])
30
31
32
# Pour sauvegarder la figure sous forme d’image
#plt.savefig("../img/mpl_basic7.png",dpi=72)
33
34
35
36
37
# Pour sauvegarder la figure en pdf
pp = PdfPages("../img/mpl_basic7.pdf")
pp.savefig()
pp.close()
38
39
show()
+1
−π
−π/2
0
0
−1
40
+ π/2
+π
Ajouter une légende :
1
2
3
4
# -*- coding: utf-8 -*import numpy as np
from pylab import *
from matplotlib.backends.backend_pdf import PdfPages
5
6
7
figure(figsize=(8,5), dpi=80)
subplot(111)
8
9
10
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
11
12
13
plot(X, C, color="blue", linewidth=2.5, linestyle="-", label="cosine")
plot(X, S, color="red", linewidth=2.5, linestyle="--", label="sine")
14
15
16
17
18
19
20
21
ax = gca()
ax.spines[’right’].set_color(’none’)
ax.spines[’top’].set_color(’none’)
ax.xaxis.set_ticks_position(’bottom’)
ax.spines[’bottom’].set_position((’data’,0))
ax.yaxis.set_ticks_position(’left’)
ax.spines[’left’].set_position((’data’,0))
22
23
24
25
xlim(X.min()*1.1, X.max()*1.1)
xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
[r’$-\pi$’, r’$-\pi/2$’, r’$0$’, r’$+\pi/2$’, r’$+\pi$’])
26
27
28
29
ylim(C.min()*1.1,C.max()*1.1)
yticks([-1, +1],
[r’$-1$’, r’$+1$’])
30
31
32
legend(loc=’upper left’)
33
34
35
# Pour sauvegarder la figure sous forme d’image
#plt.savefig("../img/mpl_basic8.png",dpi=72)
36
37
38
39
40
# Pour sauvegarder la figure en pdf
pp = PdfPages("../img/mpl_basic8.pdf")
pp.savefig()
pp.close()
41
42
show()
41
cosine
sine
−π
+1
−π/2
0
+ π/2
+π
−1
Annoter des points :
1
2
3
4
# -*- coding: utf-8 -*import numpy as np
from pylab import *
from matplotlib.backends.backend_pdf import PdfPages
5
6
7
figure(figsize=(8,5), dpi=80)
subplot(111)
8
9
10
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
11
12
13
plot(X, C, color="blue", linewidth=2.5, linestyle="-", label="cosine")
plot(X, S, color="red", linewidth=2.5, linestyle="--", label="sine")
14
15
16
17
18
19
20
21
ax = gca()
ax.spines[’right’].set_color(’none’)
ax.spines[’top’].set_color(’none’)
ax.xaxis.set_ticks_position(’bottom’)
ax.spines[’bottom’].set_position((’data’,0))
ax.yaxis.set_ticks_position(’left’)
ax.spines[’left’].set_position((’data’,0))
22
23
24
25
xlim(X.min()*1.1, X.max()*1.1)
xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
[r’$-\pi$’, r’$-\pi/2$’, r’$0$’, r’$+\pi/2$’, r’$+\pi$’])
26
27
28
29
ylim(C.min()*1.1,C.max()*1.1)
yticks([-1, +1],
[r’$-1$’, r’$+1$’])
30
31
32
33
34
35
36
37
t = 2*np.pi/3
plot([t,t],[0,np.cos(t)],
color =’blue’, linewidth=1.5, linestyle="--")
scatter([t,],[np.cos(t),], 50, color =’blue’)
annotate(r’$\cos(\frac{2\pi}{3})=-\frac{1}{2}$’, xy=(t, np.cos(t)),
xycoords=’data’,
xytext=(-90, -50), textcoords=’offset points’, fontsize=16,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
38
39
40
plot([t,t],[0,np.sin(t)],
color =’red’, linewidth=1.5, linestyle="--")
42
41
42
43
44
scatter([t,],[np.sin(t),], 50, color =’red’)
annotate(r’$\sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$’, xy=(t, np.sin(t))
, xycoords=’data’,
xytext=(+10, +30), textcoords=’offset points’, fontsize=16,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
45
46
legend(loc=’upper left’)
47
48
49
# Pour sauvegarder la figure sous forme d’image
#plt.savefig("../img/mpl_basic9.png",dpi=72)
50
51
52
53
54
# Pour sauvegarder la figure en pdf
pp = PdfPages("../img/mpl_basic9.pdf")
pp.savefig()
pp.close()
55
56
show()
cosine
sine
−π
sin(23π ) =
+1
−π/2
0
−1
43
+ π/2
cos(23π ) = −12
p
+π
3
2
Quelques améliorations :
1
2
3
4
# -*- coding: utf-8 -*import numpy as np
from pylab import *
from matplotlib.backends.backend_pdf import PdfPages
5
6
7
figure(figsize=(8,5), dpi=80)
subplot(111)
8
9
10
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
11
12
13
plot(X, C, color="blue", linewidth=2.5, linestyle="-", label="cosine")
plot(X, S, color="red", linewidth=2.5, linestyle="--", label="sine")
14
15
16
17
18
19
20
21
ax = gca()
ax.spines[’right’].set_color(’none’)
ax.spines[’top’].set_color(’none’)
ax.xaxis.set_ticks_position(’bottom’)
ax.spines[’bottom’].set_position((’data’,0))
ax.yaxis.set_ticks_position(’left’)
ax.spines[’left’].set_position((’data’,0))
22
23
24
25
xlim(X.min()*1.1, X.max()*1.1)
xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
[r’$-\pi$’, r’$-\pi/2$’, r’$0$’, r’$+\pi/2$’, r’$+\pi$’])
26
27
28
29
ylim(C.min()*1.1,C.max()*1.1)
yticks([-1, +1],
[r’$-1$’, r’$+1$’])
30
31
32
legend(loc=’upper left’)
33
34
35
36
37
38
39
40
t = 2*np.pi/3
plot([t,t],[0,np.cos(t)],
color =’blue’, linewidth=.5, linestyle="--")
scatter([t,],[np.cos(t),], 50, color =’blue’)
annotate(r’$\sin\left(\frac{2\pi}{3}\right)=\frac{\sqrt{3}}{2}$’, xy=(t,
np.sin(t)), xycoords=’data’,
xytext=(+10, +30), textcoords=’offset points’, fontsize=16,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
41
42
43
44
45
46
47
plot([t,t],[0,np.sin(t)],
color =’red’, linewidth=.5, linestyle="--")
scatter([t,],[np.sin(t),], 50, color =’red’)
annotate(r’$\cos\left(\frac{2\pi}{3}\right)=-\frac{1}{2}$’, xy=(t, np.
cos(t)), xycoords=’data’,
xytext=(-90, -50), textcoords=’offset points’, fontsize=16,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
48
49
50
51
for label in ax.get_xticklabels() +ax.get_yticklabels():
label.set_fontsize(16)
label.set_bbox(dict(facecolor=’white’, edgecolor=’None’, alpha=0.65
))
52
53
54
55
# Pour sauvegarder la figure sous forme d’image
#plt.savefig("../img/mpl_basic10.png",dpi=72)
56
57
58
# Pour sauvegarder la figure en pdf
pp = PdfPages("../img/mpl_basic10.pdf")
44
59
60
pp.savefig()
pp.close()
61
62
show()
+1
cosine
sine
−π
sin
−π/2
+ π/2
0
cos
−1
2.5.2
³
p
2π ´ = 3
3
2
+π
³
2π ´ = −1
3
2
Des graphiques plus élaborés
Des exemples de graphiques plus sophistiqués sont fournis dans les fichiers
“mpl_xxxxx.py” accompagnant cette formation. Par ailleurs, il existe de très
nombreux exemples de graphiques réalisés avec MatPlotLib (code fourni) sous
le site :
matplotlib.org/gallery.html#pylab_examples.
Graphique multiple
Dans le fichier “mpl_multi_graph.py”, il y un exemple de fenêtre graphique
multiple.
45
Titre d'en haut
1.0
0.5
0.0
0.5
Ordonnée
1.00
1.0
Série 1
2
4
6
Titre d'en bas
8
10
Série 2
0.5
0.0
0.5
1.00
1
2
Abscisse
3
4
5
Graphique animé
Dans le fichier “mpl_animation.py”, il y un exemple de courbe animée :
1
2
3
4
5
6
7
# -*- coding: utf-8 -*"""
A simple example of an animated plot
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
8
9
10
fig = plt.figure()
ax = fig.add_subplot(111)
11
12
13
x = np.arange(0, 2*np.pi, 0.01)
line, = ax.plot(x, np.sin(x))
# x-array
14
15
16
17
def animate(i):
line.set_ydata(np.sin(x+i/10.0)) # update the data
return line,
18
19
20
21
22
#Init only required for blitting to give a clean slate.
def init():
line.set_ydata(np.ma.array(x, mask=True))
return line,
23
24
25
26
ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), init_func
=init,
interval=25, blit=True)
plt.show()
46
Un autre exemple (fichier “mpl_animation2.py”) décrit le mouvement
d’un pendule double :
1
2
3
# -*- coding: utf-8 -*# Double pendulum formula translated from the C code at
# http://www.physics.usyd.edu.au/~wheat/dpend_html/solve_dpend.c
4
5
6
7
8
9
from numpy import sin, cos, pi, array
import numpy as np
import matplotlib.pyplot as plt
import scipy.integrate as integrate
import matplotlib.animation as animation
10
11
12
13
14
15
G = 9.8
L1 = 1.0
L2 = 1.0
M1 = 1.0
M2 = 1.0
#
#
#
#
#
acceleration due to gravity, in m/s^2
length of pendulum 1 in m
length of pendulum 2 in m
mass of pendulum 1 in kg
mass of pendulum 2 in kg
16
17
18
def derivs(state, t):
19
20
21
dydx = np.zeros_like(state)
dydx[0] =state[1]
22
23
24
25
26
27
del_ = state[2]-state[0]
den1 = (M1+M2)*L1 -M2*L1*cos(del_)*cos(del_)
dydx[1] =(M2*L1*state[1]*state[1]*sin(del_)*cos(del_)
+ M2*G*sin(state[2])*cos(del_) +M2*L2*state[3]*state[3]*
sin(del_)
- (M1+M2)*G*sin(state[0]))/den1
28
29
dydx[2] =state[3]
30
31
32
33
34
35
den2 = (L2/L1)*den1
dydx[3] =(-M2*L2*state[3]*state[3]*sin(del_)*cos(del_)
+ (M1+M2)*G*sin(state[0])*cos(del_)
- (M1+M2)*L1*state[1]*state[1]*sin(del_)
- (M1+M2)*G*sin(state[2]))/den2
36
37
return dydx
38
39
40
41
# create a time array from 0..100 sampled at 0.1 second steps
dt = 0.05
t = np.arange(0.0, 20, dt)
42
43
44
45
46
47
48
# th1 and th2 are the initial angles (degrees)
# w10 and w20 are the initial angular velocities (degrees per second)
th1 = 120.0
w1 = 0.0
th2 = -10.0
w2 = 0.0
49
50
rad = pi/180
51
52
53
# initial state
state = np.array([th1, w1, th2, w2])*pi/180.
54
55
56
# integrate your ODE using scipy.integrate.
y = integrate.odeint(derivs, state, t)
57
58
x1 = L1*sin(y[:,0])
47
59
y1 = -L1*cos(y[:,0])
60
61
62
x2 = L2*sin(y[:,2]) +x1
y2 = -L2*cos(y[:,2]) +y1
63
64
65
66
fig = plt.figure()
ax = fig.add_subplot(111, autoscale_on=False, xlim=(-2, 2), ylim=(-2, 2)
)
ax.grid()
67
68
69
70
line, = ax.plot([], [], ’o-’, lw=2)
time_template =’time =%.1fs’
time_text =ax.text(0.05, 0.9, ’’, transform=ax.transAxes)
71
72
73
74
75
def init():
line.set_data([], [])
time_text.set_text(’’)
return line, time_text
76
77
78
79
def animate(i):
thisx = [0, x1[i], x2[i]]
thisy = [0, y1[i], y2[i]]
80
81
82
83
line.set_data(thisx, thisy)
time_text.set_text(time_template%(i*dt))
return line, time_text
84
85
86
ani = animation.FuncAnimation(fig, animate, np.arange(1, len(y)),
interval=25, blit=True, init_func=init)
87
88
89
#ani.save(’../img/mpl_animation2.mp4’, fps=15, clear_temp=True)
plt.show()
Pour la dimension 3
Le fichier “mpl_surf.py” est un exemple de représentation en 3D d’une
fonction à deux variables.
2.0
1.5
1.0
0.5
0.0
0.5
1.0
1.5
2.0
4
3
2
1
0
1
2
3
4
3
2
1
0
1
2
3
Le fichier “mpl_contour.py” est un exemple de représentation d’une fonc48
tion à deux variables en niveaux de couleur et en contours.
0.5
0.75
0
0
50
-0.250
0
0.500
0.75
00
0
0.00
-0.
1.000
0.250
49
3
Structures algorithmiques
Sommaire
3.1
3.2
3.3
3.4
3.5
3.6
3.7
Types de données dynamiques
3.1.1 Listes
3.1.2 Tuples
3.1.3 Tables de hachage
Boucles et conditionnelles
3.2.1 Conditionnelle
3.2.2 Type booléen
3.2.3 Boucles
3.2.4 Boucle définissant une liste
Définition de fonction
3.3.1 Variables locales et globales
3.3.2 Valeur(s) de retour
3.3.3 Valeur par défaut des paramètres
3.3.4 Fonctions récursives
Lancement d’un programme
3.4.1 Ligne de commande
3.4.2 Récupérer les arguments de la ligne de commande
3.4.3 Type string
3.4.4 Opérateur %
3.4.5 Affichage
Algorithmes de tri
3.5.1 Tri par sélection
3.5.2 Tri bulles
3.5.3 Tri par insertion
3.5.4 Tri shell
3.5.5 Tri par segmentation, ou Quicksort
3.5.6 Méthode sort des listes de Python
3.5.7 Complexité des algorithmes de tris
Modules
Simulations numériques
3.7.1 Tirages aléatoires et statistiques
3.7.2 Résolution d’équation(s)
3.7.3 Quadrature numérique
3.7.4 Intégration numérique des ODE
C
51
51
52
52
53
53
54
54
55
55
55
56
57
57
58
58
58
59
60
60
60
60
62
63
65
66
67
67
68
69
69
70
71
71
omme tout langage informatique, Python est Turing-complet. Contrairement à beaucoup, le code est pauvre en signes de ponctuation et
toujours bien indenté, ce qui le rend agréable à lire.
50
Les mots-clefs et les identifiants sont tous sensibles à la casse des caractères : foo, Foo, fOO et FOO sont des variables différentes.
Les caractères suivant un # sont des commentaires, destinés aux autres
lecteurs du code source. La première ligne # -*- coding: utf-8 -*- est particulière : elle indique à la machine virtuelle Python que le code source est écrit
en UTF-8, ce qui permet les caractères accentués.
3.1
3.1.1
Types de données dynamiques
Listes
Une liste permet de stocker des successions de valeurs, et de les retrouver
par leur index dans la structure. Elle peut être modifiée : modification des
éléments présents, suppression, et ajout d’élément(s).
Une list s’écrit entre crochets : tab = [6, 7].
La numérotation des cases commence à 0. L’index se place entre crochets : tab[4]. Il est possible de sélectionner des tranches de ces structures :
tab[1:4], tab[:5], tab[3:], tab[1:-1]. Le premier élément est inclus, le
dernier est exclu : tab[1:3] contient les cases 1 et 2. L’élément d’indice -1
est le dernier élément de la liste, l’élément d’indice -2 le pénultième, etc.
Il n’est pas possible de créer une nouvelle case à une liste par une simple
affectation. Si tab est de taille 8, tab[8]=42 entraîne une erreur. Il faut ajouter
la nouvelle valeur par tab.append(42). On peut concaténer liste2 à liste1
par liste1.extend(liste2).
L’opérateur len() donne le nombre d’éléments de la liste : len([3, 7,
[5, 3], "Last"]) renvoie 4.
On peut supprimer un élément d’une liste en connaissant son index i
par del tab[i]. On peut supprimer le premier élément ayant une certaine
valeur val par tab.remove(val). Attention : tab.remove(tab[i]) ne supprime donc pas forcément l’élément d’index i.
La méthode pop() supprime et renvoie le dernier élément d’une liste :
liste = [9 , 6 , 42 ]
x = liste . pop ()
La variable x vaut désormais 42, et liste vaut [9, 6].
La méthode insert(i, x) insère l’élément x à l’indice i. Si i est supérieur
ou égal à la taille de la liste, x est inséré en dernière position, comme un appel
à append(x).
liste = [9 , 6 , 42 ]
liste . insert (1 , 7 )
liste . insert ( 100 , 24 )
La variable liste vaut désormais [9, 7, 6, 42, 24].
On peut tester l’appartenance d’un élément à une liste par l’opérateur in :
primes = [2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 ]
if 5 in primes :
print " % i is a prime number " % ( 5 )
51
Un tableau à deux dimensions n’est rien d’autre qu’une liste de listes qui
sont toutes de la même longueur.
Attention : pour faire une liste de n listes vides, il ne faut pas écrire tab
= n*[[]], car on aurait n copies de la même liste :
>>> tab = 4 * [ [ ] ]
>>> tab [ 1 ] . append ( 42 )
>>> print tab
[ [ 42 ] , [ 42 ] , [ 42 ] , [ 42 ] ]
mais :
>>> tab = [ ]
>>> for i in range ( 4 ) :
...
tab . append ( [ ] )
...
>>> tab [ 1 ] . append ( 42 )
>>> print tab
[ [ ] , [ 42 ] , [ ] , [ ] ]
Une variable de type list référence une zone mémoire. Si deux variables
référencent une même zone mémoire, modifier l’une impacte l’autre :
>>> grg1 = [ " Earth " , " : " , " harmless " ]
>>> grg2 = grg1
>>> grg2 . insert (2 , " mostly " )
>>> print grg1
[ ’ Earth ’ , ’: ’ , ’ mostly ’ , ’ harmless ’]
Extraire une tranche d’une liste réalise une copie d’une partie du contenu
d’une liste (éventuellement la liste totale). Ce comportement est différent des
tableaux de numpy (cf. section 2.4.1).
>>> grg1 = [ " Earth " , " : " , " harmless " ]
>>> grg2 = grg1 [ : ]
>>> grg2 . insert (2 , " mostly " )
>>> print grg1
[ ’ Earth ’ , ’: ’ , ’ harmless ’]
3.1.2
Tuples
Un tuple permet de stocker des successions de valeurs, et de les retrouver
par leur index dans la structure, mais ne peut pas être modifié : on dit qu’il
est non-mutable.
Un tuple s’écrit entre parenthèses : tup = (6, 7). Il peut contenir tout
type de données non-mutable, y compris d’autres tuples : tup = (6, 7.05,
"Fish", (-5, "Dolphin")).
On accède aux éléments d’un tuple par leurs index ou leurs tranches d’index exactement comme pour une liste. La fonction len() et l’opérateur in
s’appliquent également.
3.1.3
Tables de hachage
Une table de hachage (type dict) associe des clefs à des valeurs. Les clefs
doivent produire un code de hachage qui permet de les retrouver dans la table,
et donc ne peuvent pas être modifiées. Les types bool, int, float, str, tuple
et frozenset conviennent, mais pas list, dict ou set.
52
Un type non-mutable peut disposer d’une fonction de hachage (son contenu ne variant pas, son code de hachage est une constante) alors qu’un type
mutable ne le peut pas. Si tab est de type list, hash(tab) génère une erreur : TypeError: unhashable type: ’list’, alors que pour tup de type tuple,
hash(tup) renvoie un entier sur 64 bits.
Une table de hachage s’écrit entre accolades :
thash = { key1 : val1 , key2 : val2 }
L’ordre dans lequel les éléments sont ajoutés n’est pas préservé 1 .
On peut récupérer la liste des clefs par thash.keys(), celle des valeurs par
thash.values(), tester la présence d’une clef par : key in thash, supprimer
une entrée par : del thash[key].
Si seules les clefs importent, et pas les valeurs, il peut être préférable d’utiliser les types set et frozenset.
3.2
3.2.1
Boucles et conditionnelles
Conditionnelle
Le branchement s’écrit :
if cond: ... [elif cond: ... :]* [else: ... ].
1
2
3
4
5
6
7
x = 42
if x != int(x):
print "Non-integer"
elif x<0:
print "Negative integer"
else:
print "Positive integer"
Entre if et les deux-points, il est possible de mettre toute expression
booléenne, issue par exemple d’un opérateur de comparaison comme ==, <, >,
<=, >= ou !=. Notez que l’opérateur de test d’égalité est == alors que l’opérateur d’affectation est =. Le test de non-égalité s’écrit!=. L’opérateur de test
d’appartenance in construit également une expression booléenne.
Il est possible de combiner des expressions booléennes par and, or et not.
Il est possible d’inverser le comportement de in en le remplaçant par not in.
L’instruction pass ne fait rien, et permet éventuellement de remplir une
obligation syntaxique (Python n’accepte pas les blocs vides).
if x < 0 or x > = 20 :
pass
else :
print " % i has a value in [0 , 20 [ " % ( x )
Notez que prendre le complémentaire de l’expression booléenne fonctionne
aussi, et est plus élégant :
if not ( x < 0 or x > = 20 ) :
print " % i has a value in [0 , 20 [ " % ( x )
1. Python 3.3 devrait permettre un certain contrôle sur cet ordre d’insertion, mais ce
n’est normalement pas le rôle d’une table de hachage.
53
ou encore :
if x > = 0 and x < 20 :
print " % i has a value in [0 , 20 [ " % ( x )
Il n’existe pas d’équivalent du switch ... case courant dans d’autres
langages. Il convient d’utiliser une succession de elif pour choisir entre de
multiples actions possibles en fonction de la valeur d’une variable.
3.2.2
Type booléen
Il est également possible d’affecter la valeur d’une expression booléenne à
une variable, lequel est donc de type bool, et peut prendre uniquement les
deux valeurs True et False.
>>> b = 8 > 3 and not 9 in (7 , 6 , " Fish " )
>>> print b
True
>>> print True or False
True
3.2.3
Boucles
La boucle for s’écrit :
for var in tab :
instructions
Le corps de la boucle est exécuté une fois pour chaque élément de tab,
lequel peut être tout objet contenant une succussion d’éléments. Il peut donc
s’agir d’une liste, mais aussi d’une table de hachage, d’un tuple, d’un fichier,
ou d’une fonction itératrice comme range().
La fonction range() permet (entre autres) de générer une succession d’indices pour for, mais aussi toute succession de nombres : range(start, end,
step) correspond au vecteur Matlab/Octave start:step:end-step.
La boucle while s’écrit :
while cond :
instructions
Le corps de la boucle est exécuté chaque fois que la condition est vraie,
et la boucle s’arrête dès que la condition est testée comme fausse. Il est donc
possible que le corps de la boucle ne soit jamais exécuté.
À l’intérieur d’une boucle while ou for, l’instruction continue permet de
passer à l’itération suivante, et l’instruction break de quitter la boucle.
L’exemple suivant comporte trois boucles. Dans la première, x prend successivement les valeurs contenues dans les cases de tab. La seconde et la
troisième boucles ont exactement le même comportement : l’indice i prend
successivement toutes les valeurs entières de 0 à len(tab)-1, c’est-à-dire les
valeurs d’index valides pour tab.
1
2
3
tab = [6, 7, 2, 8, 42, 14]
for x in tab:
if 42%x!=0:
54
4
5
continue
print x
6
7
8
for i in range(len(tab)):
print i, tab[i]
9
10
11
12
13
14
15
3.2.4
i =0
while True:
if i==len(tab):
break
print i, tab[i]
i += 1
Boucle définissant une liste
Il est immédiat de faire une boucle qui remplit une liste par des appels
successifs à append() :
y = []
for x in arange ( - 10 , 10 , 0 . 1 ) :
y . append ( x ** 3 )
Toutefois ces appels à append() sont assez coûteux en temps de calcul,
et la syntaxe est assez lourde. Python propose une alternative plaçant for à
l’intérieur de la définition de la liste.
y = [ x ** 3 for x in arange ( - 10 , 10 , 0 . 1 ) ]
3.3
Définition de fonction
Il est bien sûr possible de créer ses propres fonctions, qui reçoivent éventuellement des paramètres à traiter, et renvoient un résultat via return.
La fonction se déclare avec le mot-clé def.
1
2
3
# Computes the discriminant of ax^2+bx+c
def discr(a, b, c):
return b**2-4*a*c
4
5
6
7
8
9
10
11
3.3.1
# Computes the root(s) of ax^2+bx+c
def roots(a, b, c):
delta = discr(a, b, c)
if delta >0:
return (-b-delta**0.5)/(2*a), (-b+delta**0.5)/(2*a)
elif delta ==0:
return -b/(2.0*a)
Variables locales et globales
Si on affecte une valeur à une variable dans la fonction, on définit une
variable locale. Cette variable n’existe qu’à l’intérieur de la fonction, et n’est
plus accessible ensuite. Si une fonction f1 a une variable locale x et appelle
une fonction f2, la variable x n’est pas disponible dans f2.
Les paramètres de la fonction se comportent comme des variables locales
à cette fonction.
Si une variable existe déjà à l’extérieur de la méthode avec le même nom –
c’est donc une variable globale – la variable locale masque la variable globale.
55
Les opérations réalisées à l’intérieur de la fonction portent uniquement sur la
variable locale, et la variable globale de même nom n’est pas modifiée.
Si on souhaite modifier une variable globale à l’intérieur d’une fonction, il
convient de faire référence à cette variable globale par global foo.
L’exécution du programme suivant affiche : 43 42 45 46 45
1
2
3
def f_loc(x):
a =x
print a,
4
5
6
7
8
def f_glob(x):
global a
a =x
print a,
9
10
11
def g(x):
print a,
12
13
14
15
16
17
18
3.3.2
a = 42
f_loc(43)
g(44)
f_glob(45)
f_loc(46)
g(47)
Valeur(s) de retour
Si return est suivi par plusieurs paramètres, ceux-ci sont placés dans un
tuple. S’il n’y a pas de return (cas où δ < 0 dans roots), la valeur renvoyée
est la valeur spéciale 2 None de type NoneType.
Si on souhaite garantir que roots renvoie toujours un tuple, même vide,
il faut traiter le cas δ < 0, et forcer la création d’un tuple quand δ =
0, par l’ajout d’une virgule ou la création explicite d’un tuple avec return
tuple([-b/2/a]).
1
2
3
4
5
6
7
8
9
10
""" Computes the root(s) of ax^2+bx+c """
""" Returns a tuple """
def roots(a, b, c):
delta = discr(a, b, c)
if delta >0:
return (-b-delta**0.5)/2/a, (-b+delta**0.5)/2/a
elif delta ==0:
return -b/2/a,
else:
return ()
Si la fonction renvoie un tuple de valeurs, il est possible d’affecter directement ces valeurs à pusieurs variables :
1
2
3
4
5
6
7
# Swaps x and y if x>y
def order2(x, y):
if x<y:
return x,y
else:
return y,x
print order2(7,6)
Un return met fin à l’appel de la fonction.
2. Cette valeur spéciale est appelée null dans de nombreux autres langages.
56
3.3.3
Valeur par défaut des paramètres
Il est possible de donner des valeurs par défaut aux arguments d’une fonction.
1
2
def norme(x, y=0, z=0):
return (x**2+y**2+z**2)**0.5
Ainsi, des appels à norme(0,4,3), à norme(4,3), à norme(-5), à norme(4,z=3),
ou à norme(0,z=4,y=3) renvoient 5.0.
Un appel à norme(y=4, z=3) provoque une erreur : x n’a pas de valeur.
3.3.4
Fonctions récursives
Une fonction est dite récursive si elle est capable de s’appeler elle-même.
En général, une telle fonction modifie les paramètres d’appel, et dispose
d’une condition d’arrêt qui, lorsqu’elle est vérifiée, fait qu’il n’y a pas d’appel
récursif.
Il est souvent 3 possible d’écrire une fonction récursive sous la forme d’une
simple boucle, en général plus rapide à l’exécution, et moins simple à écrire et
à comprendre.
Factorielle, récursive et non-récursive :
1
2
3
4
5
6
# -*- coding: utf-8 -*def factorielle(n):
if n<2:
# Condition d’arrêt
return 1
else:
# Appel récursif
return factorielle(n-1)*n
7
8
9
10
11
12
def factorielle_boucle(n):
res = 1
for k in range(2, n+1):
res *= k
return res
Recherche d’un zéro d’une fonction par dichotomie :
1
2
3
# -*- coding: utf-8 -*def f0(x):
return x**3
4
5
6
def f1(x):
return x**3-1
7
8
9
def f2(x):
return x**3-2
10
11
12
13
14
def dichotomie(f, a, b, eps=1e-6):
if b-a<=eps:
# Condition d’arrêt :précision atteinte
return (a, b)
if f(a)*f(b)>0: # Condition d’arrêt :pas de racine
3. La fonction d’Ackermann ne peut pas être écrite sous forme de récursion primitive, ni
sous forme de boucle :
A(m, n) =

n + 1

A(m − 1, 1)
A(m − 1, A(m, n − 1))
57
if m = 0
if m > 0 and n = 0
if m > 0 and n > 0.
return None
z = f(0.5*(a+b))
if z==0:
# Condition d’arrêt :racine trouvée
return 0.5*(a+b)
if z*f(a)<0:
# Racine sur la gauche
return dichotomie(f, a, 0.5*(a+b), eps)
else:
# Racine sur la droite
return dichotomie(f, 0.5*(a+b), b, eps)
15
16
17
18
19
20
21
22
23
24
25
26
27
print
print
print
print
"Racine
"Racine
"Racine
"Racine
de
de
de
de
f0
f1
f2
f0
entre
entre
entre
entre
-4 et 4 :", dichotomie(f0, -4, 4, 1e-10)
-4 et 4 :", dichotomie(f1, -4, 4)
-4 et 4 :", dichotomie(f2, -4, 4)
1 et 4 :", dichotomie(f0, 1, 4)
Le résultat de ce programme est :
Racine
Racine
Racine
Racine
de
de
de
de
f0
f1
f2
f0
entre
entre
entre
entre
-4 et 4 : 0.0
-4 et 4 : 1.0
-4 et 4 : (1.2599201202392578, 1.2599210739135742)
1 et 4 : None
3.4
Lancement d’un programme
Il est possible d’appeler l’interpréteur Python à partir d’un environnement
de développement intégré. Sous spyder cela se fait par F5, sous Eclipse par
F11 ou Ctrl-F11. Il est possible de préciser les options de ligne de commande.
On peut préciser les paramètres à passer au script dans le menu d’exécution.
3.4.1
Ligne de commande
Pour exécuter un script foo.py à partir d’une terminal on tape simplement : python foo.py
Sur un système Unix/Linux, si la première ligne du script est de la forme
#!/usr/bin/python et que l’utilisateur a des droits en exécution dessus (bit
x fixé), il suffit de taper foo.py.
3.4.2
Récupérer les arguments de la ligne de commande
Le module sys donne accès à l’environnement du script. Notamment :
argv : éléments de la ligne de commande. argv[0] est le nom du script, et les
éléments suivants contiennent ses options et paramètres. Chaque élément
est une chaîne de caractère, de type str : si l’argument souhaité est
numérique, il convient de le transtyper par k = int(argv[1]) ou x =
float(argv[1]).
stdin : entrée standard, c’est-à-dire le clavier par défaut.
stdout : sortie standard, c’est-à-dire le terminal d’où est exécuté le script par
défaut.
stderr : sortie d’erreur.
1
import sys
2
3
4
s =0
for x in sys.argv[1:]:
58
5
6
s += float(x)
print "Total :",s
Le script précédent s’appelant sum.py, un appel à :
python sum.py 31 -9.5 20.5
provoquera l’affichage de :
Total : 42.0
3.4.3
Type string
Le type chaîne de caractères est nommé str en Python. Une chaîne de
caractère est délimitée par des apostrophes 4 ou des guillemets.
Certains caractères spéciaux, comme les tabulations ou les retours à la
ligne, sont codés par caractères échappés : ’\t’ pour une tabulation, ’\n’
pour un retour à la ligne. Il faut échapper l’anti-slash par ’\\’ pour l’inclure
dans une chaîne de caractères.
>>> table = " Nom\t| Age\nMar\\/in\t|60E9"
>>> print table
Nom
| Age
Mar\/in |60E9
On peut demander à Python de ne pas interpréter les échappements dans
une chaîne en la précédant par r.
>>> table = r" Nom\t| Age\nMar\\/in\t|60E9"
>>> print table
Nom\t| Age\nMar\\/in\t|60E9
Il est possible de référencer l’un des caractères en considérant la chaîne
comme une liste (s[3] pour le 4e caractère), mais chaque caractère est luimême de type str. Une chaîne de caractère est non-mutable : on ne peut pas
modifier l’un de ses éléments par s[3]=’z’ (comme pour les tuples).
On peut découper une chaîne de caractères en mots par la méthode split().
>>> s = " The answer is 42 . "
>>> s . split ()
[ ’ The ’ , ’ answer ’ , ’ is ’ , ’ 42 . ’]
On peut spécifier un délimiteur à split :
>>> s . split ( ’e ’)
[ ’ Th ’ , ’ answ ’ , ’r is 42 . ’]
Des outils plus évolués de manipulation de chaîne de caractères sont accessibles par le module re (section 6.1).
4. Il existe plusieurs codages des apostrophes : p est différent de ’ ou de ‘. Le premier est
un délimiteur valide pour les chaînes de caractères, et s’obtient par la touche “4” du clavier.
Le second, plus joli, est généré par LATEX et se trouve dans les codes sources de ce document ;
il vous posera des problèmes en cas de copier-coller depuis le document pdf. Le troisième,
appelé anti-quote, sert à réaliser des appels au système d’exploitation ; il s’obtient par la
touche “7” du clavier et peut apparaître comme plus semblable à 0 .
59
3.4.4
Opérateur %
L’opérateur % permet de placer une ou plusieurs valeurs dans une chaîne :
" Sinus de % i degr é s ~ : % 1 . 4f " % (x , math . sin ( x * math . pi / 180 ) )
Il doit y avoir autant d’éléments dans le tuple de valeurs à insérer que de
caractères % dans la chaîne de caractères. La lettre qui suit le caractère % dans
la chaîne détermine le type d’information à écrire : d ou i pour un nombre
entier décimal ; x pour un nombre entier hexadécimal ; f, e, g, E ou G pour un
nombre à virgule flottante ; s pour une chaîne de caractères, . . . . Les nombres
qui précèdent permettent de maîtriser le nombre de caractères à écrire, et
notamment la précision d’une nombre à virgule flottante.
3.4.5
Affichage
L’instruction print permet l’écriture sur la sortie standard. Lors d’un
appel à print x, si x n’est pas une chaîne de caractères, x est converti en
chaîne de caractères par str(x).
Il est possible 5 de demander l’affichage de plusieurs objets en les séparant
par des virgules :
print 6 , " x " , 7 , " = " , 6 * 7
Si le dernier objet est suivi d’une virgule, il n’y a pas de retour à la ligne :
print 6 , " x " , 7 , " = " ,
print 6 * 7
3.5
Algorithmes de tri
Définition 3.1 (Problème de tri). Soit une suite de n nombres : a1 , a2 , ..., an .
Trier cette suite de nombres revient à trouver une permutation σ1 , ..., σn de
1, ..., n telle que aσ1 6 aσ2 6 ... 6 aσn .
Le tri est un algorithme de base nécessaire pour bien d’autres algorithmes.
Il permet de plus d’introduire la plupart des notions algorithmiques. Il existe
de nombreux algorithmes de tris, plus ou moins simples à appréhender et
plus ou moins efficaces. La plupart des ouvrages d’algorithmique, comme par
exemple [CLRS94] décrivent les algorithmes de tris les plus classiques. Pour
une analyse relativement détaillée des méthodes de tris les plus classiques,
consulter [Knu73].
Dans tous les exemples suivants, l’algorithme de tri sera appliqué à un
tableau d’entiers, mais il est possible de trier tout ensemble de données muni
d’une relation d’ordre total (il est par exemple possible de trier un ensemble
de mots suivant l’ordre lexicographique).
3.5.1
Tri par sélection
Le tri par sélection est un tri extrêmement intuitif mais particulièrement
inefficace. L’idée de base de l’algorithme est la suivante : rechercher le plus
petit élément du tableau et l’échanger avec l’élément en première position.
5. Un des changements provoqués par Python 3 concerne print : cette instruction se
comportera comme une fonction et s’appellera par print(6, "x", 7, "=", 6*7).
60
Recommencer avec le deuxième plus petit élément, et continuer jusqu’au n−1e
plus petit élément.
Exemple :
7*
1
1
1
1
2
2**
2
2
2
1*
7
7*
4
4
8
8
8
8*
7
4
4
4*
7*
8
Les éléments à permuter sont marqués d’un « * ». Remarquer que lors de
la seconde étape l’élément 2 est permuté avec lui-même.
L’algorithme du tri par sélection est décrit par l’algorithme 1. Il se traduit
en Python par la fonction trisel().
Algorithme 1: Algorithme du tri par sélection
Entrées : tab : entier[]
Données : indMin, i, j, n : entier
n ← taille(tab) ;
pour i ∈ [0, n − 2] faire
indM in ← i ;
pour j ∈ [i + 1, n − 1] faire
si tab[j] < tab[indM in] alors
indM in ← j ;
fin
fin
inverser(tab[indM in], tab[i]);
fin
1
2
3
4
5
6
7
8
def trisel(tab):
n = len(tab)
for i in range(n-1):
indmin =i
for j in range(i+1, n):
if tab[j] <tab[indmin]:
indmin =j
tab[i], tab[indmin] =tab[indmin], tab[i]
Étude du tri par sélection
La notion de complexité permet d’évaluer l’efficacité des algorithmes. Elle
permet de répondre à la question : entre différents algorithmes réalisant une
même tâche, quel est le plus rapide et dans quelles conditions ?
La réponse à cette question, lorsqu’on souhaite légitimement s’abstraire
des facteurs matériels est de quantifier le nombre d’opérations élémentaires
nécessaires pour résoudre le problème.
Définition 3.2. La complexité en temps est le nombre d’opération élémentaires permettant de résoudre un problème de taille N .
61
Donald Knuth fut un des premiers à l’appliquer systématiquement dans
[Knu68].
La complexité est évaluée en fonction de la taille N des données d’entrée,
où la taille est le nombre d’octets nécessaires pour stocker l’information des
données d’entrée de l’algorithme.
Les opérations élémentaires sont le plus souvent les opérations portant directement sur les données, comparaisons, affectation, modifications ou opérateurs arithmétiques. Il est courant d’omettre les opérations sur les indices
lorsque leur nombre n’est pas d’un ordre de grandeur supérieur aux opérations
sur les données : ces opérations sur les indices sont en général individuellement
plus rapides, et beaucoup plus sensibles aux optimisations d’un compilateur.
La complexité peut être évaluée dans le pire des cas, c’est-à-dire pour la
répartition des données provoquant le plus d’opérations mais il est également
possible de calculer la complexité moyenne, c’est-à-dire la moyenne des complexités pour toutes les données d’entrée possibles.
Remarque. La complexité en moyenne est généralement beaucoup plus difficile
à calculer que dans le pire des cas, mais elle donne souvent des informations
plus pertinentes. Elle s’appuie toutefois sur une loi de probabilité sur les données qui peut être difficile à obtenir.
Dans le cas du tri par sélection, remarquons que tous les cas sont identiques : la complexité dans le pire des cas est la complexité de tous les cas.
Rechercher le plus petit élément force à parcourir le tableau et coûte donc
n − 1 comparaisons. La recherche du deuxième plus petit élément coûte n − 2
Pn−1
i = n(n−1)
comparaisons. Le coût total du tri par sélection est donc de i=1
.
2
Il est d’usage de ne garder que le terme prépondérant de la complexité et de
ne pas prendre en compte les constantes multiplicatives.
On dit alors que la complexité en moyenne et dans le pire des cas du tri
par sélection est de Θ(n2 ).
Remarque. La complexité de la plupart des algorithmes de tris intuitifs est de
Θ(n2 ). La meilleure complexité possible pour un tri est de Θ(n log n) (voir la
section 3.5.7 pour une démonstration de cette proposition).
3.5.2
Tri bulles
Le tri bulles est un tri très populaire, très facile à mettre en œuvre. Son
fonctionnement s’appuie sur des permutations répétées d’éléments contigus
qui ne sont pas dans le bon ordre.
Algorithme 2: Algorithme du tri bulles
Entrées : tab : entier[]
Données : i, j, n : entier
n ← taille(tab);
pour i ∈ [n − 1, 1] faire
pour j ∈ [0, i − 1] faire
si tab[j] > tab[j + 1] alors
inverser(tab[j], tab[j + 1]);
fin
fin
fin
62
L’idée de l’algorithme est de faire remonter le plus grand élément comme
une bulle, puis de faire remonter l’élément suivant et ainsi de suite. Ainsi,
lors de la première itération, chaque élément du tableau est comparé à son
successeur, et permuté si nécessaire. À la fin de cette itération, le plus grand
élément a été placé en fin de tableau. On recommence alors l’itération sur les
n − 1 premières cases, puis sur les n − 2 premières, etc. Cet algorithme est
décrit figure 2.
1
2
3
4
5
6
def tribulles(tab):
n = len(tab)
for i in range(n-1,0,-1):
for j in range(0, i):
if tab[j] >tab[j+1]:
tab[j], tab[j+1] =tab[j+1], tab[j]
Étude du tri bulles
L’étude de la complexité du tri bulles est très simple, et similaire à celle du
tri par sélection. Encore une fois, tous les cas sont équivalents, et la complexité
en moyenne et dans le pire des cas valent Θ(n2 ).
3.5.3
Tri par insertion
Le tri par insertion est une méthode de tri efficace dans le cas où le nombre
d’éléments à trier est relativement faible ou dans le cas où le tableau est
pratiquement ordonné. Le principe de l’algorithme (décrit dans la figure 3) est
le suivant : le tableau à trier est découpé en deux parties. La partie de gauche
est triée, et la partie de droite non triée. On insère alors successivement les
éléments de la partie non triée à leur place dans la partie triée. Initialement,
le premier élément est seul dans la partie triée. L’élément à insérer dans la
partie triée est nommé clé.
Afin d’insérer la clé à sa place dans la partie triée, il faut décaler tous les
éléments qui lui sont supérieurs d’un cran vers la droite.
Remarque. bien noter qu’il s’agit ici d’un décalage d’éléments et pas d’une
permutation.
Algorithme 3: Algorithme du tri par insertion
Entrées : tab : entier[]
Données : i, j, n, cle : entier
n ← taille(tab) ;
pour i ∈ [1, n − 1] faire
cle ← tab[i] j ← i;
tant que j > 0 et tab[j − 1] > cle faire
tab[j] ← tab[j − 1] ;
décrémenter j ;
fin
tab[j] ← cle
fin
Exemple d’insertion de clé :
63
1
3
4
2
Dans cet exemple, la clé vaut 2. Lors de son insertion, on passe par les
étapes suivantes :
1
1
1
1
3
3
3
2
4
4
3
3
2
4
4
4
L’élément 4 est supérieur à la clé, et il a donc été copié d’un cran à droite
(à ce moment, il apparaît donc deux fois). Ensuite, l’élément 3 a été copié un
cran à droite. Enfin, la clé a été insérée à sa place.
En utilisant la méthode d’insertion vu précédemment, voici un exemple
d’étapes du tri par insertion. Considérons le tableau ci-dessous :
5
2
6
3
1
Dans ce tableau, 5 fait partie de la partie triée. La première étape consiste
à insérer la clé 2 dans la partie triée. On obtient alors le tableau suivant, où
les deux premières valeurs sont triées :
2
5
6
3
1
On poursuit alors les itérations avec comme clés successives 6, 3 et 1 :
2
2
1
1
2
3
4
5
6
7
8
9
5
3
2
6
5
3
3
6
5
1
1
6
def triins(tab):
n = len(tab)
for i in range(1,n):
cle = tab[i]
j =i
while j>0 and tab[j-1]>cle:
tab[j] =tab[j-1]
j -= 1
tab[j] =cle
Étude du tri par insertion
Le tri par insertion est plus rapide que les tris précédents, bien que sa
complexité moyenne soit du même ordre.
Cependant, cette fois, tous les cas ne sont pas équivalents. Le pire des cas
correspond à un tableau trié en ordre inverse. Dans ce cas, « insérer la clé à
sa place » coûte Θ(i) avec i la taille du tableau trié à explorer. La complexité
Pn−1
de l’algorithme est alors i=1
i = Θ(n2 ).
Le meilleur des cas est un tableau trié. Dans ce cas, l’insertion de la clé
coûte 1, et la complexité de l’algorithme devient Θ(n).
2
Nous admettrons que sa complexité moyenne est de Θ(n2 ) ( n4 comparaisons).
64
3.5.4
Tri shell
Ce tri, proposé en 1959 par Donald L. Shell, constitue une variante optimisée du tri par insertion.
Remarquons que le principal inconvénient du tri par insertion est le temps
nécessaire pour déplacer une clé d’un côté à l’autre du tableau : il faut n
déplacements d’une case. Cette remarque est à l’origine de l’algorithme du tri
shell.
Avant de trier le tableau, le tri shell va réaliser un pré-tri, c’est-à-dire qu’il
va placer approximativement les éléments à leur place. Ce pré-tri va être réalisé sous la forme de tris par insertion avec différents pas h c’est-à-dire que
chaque élément est décalé de h cases vers la droite (remarquons que pour
h = 1, il s’agit d’un vrai tri par insertion). Un premier pré-tri avec un pas
h grand permet de placer grossièrement les éléments. Ensuite, le pré-tri est
affiné en diminuant la valeur de h. Finalement, un tri avec h = 1 (donc un tri
par insertion) est effectué. Remarquons toutefois que le tri par insertion est
effectué sur un tableau pratiquement trié et qu’il sera donc très efficace.
Le choix de la suite de h est important et conditionne la rapidité du tri.
Exemple de choix :
Considérons la suite u0 = 1; un+1 = 3un + 1. Soit N la taille du tableau à trier.
La suite de pas sera définie par :
– h0 = le plus grand un tel que un < N
hn − 1
– hn+1 =
3
Algorithme 4: Algorithme du tri Shell
Entrées : tab : entier[]
Données : i, j, n, cle,h : entier
n ← taille(tab) ;
h←1;
tant que 3h + 1 < n
# calcul de h0 ;
faire
h ← 3h + 1 ;
fin
tant que h > 0 faire
pour i ∈ [h, n − 1] faire
cle ← tab[i]
# valeur à insérer dans la partie triée ;
j ← i;
tant que j > h et tab[j − h] > cle faire
tab[j] ← tab[j −h]
# décaler l’élément j−h de h crans à
droite ;
j ←j−h ;
fin
tab[j] ← cle
# insérer cle à sa place ;
fin
h ← h/3
# équivalent à (h-1)/3
fin
65
Étude du tri shell
Le tri shell est plus complexe à étudier que les tris vus jusqu’ici. Aussi,
nous nous contenterons de donner les complexités sans les calculer. Pour une
étude complète du tri shell, consulter [Knu73].
La complexité dans le pire des cas du tri shell dépend de la suite hi choisie.
La meilleure suite est inconnue, mais il existe des suites 6 pour lesquelles la
4
3
complexité est de Θ(n 2 ) et d’autres 7 pour lesquelles elle est de Θ(n 3 ).
La complexité en moyenne pour la meilleure suite de h est elle aussi inconnue (car la meilleure suite de h est inconnue). Pour hi = 2i+1 − 1, elle est de
3
O(n 2 ). Pour hi = 2p 3q , elle est de O(n log2 n).
3.5.5
Tri par segmentation, ou Quicksort
Le tri par segmentation est un des tris les plus performants connus pour les
tableaux de grande dimension. Couplé au tri par insertion, il devient le quicksort qui, comme son nom l’indique, est un tri particulièrement rapide et qui
possède l’avantage d’avoir une complexité en espace de Θ(1) (i.e. indépendant
de la taille des données).
L’idée du tri par segmentation est la suivante : étant donné un tableau, on
choisit un élément pivot, puis on place tous les éléments inférieurs au pivot
à gauche et tous les éléments supérieurs à droite. On recommence ensuite
l’opération sur les deux sous-tableaux délimités par l’élément pivot.
1
2
3
4
5
6
7
8
def triseg(tab):
"""Tri par segmentation avec une fonction de partitionnement"""
if tab ==[]:
return []
else:
pivot = tab[0]
lesser, equal, greater =partition(tab[1:], [], [pivot], [])
return triseg(lesser) +equal +triseg(greater)
9
10
11
12
13
14
15
16
17
18
19
def partition(tab, lesser, equal, greater):
while tab !=[]:
head = tab.pop(0)
if head <equal[0]:
lesser.append(head)
elif head >equal[0]:
greater.append(head)
else:
equal.append(head)
return (lesser, equal, greater)
Le quicksort utilise de plus la contrainte suivante : si la taille du sous
tableau est inférieure à un seuil n, on le trie en utilisant un tri par insertion.
Les implantations les plus simples de cet algorithme utilisent la notion de
récursivité vue au paragraphe 3.3.4.
Dans le pire des cas, le quicksort a une complexité de Θ(n2 ). Par contre,
sa complexité moyenne est de Θ(n log n) qui est la meilleure complexité atteignable par un algorithme de tri. De plus, les constantes multiplicatives (qui
6. hi = 2i+1 − 1
i
9.2i − 9.2 2 + 1 si i est pair
7. hi =
i+1
8.2i − 6.2 2 + 1 si i est impair
66
n’apparaissent pas dans l’expression de la complexité) sont très faibles et font
de ce tri l’un des plus performants connus.
3.5.6
Méthode sort des listes de Python
Depuis 2002, Python utilise Timsort, une méthode hybride de tri issue du
tri par fusion et du tri par insertion, développée par Tim Peters [Pet02]. Elle a
un meilleur comportement dans le pire des cas que Quicksort. Contrairement
aux tris des versions précédente, elle garantit un tri stable, c’est-à-dire qu’elle
conserve l’ordre partiel des éléments considérés comme de même rang par
l’opérateur de comparaison.
L’implémentation de Timsort est faite en C, et est compilée dans la machine virtuelle python. Il s’agit alors d’un code adapté à l’architecture de la
machine hôte.
3.5.7
Complexité des algorithmes de tris
Lors de l’étude des différents algorithmes de tris, une question vient naturellement à l’esprit : quel est le meilleur tri existant ? Ou encore : existe-t-il
une complexité minimale pour les algorithmes de tri ? Par meilleur algorithme
de tri, on entend ici algorithme de tri qui minimise le nombre de comparaisons.
Pour simplifier le problème, nous supposerons que toutes les valeurs à trier
sont distinctes. Si l’ensemble contient n éléments, il existe n! permutations
possibles. Comparer les éléments deux à deux revient à les placer dans un
arbre binaire (voir figure 3.1 : les comparaisons effectuées par l’algorithme
sont les nœuds de l’arbre (les cercles), les ordres finaux possibles sont ses
feuilles (les rectangles). Trier un ensemble revient à parcourir l’arbre binaire
jusqu’à une feuille.
Proposition 3.1. La complexité dans le pire des cas d’un algorithme de tri
basé sur des comparaisons ne peut pas être meilleure que Θ(n log n).
1<2
2<3
2<3
1<3
123
132
1<3
312
213
321
231
Figure 3.1 – Comparaisons permettant de trier 3 éléments
Remarquons que cet arbre possède f = n! feuilles (toutes les permutations
possibles). De plus, si l’arbre est de hauteur h, alors
f 6 2h
67
(3.1)
Dans le pire des cas, l’algorithme ne sera capable de conclure qu’après un
nombre de tests égal à la hauteur de l’arbre. Soit c(n) le nombre de comparaisons nécessaires. Étant donné que ce nombre est un entier, on peut réécrire
l’équation 3.1 en :
c(n) > h = dlog2 (n!)e
En utilisant la formule de Stirling, on obtient :
dlog2 (n!)e = n log2 (n) −
n
1
+ log2 (n) + O(1)
ln(2) 2
C’est-à-dire :
c(n) = Θ(n log n)
3.6
Modules
Des nombreuses extensions du langage sont disponibles dans des modules
Python. Pour y accéder :
import module
Pour utiliser une fonction foo définie dans module :
module . foo ()
On peut renommer le module alors qu’on l’importe :
import module as m
m . foo ()
Il est possible d’importer ce qui s’y trouve, et de rendre son usage transparent :
from module import foo
foo ()
On peut aussi tout importer par
from module import *
. . . mais cela peut entraîner des conflits entre modules. Pour utiliser la fonction,
il suffit alors de faire foo().
1
2
import sys, re
from sys import stdin
3
4
5
6
7
8
9
test42 =re.compile(".*42.*")
while True:
s = stdin.readline()
if test42.match(s):
break
print "No 42 in your line"
Un module peut comporter des sous-modules. Ceux-ci sont organisés comme
des sous-répertoires du répertoire courant ou d’un répertoire identifié comme
contenant des modules Python pour la machine virtuelle 8 .
8. Sur un linux, ce répertoire est /usr/lib/python2.7
68
from matplotlib . backends . backend_pdf import PdfPages
# Add some lines here to create a figure
# Save it :
pp = PdfPages ( " .. / img / mpl_basic10 . pdf " )
pp . savefig ()
pp . close ()
3.7
Simulations numériques
Le chapitre 2 a montré comment utiliser Python comme une calculatrice
de haut niveau. Pour de nombreuses simulations numériques, boucles, tests et
définitions de fonction peuvent être nécessaires.
3.7.1
Tirages aléatoires et statistiques
Le module random permet des tirages aléatoires selon une grande variété
de lois. Il est possible de faire coexister plusieurs générateurs pseudo-aléatoires
dans un même programme. On crée un générateur par :
rng = random.Random()
On peut passer un paramètre à Random pour spécifier la graine (seed)
initiale. Par défaut, la graine est initialisée avec l’horloge du système.
random() : tirage aléatoire selon une loi uniforme sur [0, 1].
gauss(m, s) : tirage aléatoire selon une loi normale d’espérance m et de variance s2 .
expovariate(a) : tirage aléatoire selon une loi exponentielle d’espérance 1/a.
randint(a,b) : tirage d’un entier aléatoire entre a et b. Pour la fonction
randint du module random, random.randint(a,b), les bornes sont inclues ; pour numpy.random.randint(a,b) seule la borne a est inclue, b
est exclue.
shuffle(x) : mélange la liste fournie en paramètre.
seed(s) : utilise s comme nouvelle graine. Cela permet de jouer plusieurs fois
la même séquence peudo-aléatoire.
choice(x) : sélectionne un élément de x au hasard (loi équiprobable)
sample(x, k) : sélectionne k éléments de x.
1
2
# -*- coding: utf-8 -*import random
3
4
rng = random.Random()
5
6
7
# Un dé a vingt faces
d20 = rng.randint(1, 20)
8
9
10
11
12
# Somme de trois dés a six faces
dsum3 = 0
for i in range(3):
dsum3 +=rng.randint(1, 6)
13
14
# Somme des trois plus grands dés parmi 4
69
15
16
17
18
19
20
21
dices = [ ]
for i in range(4):
dices.append(rng.randint(1,6))
dices.sort()
dsum34 =0
for d in dices[1:]:
dsum34 +=d
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# Constitution d’un jeu de 52 cartes
values =range(2,11)
values.extend(["V", "D", "R", "A"])
colors =["Ca", "Co", "Pi", "Tr"]
deck = [ ]
for v in values:
for c in colors:
deck.append(str(v)+"_"+c)
# Copier cinq cartes au hasard dans le paquet
# (elles y sont encore pour un autre tirage)
hand1 = rng.sample(deck, 5)
# Melanger le paquet
rng.shuffle(deck)
# Piocher les cinq dernières cartes (elles quittent le paquet)
hand2=[ ]
for i in range(5):
hand2.append(deck.pop())
40
41
42
43
44
45
46
47
48
49
3.7.2
# Faire 1000 tirages selon N(0,1) et compter les valeurs hors de
# l’intervalle de confiance a 95% (on doit avoir n proche de 50)
tab = [ ]
for i in range(1000):
tab.append(rng.gauss(0,1))
n =0
for x in tab:
if abs(x)>1.96:
n+=1
Résolution d’équation(s)
Le module optimize de scipy permet notamment la résolution approchée
d’équations ou de systèmes d’équation.
Le programme suivant permet de résoudre l’équation
x
sin x =
(3.2)
2
par une méthode de Newton avec un point de départ x0 = 2.
1
2
3
import numpy
import scipy
import scipy.optimize
4
5
6
def f(x):
return numpy.sin(x)-x/2
7
8
9
10
start = 2
xsol = scipy.optimize.newton_krylov(f, start, f_tol=1e-14)
print xsol
Le programme suivant cherche un des huit points d’intersections entre les
deux coniques :
(
2
x2 − y 2 − 1
= 0
(3.3)
2
2
2
x − 2 − 2y = 0
70
1
2
3
import numpy
import scipy
import scipy.optimize
4
5
6
7
8
9
10
# f prend en entree une liste de deux elements
def f(xy):
fval = [0, 0]
fval[0] =xy[0]**2 -(xy[1]**2-1)**2
fval[1] =(xy[0]-2)**2 -2*xy[1]
return fval
11
12
13
14
3.7.3
start = [1.8, 2]
xysol = scipy.optimize.newton_krylov(f, start, x_tol=1e-7)
print xysol, " :", f(xysol)
Quadrature numérique
Le module scipy.integrate fournit des fonctions pour la quadrature
numérique ainsi que pour l’intégration numérique des équations différentielles.
La fonction quad(f, a, b) est à pas adaptatif, et fournit un résultat
sous
Rb
forme de tuple, dont le premier élément est une approximation de a f (x)dx
où a ou b peuvent être infinis. Le second élément est une estimation de l’erreur
absolue commise.
1
2
3
4
import
import
import
import
numpy as np
scipy as sp
scipy.integrate as integ
math as m
5
6
7
def fN(x):
return 1/(m.sqrt(2*m.pi))*m.exp(-0.5*x**2)
8
9
10
11
print "De -100 a 1.96: ", integ.quad(fN,-100,1.96)
y, err =integ.quad(fN,-np.inf,1.96)
print "De -oo a 1.96: %.12f plus ou moins %.2e"%(y, err)
12
13
14
15
16
17
18
tabx = np.arange(-100,1.96001,0.01)
taby = np.zeros(len(tabx))
for i in range(len(tabx)):
taby[i] = fN(tabx[i])
print "De -100 a 1.96 par les trapezes avec un pas de 1/100: ",
print integ.trapz(taby, tabx)
Résultat :
De -100 a 1.96: (0.9750021048517795, 4.2103849945256025e-11)
De -oo a 1.96: 0.975002104852 plus ou moins 3.62e-09
De -100 a 1.96 par les trapezes avec un pas de 1/100: 0.975001150321
Rb
La fonction trapz(y,x) calcule une approximation de a f (x)dx par la
méthode des trapèzes en se basant sur les vecteurs x et y. Elle sera à pas
constant si les points de x suivent une telle répartition, par exemple générée
par numpy.arange().
3.7.4
Intégration numérique des ODE
La fonction odeint permet l’intégration numérique d’une équation différentielle ou d’un système d’équations différentielles du premier ordre. Elle
71
utilise la bibliothèque odepack, écrite en Fortran, qui implémente une méthode adaptative : les points effectivement calculés par la méthode ne sont pas
seulement les points demandés pour la sortie.
L’équation du pendule est :
∂2θ
g
= − sin θ
2
∂t
`
(3.4)
On la passe au premier ordre en introduisant une variable u(t) =
!
∂ θ
∂t u
=
u
g
− ` sin θ
∂θ
∂t
:
!
(3.5)
On obtient ainsi la fonction de R2 dans R2 qui est la dynamique (ou
équation d’état) du système.
1
2
3
import numpy as np
from scipy.integrate import odeint
from pylab import *
4
5
6
7
def dyn(x, t, ell, g):
(th, u) =x
return (u, -g/ell*np.sin(th))
8
9
10
x0=(3*np.pi/4, 0)
t = np.arange(0, 10, 0.01)
11
12
x = odeint(dyn, x0, t, args=(1, 9.81))
13
14
plot(t, x[:,0], color="blue", linewidth=2.5, linestyle="-")
15
16
17
18
19
20
21
22
ax = gca()
ax.spines[’right’].set_color(’none’)
ax.spines[’top’].set_color(’none’)
ax.xaxis.set_ticks_position(’bottom’)
ax.spines[’bottom’].set_position((’data’,0))
ax.yaxis.set_ticks_position(’left’)
ax.spines[’left’].set_position((’data’,0))
23
24
25
xlim(0, 10.3)
xticks(range(0, 11))
26
27
28
29
ylim(x[:,0].min()*1.1, x[:,0].max()*1.1)
yticks(arange(-np.pi, np.pi+1e-12, np.pi/4),
[r’$\frac{%i}{4}\pi$’%(i) for i in range(-4,5)])
30
31
32
#savefig("odeint.png",dpi=200)
show()
La fonction odeint() demande au moins trois paramètres : la dynamique
de l’équation différentielle, qui doit être une fonction (dyn dans l’exemple
précédent), le vecteur d’état à l’instant initial (x0 dans l’exemple précédent),
et les instants pour lesquels on souhaite calculer le vecteur d’état (t dans
l’exemple précédent).
Ici, la dynamique demande deux paramètres supplémentaires, que l’on
passe via le paramètre args de odeint. Si l’on dispose du jacobien de la dynamique sous forme de fonction, on peut le fournir à odeint par le paramètre
Dfun, ce qui peut améliorer et/ou accélérer le schéma numérique.
72
Figure 3.2 – Tracé de θ en fonction du temps
73
4
Bibliothèques de haut niveau
Sommaire
4.1
4.2
4.3
Gestion du temps par time
Utilisation des fichiers en mode texte
PIL : traitement d’image
4.3.1 Fichier image
4.3.2 Transformations
4.3.3 Exemple de manipulations
4.3.4 Lien avec d’autres objets Python
4.4 Sympy
4.4.1 Notion de symbole
4.4.2 Fractions
4.4.3 Limites
4.4.4 Dérivation
4.4.5 Développements limités
4.4.6 Séries
4.4.7 Intégration
4.4.8 Équations différentielles
4.4.9 Équations algébriques
4.4.10 Algèbre matricielle
74
74
75
75
76
79
81
82
82
83
84
84
85
85
85
86
86
86
D
e nombreuses fonctionnalités de haut niveau ont été développées en
Python, ce qui permet d’obtenir des programmes très puissants en
peu de lignes.
4.1
Gestion du temps par time
Le package time permet de gérer le temps.
time() : renvoie le nombre de secondes depuis le 1er janvier 1970, sous forme
d’un float.
sleep(sec) : met le processus en pause. Le paramètre sec est le temps de
pause exprimé en secondes ; ce peut être un nombre à virgule flottante.
4.2
Utilisation des fichiers en mode texte
On crée un objet fichier Python avec la fonction open() :
>>> MonFichier = open ( " NomDuFichier " , ’r ’)
74
Le mode peut être ’r’ (read, en lecture seule), ’w’ (en écriture seule), ’a’
pour rajouter à la fin du fichier, . . . . D’autres modes (mixte lexture/écriture,
etc...) existent. La lecture des fichiers texte (i.e. non binaires) se fait avec les
fonctions read(), readline() et readlines() :
>>> MonFichier . read () # lit la totalit é du fichier sous forme d ’
une cha î ne de caract è res
>>> MonFichier . readline () # lit la ligne suivante du fichier ,
sous forme d ’ une cha î ne de
caract è res
>>> MonFichier . readlines () # lit toutes les lignes du fichier
sous forme d ’ une liste de cha î
nes de caract è res
>>> Monfichier . write ( ’ toto ’) # é crit la cha î ne de caract è re ’ toto
’ dans le fichier
Pour lire une liste de nombres contenu dans une ligne, il suffit de lire cette
ligne avec la fonction readline(), puis de séparer les nombres avec la méthode
split() de str. Par exemple :
>>> f = open ( " tmp0 " , ’r ’)
>>> ligne = f . readline () # lecture d ’ une ligne
>>> print ligne # É criture de la ligne sous forme d ’ une cha î ne de
caract è res
Toto 1 . 8 9 . 2
>>> print ligne . split () # On s é pare les é l é ments - > liste
[ ’ Toto ’ , ’0 . 2 ’ , ’9 . 2 ’]
>>> print float ( ligne . split () [ 1 ] ) # Conversion en nombre r é el de
’0 . 2 ’
>>> f . close () # referme le fichier
La commande help(file) permet de lister l’aide sur l’utilisation des fichiers.
4.3
PIL : traitement d’image
Il existe beaucoup de possibilités pour réaliser du traitement d’image sous
Python. Par exemple, sous MatPlotLib certaines fonctionnalités 1 permettent
de traiter les images. Il existe aussi des bibliothèques dédiées au traitement
d’image de niveau professionnel avec lesquelles on peut travailler sous Python
(par exemple OpenCV 2 . L’avantage principal de la bibliothèque PIL est la
simplicité de mise œuvre.
Cette section est fortement inspirée d’un tutoriel réalisé par Jean-Louis
Bicquelet-Salaün [BS09].
4.3.1
Fichier image
Pour accéder au fichier image et pour connaître certaines informations sur
l’image :
1
# -*- coding: utf-8 -*-
2
3
from PIL import Image
4
5
filename =’../img/pil_colibri.jpeg’
6
1. matplotlib.org/users/image_tutorial.html
2. www.neuroforge.co.uk/index.php/getting-started-with-python-a-opencvl
75
7
8
im = Image.open(filename)
print file, im.format, "%dx%d" % (im.size), (im.mode)
On peut signaler que la classe image de la bibliothèque PIL est un descendant de la classe file. À l’exécution, nous obtenons :
.. / img / pil_colibri . jpeg JPEG 400x398 RGB
Pour visualiser l’image :
1
2
3
# -*- coding: utf-8 -*from PIL import Image
import ImageFilter
4
5
6
filename =’../img/pil_colibri.jpeg’
im = Image.open(filename)
7
8
im.show()
Cette image fait partie de l’exposition IMAGINARY organisée par l’institut Mathematisches Forschungsinstitut Oberwolfach.
4.3.2
Transformations
Décomposition en 3 composantes
On décompose l’image en trois images différentes correspondant aux trois
composantes (rouge, vert, bleu) de l’image originale :
1
# -*- coding: utf-8 -*-
2
3
4
5
6
7
8
9
import Image
img = Image.open("../img/pil_colibri.jpeg") # Ouverture de l’image
r,g,b = img.split() # Récupération des différentes composantes de l’image
# Sauvegarde des images des différentes composantes
r.save(’../img/pil_colibri_r.jpg’)
g.save(’../img/pil_colibri_v.jpg’)
b.save(’../img/pil_colibri_b.jpg’)
Convertion du format
Avec PIL, il est possible de convertir une image sous les trois formats :
PNG, JPEG, BMP.
1
2
3
# -*- coding: utf-8 -*from PIL import Image
img = Image.open("../img/pil_colibri.jpeg") # Ouverture de l’image
76
Figure 4.1 – Niveaux de rouge, vert et bleu de l’image originale.
4
5
6
img.save("../img/pil_colibri.png", "PNG")
img.save("../img/pil_colibri.bmp", "BMP")
Image miniature
Pour créer une miniature à partir de l’image originale :
1
2
# -*- coding: utf-8 -*from PIL import Image
3
4
5
6
7
size=128,128
im = Image.open(’../img/pil_colibri.jpeg’)
im.thumbnail(size, Image.ANTIALIAS)
im.save(’../img/pil_colibri_small.png’, "PNG")
Pour réaliser cette opération sur tout un répertoire :
1
2
3
# -*- coding: utf-8 -*from PIL import Image
import glob, os
4
5
size = 128, 128
6
7
8
9
10
11
for infile in glob.glob("*.png"):
filename, ext =os.path.splitext(infile)
im = Image.open(infile)
im.thumbnail(size, Image.ANTIALIAS)
im.save(filename +"_small.png", "PNG")
Transformation isométrique
On peut réaliser une rotation à l’aide de la fonction rotate() :
1
2
# -*- coding: utf-8 -*from PIL import Image
3
4
im = Image.open(’../img/pil_colibri.jpeg’)
77
5
6
out = im.rotate(45)
out.save(’../img/pil_colibri_rot45.png’)
Il est possible de réaliser d’autres transformations en utilisant transpose()
et en utilisant des mots clé comme : FLIP_LEFT_RIGHT, FLIP_TOP_BOTTOM,
ROTATE_90, ROTATE_180, ROTATE_270,...
1
2
# -*- coding: utf-8 -*from PIL import Image
3
4
5
6
im = Image.open(’../img/pil_colibri.jpeg’)
out = im.transpose(Image.FLIP_LEFT_RIGHT)
out.save(’../img/pil_colibri_flipLR.png’)
Redimensionnement
Pour redimensionner une image, on utilise resize() :
1
2
# -*- coding: utf-8 -*from PIL import Image
3
4
5
6
im = Image.open(’../img/pil_colibri.jpeg’)
out = im.resize((100,200))
out.save(’../img/pil_colibri_resize.png’)
Filtrage
Le filtrage d’une image se réalise à l’aide de la fonction filter() et le module ImageFilter qui propose de nombreux filtres (filtres min, max, médian,
flou, . . . 3 ).
3. http://www.pythonware.com/library/pil/handbook/imagefilter.htm
78
# -*- coding: utf-8 -*from PIL import Image
import ImageFilter
1
2
3
4
im = Image.open(’../img/pil_colibri.jpeg’)
out = im.filter(ImageFilter.BLUR)
out.save(’../img/pil_colibri_blur.png’, "PNG")
out2 = im.filter(ImageFilter.MinFilter)
out2.save(’../img/pil_colibri_min.png’, "PNG")
out3 = im.filter(ImageFilter.MedianFilter)
out3.save(’../img/pil_colibri_median.png’, "PNG")
5
6
7
8
9
10
11
Figure 4.2 – Image originale (gauche) et filtrée par blur (droite).
4.3.3
Exemple de manipulations
Concaténation d’images
Pour concaténer une image avec son symétrique :
1
2
# -*- coding: utf-8 -*from PIL import Image
3
4
5
6
7
8
9
10
11
12
im = Image.open(’../img/pil_colibri.jpeg’)
w,h=im.size
box = (0, 0, w, h)
src = im.crop(box)
out = im.resize((w*2,h))
out.paste(src,(0,0,w,h))
src=im.transpose(Image.FLIP_LEFT_RIGHT)
out.paste(src,(w,0,2*w,h))
out.save(’../img/pil_colibri_plussym.png’)
79
Dessiner sur une image
1
2
3
# -*- coding: utf-8 -*from PIL import Image
import ImageDraw
4
5
6
7
8
9
10
11
12
13
im = Image.new("RGB", (400,200), "lightgrey")
draw = ImageDraw.Draw(im)
w,h=im.size
draw.ellipse((w/4,h/4) +(3*w/4,3*h/4), fill="green")
draw.line((0, 0) +im.size, width=10,fill="red")
offsetx=100
draw.rectangle(((100+offsetx,100),(130+offsetx,200)),fill="gray")
del draw
im.save("../img/pil_dessin.png", "PNG")
Image multiple
1
2
3
# -*- coding: utf-8 -*from PIL import Image
import ImageDraw
4
5
6
im = Image.new("RGB", (500,400), "white")
draw = ImageDraw.Draw(im)
80
7
8
9
10
11
12
13
4.3.4
1
2
3
4
into = Image.open("../img/pil_colibri_small.png")
w,h=into.size
im.paste(into, (0,0,w,h))
im.paste(into, (300,0,300+w,h))
im.paste(into, (200,200,200+w,200+h))
del draw
im.save("../img/pil_multiple.png")
Lien avec d’autres objets Python
# -*- coding: utf-8 -*from PIL import Image
import ImageFilter
import numpy as np
5
6
7
filename =’../img/pil_colibri.jpeg’
im = Image.open(filename)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# ag recoit les pixels de l’image im en niveaux de gris
ag = np.zeros((im.size[1], im.size[0]))
i =0
j =0
for x in im.getdata():
ag[j, i] =0.21*x[0]+0.72*x[1]+0.07*x[2]
i += 1
if i == im.size[0]: # Passage a la ligne suivante
i =0
j += 1
ig = Image.fromarray(ag) # Conversion du tableau ag en Image
ig.show()
ig.convert(’RGB’).save(’../img/pil_colibri_gray.png’)
22
23
24
25
26
27
28
29
30
31
32
33
# On arrondit le niveau de gris a 16 pres
ag = 16*np.round(ag/16)
# On ajoute des lignes blanches verticales
for i in range(0,im.size[0], 16):
ag[:,i] =255
# On ajoute des lignes noires horizontales
for j in range(0,im.size[1], 16):
ag[j,:] =0
it = Image.fromarray(ag)
it.show()
it.convert(’RGB’).save(’../img/pil_colibri_gray_16.png’,’png’)
Figure 4.3 – Deux images traitées via numpy
81
La méthode getdata() permet de récupérer le contenu de l’image, sous
forme d’un itérateur sur les pixels de l’image. Elle permet de réécrire simplement les pixels dans une liste ou un tableau.
La fonction fromarray permet de transformer un tableau, notamment un
tableau numpy en Image. Un passage par la méthode convert peut être nécessaire pour garantir le format interne de l’image avant écriture.
4.4
Sympy
La bibliothèque Sympy ouvre au langage Python la possibilité de réaliser
du calcul mathématique symbolique. Il est important de souligner que cette
bibliothèque fait actuellement l’objet d’une activité très importante de développement et qu’il est sans doute à attendre dans un avenir proche des améliorations significatives. D’ores et déjà, Sympy offre un nombre important de
fonctionnalités qui le rapproche de logiciels classiques du calcul symbolique
comme Mapple ou Mathematica.
Cette section reprend des extraits du tutoriel de Sympy qui peut être lancé
de façon interactive sur le site : docs.sympy.org/0.7.2/tutorial.html.
Voici un premier exemple simple d’application au calcul fractionnel :
>>> from sympy import Rational
>>> a = Rational (1 , 2 )
>>> a
1/2
>>> a * 2
1
>>> Rational ( 2 ) ** 50 / Rational ( 10 ) ** 50
1/ 88817841970012523233890533447265625
On peut également écrire :
>>> R = Rational
>>> R (1 , 2 )
1/2
>>> R ( 1 ) / 2 # R ( 1 ) est SymPy Integer et Integer / int donne un
Rational
1/2
Sympy permet aussi l’utilisation d’éléments mathématiques comme π, e ou
∞:
>>> from sympy import pi , E
>>> pi ** 2
pi ** 2
>>> pi . evalf ()
3 . 14159265358979
>>> ( pi + E ) . evalf ()
5 . 85987448204884
>>> from sympy import oo
>>> oo > 99999
True
>>> oo + 1
oo
4.4.1
Notion de symbole
Avec Sympy, si l’on souhaite travailler avec des variables symboliques
comme x, y, z, r, θ, φ etc, il est nécessaire de les déclarer explicitement :
82
>>> from sympy import Symbol
>>> x = Symbol ( ’x ’)
>>> y = Symbol ( ’y ’)
Certains symboles sont déjà prédéfinis dans la sous-bibliothèque abc :
>>> from sympy . abc import x , theta
>>> x
x
>>> theta
theta
Pour créer des symboles, on peut également utiliser la fonction var() :
>>> from sympy import symbols , var
>>> a , b , c = symbols ( ’a ,b , c ’)
>>> d , e , f = symbols ( ’d : f ’)
>>> var ( ’g : h ’)
(g , h )
>>> var ( ’g : 2 ’)
( g0 , g1 )
Voici quelques opérations simples :
>>> x + y + x - y
2*x
>>> ( x + y ) ** 2
( x + y ) ** 2
>>> (( x + y ) ** 2 ) . expand ()
x ** 2 + 2 * x * y + y ** 2
Lors d’opérations, il est possible de faire prendre à une variable une valeur
numérique ou encore la remplacer par une autre expression en utilisant subs() :
>>> (( x + y ) ** 2 ) . subs (x , 1 )
( y + 1 ) ** 2
>>> (( x + y ) ** 2 ) . subs (x , y )
4 * y ** 2
>>> (( x + y ) ** 2 ) . subs (x , 1 - y )
1
Pour améliorer la présentation, on lancera :
>>> from sympy import init_printing
>>> init_printing ( use_unicode = True , wrap_line = False , no_global =
True )
4.4.2
Fractions
Développement de fraction :
>>> from sympy import apart
>>> from sympy . abc import x , y , z
>>> 1 / ( ( x + 2 ) * ( x + 1 ) )
1
--------------(x + 1)*(x + 2)
>>> apart ( 1 / ( ( x + 2 ) * ( x + 1 ) ) , x )
1
1
- ----- + ----x + 2
x + 1
>>> ( x + 1 ) / ( x - 1 )
83
x + 1
----x - 1
>>> apart ( 1 / ( ( x + 2 ) * ( x + 1 ) ) , x )
1
1
- ----- + ----x + 2
x + 1
Mise sous dénominateur commun :
>>> from sympy import together
>>> together ( 1 / x + 1 / y + 1 / z )
x*y + x*z + y*z
--------------x*y*z
>>> together ( apart (( x + 1 ) / ( x - 1 ) , x ) , x )
x + 1
----x - 1
>>> together ( apart ( 1 / ( ( x + 2 ) * ( x + 1 ) ) , x ) , x )
1
--------------(x + 1)*(x + 2)
4.4.3
Limites
La fonction limit(function, variable, point) permet de calculer la
limite d’une fonction définie par son expression symbolique :
>>>
>>>
>>>
1
>>>
oo
>>>
0
>>>
1
from sympy import limit , Symbol , sin , oo
x = Symbol ( " x " )
limit ( sin ( x ) /x , x , 0 )
limit (x , x , oo )
limit ( 1 /x , x , oo )
limit ( x ** x , x , 0 )
4.4.4
Dérivation
Le calcul des dérivées s’effectue à l’aide de la fonction diff(func, var) :
>>> from sympy import diff , Symbol , sin , tan
>>> x = Symbol ( ’x ’)
>>> diff ( sin ( x ) , x )
cos ( x )
>>> diff ( sin ( 2 * x ) , x )
2 * cos ( 2 * x )
>>> diff ( tan ( x ) , x )
2
tan ( x ) + 1
Dérivation d’ordre supérieur :
>>> diff ( sin ( 2 * x ) , x , 1 )
2 * cos ( 2 * x )
>>> diff ( sin ( 2 * x ) , x , 2 )
- 4 * sin ( 2 * x )
>>> diff ( sin ( 2 * x ) , x , 3 )
84
- 8 * cos ( 2 * x )
4.4.5
Développements limités
Voici un exemple :
>>> from sympy import Symbol , cos
>>> x = Symbol ( ’x ’)
>>> cos ( x ) . series (x , 0 , 10 )
2
4
6
8
x
x
x
x
1 - - - + - - - - - - + - - - - - + O ( x ** 10 )
2
24
720
40320
>>> ( 1 / cos ( x ) ) . series (x , 0 , 10 )
2
4
6
8
x
5*x
61 * x
277 * x
1 + - - + - - - - + - - - - - + - - - - - - + O ( x ** 10 )
2
24
720
8064
>>> y = Symbol ( " y " )
>>> e = 1 / ( x + y )
>>> s = e . series (x , 0 , 5 )
>>> print ( s )
1 / y - x / y ** 2 + x ** 2 / y ** 3 - x ** 3 / y ** 4 + x ** 4 / y ** 5 + O ( x ** 5 )
4.4.6
Séries
>>> from sympy import summation , oo , symbols , log
>>> i , n , m = symbols ( ’i n m ’ , integer = True )
>>> summation ( 2 * i - 1 , (i , 1 , n ) )
n ** 2
>>> summation ( 1 / 2 ** i , (i , 0 , oo ) )
2
>>> summation ( 1 / log ( n ) ** n , (n , 2 , oo ) )
Sum ( log ( n ) ** ( - n ) , (n , 2 , oo ) )
>>> summation (i , (i , 0 , n ) , (n , 0 , m ) )
m ** 3 / 6 + m ** 2 / 2 + m / 3
>>> from sympy . abc import x
>>> from sympy import factorial
>>> summation ( x ** n / factorial ( n ) , (n , 0 , oo ) )
exp ( x )
4.4.7
Intégration
Pour le calcul de primitive :
>>> from sympy import integrate , erf , exp , sin , log , oo , pi , sinh
, symbols
>>> x , y = symbols ( ’x , y ’)
>>> integrate ( 6 * x ** 5 , x )
x ** 6
>>> integrate ( sin ( x ) , x )
- cos ( x )
>>> integrate ( exp ( - x ** 2 ) * erf ( x ) , x )
pi ** ( 1 / 2 ) * erf ( x ) ** 2 / 4
Pour le calcul d’intégrales définies ou impropres :
85
>>>
0
>>>
1
>>>
1
>>>
-1
integrate ( x ** 3 , (x , -1 , 1 ) )
integrate ( sin ( x ) , (x , 0 , pi / 2 ) )
integrate ( exp ( - x ) , (x , 0 , oo ) )
integrate ( log ( x ) , (x , 0 , 1 ) )
4.4.8
Équations différentielles
>>> from sympy import Function , Symbol , dsolve
>>> f = Function ( ’f ’)
>>> x = Symbol ( ’x ’)
>>> f ( x ) . diff (x , x ) + f ( x )
f ( x ) + Derivative ( f ( x ) , x , x )
>>> dsolve ( f ( x ) . diff (x , x ) + f ( x ) , f ( x ) )
f ( x ) = = C1 * cos ( x ) + C2 * sin ( x )
4.4.9
>>>
>>>
>>>
[1 ,
>>>
{x:
Équations algébriques
from sympy import solve , symbols
x , y = symbols ( ’x , y ’)
solve ( x ** 4 - 1 , x )
-1 , -I , I ]
solve ( [ x + 5 * y - 2 , - 3 * x + 6 * y - 15 ] , [x , y ] )
-3 , y : 1 }
4.4.10
Algèbre matricielle
>>> from sympy import Matrix , Symbol
>>> Matrix ( [ [1 , 0 ] , [0 , 1 ] ] )
[1 , 0 ]
[0 , 1 ]
>>> x = Symbol ( ’x ’)
>>> y = Symbol ( ’y ’)
>>> A = Matrix ( [ [1 , x ] , [y , 1 ] ] )
>>> A
[1 , x ]
[y , 1 ]
>>> A ** 2
[x*y + 1,
2*x]
[
2 *y , x * y + 1 ]
86
5
Langage objet
Sommaire
5.1
5.2
5.3
5.4
5.5
5.6
5.7
5.8
Variables d’instance
Méthodes
Constructeur
5.3.1 Transtypage
Destructeur : ramasse-miette
Surcharge d’opérateur
Documention et interrogation
5.6.1 Conventions de nommage
Héritage
5.7.1 Appartenance à une classe
Exemple : géométrie par les objets
88
88
88
89
89
90
90
91
91
91
92
P
ython est un langage objet, et tous les types vus précédemment sont
des types objet. Il est possible d’en définir d’autres, que ce soit comme
descendant de types existant ou de façon autonome, et de les utiliser
aussi simplement.
Une classe est un type objet. Un objet est une variable de ce type ; on
dira aussi qu’un objet est une instance de la classe. Un objet regroupe des
variables d’instance dont les valeurs définissent l’état de l’objet, et des méthodes permettant d’agir sur ces variables d’instance, aussi bien en lecture qu’en
écriture.
Une classe se définit par le mot-clef class. Le constructeur est une fonction
particulère qui s’appelle toujours __init__(). L’héritage se fait par class
MyClass(Class1, Class2, ...).
1
2
3
4
5
6
7
8
class Complex:
def __init__(self, x_init, y_init):
self.x =x_init
self.y =y_init
def module(self):
return (self.x**2+self.y**2)**0.5
z = Complex(3,4)
print z.module()
87
5.1
Variables d’instance
Les variables d’instances sont attachées à chaque instance de la classe. Elles
caractérisent l’objet, et portent toute son information.
Dans l’exemple précédent, les deux variables d’instance d’un objet de type
Complex sont x et y. Il n’est pas nécessaire d’en spécifier le type ; comme toute
variable en Python, elles reçoivent ou modifient leur type lors des opérations
d’affectation.
On peut accéder aux variables d’instance x et y d’un objet z par z.x et
z.y, en écriture comme en lecture.
5.2
Méthodes
Une méthode est une fonction particulière, attachée à une classe. Le premier paramètre d’une méthode est toujours self. Si obj est un objet de
la classe définissant la méthode foo, il est équivalent d’appeler la méthode
foo(self, x) par obj.foo(x) ou foo(obj, x).
La notation obj.foo(x) est celle de la programmation objet : on demande
à l’objet obj d’utiliser son service foo.
5.3
Constructeur
On crée un objet de classe MaClasse par :
mon_objet = MaClasse ( p1 , p2 )
Les paramètres p1 et p2 sont passés au constructeur de MaClasse, et servent à initialiser les variables d’instance de mon_objet.
Le constructeur est une méthode particulière, qui est appelée juste après la
réservation de l’espace mémoire pour l’objet. Il s’appelle toujours __init__().
Son premier paramètre est l’objet en cours de création, et les paramètres suivants servent à l’initialiser.
À l’issue de l’exécution du constructeur, toutes les variables d’instance
doivent avoir reçu une valeur.
Comme pour les fonctions (section 3.3), les paramètres du constructeur
peuvent recevoir des valeurs par défaut.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Complex:
def __init__(self, x_init, y_init=0):
""" builder; give values to instance variables x et y. """
self.x =x_init
self.y =y_init
def module(self):
""" returns the absolute value of the Complex. """
return (self.x**2+self.y**2)**0.5
def set_module(self, r):
""" modifies the absolute value but keeps the argument. """
r_act = self.module()
self.x *=r/r_act
self.y *=r/r_act
z1 = Complex(3, 4)
z1.set_module(10)
print "z1 :", z1.x, z1.y
z2 = Complex(-3)
z2.set_module(10)
88
19
5.3.1
print "z2 :", z2.x, z2.y
Transtypage
En section 3.4.2, nous avons vu un programme récupérant les arguments
de la ligne de commande pour en faire la somme.
1
import sys
2
3
4
5
6
s =0
for x in sys.argv[1:]:
s += float(x)
print "Total :",s
En ligne 5, on effectue un transtypage de x vers un type float.
En pratique, on appelle le constructeur de float avec un paramètre de type
str, et ce constructeur fournit une nouvelle instance de float dont la valeur
numérique est construite en analysant le contenu de la chaîne de caractères x.
Si la conversion n’est pas possible, c’est-à-dire dire si la valeur ou le type
des paramètres fournis ne conviennent pas, une exception est levée :
>>> float ( " quarante - deux " )
ValueError : could not convert string to float : quarante - deux
>>> float ( [ 42 ] )
TypeError : float () argument must be a string or a number
5.4
Destructeur : ramasse-miette
En Python, lorsqu’un objet n’est plus utile, il n’est pas nécessaire de le
détruire explicitement 1 . Chaque objet dispose d’un compteur de référence,
qui détermine le nombre de fois que la zone mémoire occupée par l’objet est
référencée par le programme. Ce peut être directement par une variable du
programme, par une variable locale d’une fonction en cours d’exécution, ou
par une variable d’insance d’un autre objet. Si ce compteur de référence tombe
à 0, la zone mémoire utilisée par l’objet ne pourra plus jamais être référencée.
Un ramasse-miettes (un objet de type garbage collector attaché à chaque
programme) est chargé de désallouer la mémoire des objets dont le compteur
de références tombe à 0.
Un cycle de référence survient si A a une variable d’instance dont la valeur
est B, et B a une variable d’instance dont la valeur est A. Lorsque ni A ni B
ne sont plus référencés par le programme, chaque objet a un compteur de
références de 1, mais aucun n’est accessible, et leur espace mémoire doit être
désalloué. Si un objet C se référence lui-même, l’effet est le même. Si le ramassemiette utilise uniquement le mécanisme de comptage de références, ces zones
mémoires sont à la fois inutiles et allouées : c’est une fuite de mémoire, et donc
une perte de mémoire disponible.
Depuis la version 2.0 de Python, le ramasse-miettes est également capable
de détecter les cycles de références. Cette fonctionnalité est cependant assez
lourde – algorithmiquement – et n’est lancée que de temps en temps, ou lorsque
certains seuils de quantité d’objets actifs dans le programme sont atteints.
1. En C++; il faut détruire explicitement un objet par un appel à son destructeur pour
que la mémoire qu’il occupe soit à nouveau disponible.
89
5.5
Surcharge d’opérateur
Les opérateurs sont des méthodes de leurs opérandes. Il est possible de les
surcharger quand on définit un nouvel objet.
• str(x) : x.__str__(),
• repr(x) : x.__repr__()
• a+b : a.__add__(b), b.__radd__(a)
• a-b : a.__sub__(b), b.__rsub__(a)
• * : a.__mul__(b), b.__rmul__(a)
• size(x) : x.__sizeof__(),
• <,>, <=,>=,==,!= : analyser le résultat de a.__cmp__(b)
. . . et quantité d’autres : faire dir(obj) pour voir toutes les méthodes attachées à un objet.
1
2
3
4
5
6
7
8
9
10
11
12
13
class Complex:
""" Defines a new complex type """
def __init__(self, x_init, y_init):
self.x =x_init
self.y =y_init
def __add__(self, z):
""" Addition in C """
return Complex(self.x+z.x, self.y+z.y)
def __str__(self):
return str(self.x)+"+"+str(self.y)+"i"
z = Complex(3,4)
z2 = Complex(-2,-2)
print z+z2
L’exécution de ce code conduit à :
1 + 2i
5.6
Documention et interrogation
Les textes entre triple guillemets """ ... """ définissent la documentation. Ainsi help(z) ainsi que help(Complex) donnent :
Help on instance of Complex in module cmplx:
class Complex
| Defines a new complex type
|
| Methods defined here:
|
| __add__(self, z)
|
Addition in C
|
| __init__(self, x_init, y_init)
|
| __str__(self)
On peut demander la documentation de tout objet, y compris une méthode.
Ainsi help(z.__add__) donne :
90
Help on method __add__ in module cmplx:
__add__(self, z) method of cmplx.Complex instance
Addition in C
L’opérateur dir() renseigne sur tous les attributs d’un objet, aussi bien
ses méthodes que ses variables d’instance. Si z est un objet de classe Complex,
dir(z) donne :
[ ’ __add__ ’ , ’ __doc__ ’ , ’ __init__ ’ , ’ __module__ ’ , ’ __str__ ’ , ’x ’ ,
’y ’]
Dans cette liste, ’x’ et ’y’ sont les noms des variables d’instance de z,
’__init__’ est son constructeur, et ’__add__’ et ’__str__’ sont des méthodes surchargées.
La variable ’__module__’ renseigne sur le module dans lequel est défini
l’objet z. Si le programme est lancé directement depuis la console, elle vaudra
’__main__’. Si le programme est placé dans un module cmplx.py que l’on
importe par import cmplx, elle vaudra ’cmplx’.
La variable __doc__ contient le texte affiché par la commande help(z).
Note : la classe complex (cf. section 2.1.1) fonctionne très bien ; il n’est
pas nécessaire d’en définir une nouvelle.
5.6.1
Conventions de nommage
Il est d’usage de réserver les doubles _ pour les méthodes liées à un opérateur, comme ’__init__’, ’__str__’ ou ’__add__’.
Les variables d’instances ou les méthodes auront un nom commençant par
_, comme par exemple _x ou _flag, si elles sont privées. Cela signifie qu’on
conseille aux programmes utilisant la classe de ne pas utiliser directement ces
variables ou méthodes.
Les variables d’instances ou les méthodes publiques auront un nom commençant par une lettre minuscule.
5.7
Héritage
Il est possible de créer un nouveau type objet en le faisant hériter d’un
type existant (ou de plusieurs type existants : on parle alors d’héritage multiple). Toutes les méthodes du type parent sont disponibles, mais il est possible
de les surcharger pour modifier leur comportement. Il convient d’invoquer le
constructeur du type parent __init__() avant de réaliser les opérations d’initialisation du type descendant.
5.7.1
Appartenance à une classe
La fonction isinstance(objet, classe) renvoie True si objet est de
classe classe ou d’un descendant de classe
Elle permet notamment de tester le type des paramètres reçus par une
fonction.
On peut aussi demander son type à un objet par l’opérateur type().
91
>>> grg = { " Earth " : " harmless " }
>>> type ( grg )
< type ’ dict ’>
5.8
Exemple : géométrie par les objets
La classe Point définit un point par deux variables d’instances, x et y.
Elle surcharge les opérateurs +, - et * pour donner à un Point les propriétés
d’un élément d’un espace vectoriel 2 . La méthode dist calcule la distance
euclidienne entre deux Points. Il n’y a pas de produit scalaire ni de produit
vectoriel : il est calculé de manière manuelle dans les méthodes de Triangle
qui en ont besoin.
La classe Figure fournit le squelette de description d’une figure géométrique,
et lui impose d’avoir un centre et une surface. Toutefois, cette classe générique
n’effectue pas les calculs correspondants : ils sont confiés aux trois sous-classes,
Circle, Koch et Triangle.
Plusieurs paramètres sont testés, que ce soit par isinstance() ou en vérifiant que les conversions se passent bien dans un bloc try: . . . except:. En
cas de problème, une exception est levée, ce qui met fin à l’exécution du programme si elle n’est pas traitée dans le cadre d’un bloc try: . . . except:
englobant.
1
2
3
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Point:
""" Class Point :implements addition, substraction, and
multiplication with a scalar
"""
def __init__(self, init_x, init_y):
self.x =float(init_x)
self.y =float(init_y)
def __str__(self):
return ’(%f, %f)’%(self.x, self.y)
def __sub__(self, p):
if not isinstance(p, Point):
raise TypeError(’Target should be a Point’)
else:
return Point(self.x -p.x, self.y -p.y)
def __add__(self, p):
if not isinstance(p, Point):
raise TypeError(’Operand should be a Point’)
else:
return Point(self.x +p.x, self.y +p.y)
def __rmul__(self, v):
""" use by ’v *p’ where p is a Point and v a scalar """
try:
mult = float(v)
return Point(mult*self.x, mult*self.y)
except:
raise TypeError(’Bad multiplier’)
def dist2(self, p):
""" make use of p1.dist2(p2) instead of (p1.dist(p2))**2 """
2. Encore que l’opérateur - se définisse plus sainement comme associant un élément d’un
espace vectoriel à deux éléments d’un espace affine.
92
31
32
33
34
35
36
if not isinstance(p, Point):
raise TypeError(’Target should be a Point’)
else:
return (self.x-p.x)**2 +(self.y-p.y)**2
def dist(self, p):
return self.dist2(p)**0.5
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class Figure():
def __init__(self, init_center, init_radius):
if isinstance(init_center, Point):
self.center =init_center
else:
raise TypeError(’Center should be a Point’)
if float(init_radius)>0:
self.radius =float(init_radius)
def __str__(self):
return ’Center :’+str(self.center)+’, Radius :’+str(self.radius)
def surface(self):
return None
def perimeter(self):
return None
def draw(self, axes):
""" axes should be a subplot of a pyplot figure """
pass
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class Circle(Figure):
def __init__(self, init_center, init_radius):
Figure.__init__(self, init_center, init_radius)
def __str__(self):
return ’Circle ’+Figure.__str__(self)
def surface(self):
return np.pi*self.radius**2
def perimeter(self):
return np.pi*self.radius*2
def draw(self, axes):
# Note that Circle and plt.Circle are completely different
classes
circ = plt.Circle((self.center.x, self.center.y), radius=self.
radius, color=’b’)
axes.add_patch(circ)
69
70
71
72
73
74
75
76
77
78
class Koch(Figure):
def __init__(self, init_center, init_radius):
Figure.__init__(self, init_center, init_radius)
def __str__(self):
return ’Koch snowflake ’+Figure.__str__(self)
def surface(self):
return 1.8*0.75*3**0.5*self.radius**2
def perimeter(self):
return np.Inf
79
80
81
82
83
84
85
86
87
88
class Triangle(Figure):
def __init__(self, A, B, C):
if isinstance(A, Point) and isinstance(B, Point) and isinstance(C
, Point):
self.vertex =[A, B, C]
AB = B-A
AC = C-A
product =AB.x*AC.y -AB.y*AC.x
radius =0.5*A.dist(B)*B.dist(C)*C.dist(A)/product
AM = 0.5/product *Point(AC.y*A.dist2(B)-AB.y*A.dist2(C), AB.x
*A.dist2(C)-AC.x*A.
93
89
90
91
92
93
def
94
95
96
97
98
99
100
def
101
102
def
103
104
105
106
107
108
109
110
111
112
113
114
def
dist2(B))
center =A + AM
Figure.__init__(self, center, radius)
else:
raise TypeError(’Need three Point to define a Triangle’)
__str__(self):
s = ’Triangle (’
for p in self.vertex:
s += str(p)
s += ’)\n ’
s += Figure.__str__(self)
return s
perimeter(self):
return self.vertex[0].dist(self.vertex[1]) +self.vertex[1].dist(
self.vertex[2]) +self.
vertex[2].dist(self.
vertex[0])
surface(self):
AB = self.vertex[1]-self.vertex[0]
AC = self.vertex[2]-self.vertex[0]
return 0.5*(AB.x*AC.y -AB.y*AC.x)
draw(self, axes):
""" Draws the Triangle in red and its circumcenter in black """
tri_ccenter =plt.Circle((self.center.x, self.center.y), radius=
self.radius*0.05, color=’
k’)
vertices =np.array([[self.vertex[0].x, self.vertex[0].y],
[self.vertex[1].x, self.vertex[1].y],
[self.vertex[2].x, self.vertex[2].y]])
tri = plt.Polygon(vertices, color=’r’)
axes.add_patch(tri)
axes.add_patch(tri_ccenter)
115
116
117
118
119
120
f = Figure(Point(0,2), 3)
print f
print "Perimeter of f:", f.perimeter()
print "Surface of f:", f.surface(), "\n"
121
122
123
124
125
c = Circle(Point(0,2), 3)
print c
print "Perimeter of c:", c.perimeter()
print "Surface of c:", c.surface(), "\n"
126
127
128
129
130
t1 = Triangle(Point(0,0), Point(3,0), Point(0,4))
print t1
print "Perimeter of t1:", t1.perimeter()
print "Surface of t1:", t1.surface(), "\n"
131
132
133
134
135
t2 = Triangle(Point(-4,0), Point(-2,0), Point(-3,3**0.5))
print t2
print "Perimeter of t2:", t2.perimeter()
print "Surface of t2:", t2.surface(), "\n"
136
137
138
139
140
141
142
# First iteration of the Koch fractal is an equilateral triangle of
# surface 1
k = Koch(Point(0,0), 2*3**-0.75)
print k
print "Perimeter of k:", k.perimeter()
print "Surface of k:", k.surface()
143
144
# Draws the Circle and the two Triangle on a pylab figure
94
145
146
147
148
149
150
151
152
153
154
155
fig = plt.figure(1)
ax = fig.add_subplot(1, 1, 1)
plt.xlim(-5, 6)
plt.ylim(-2, 6)
c.draw(ax)
t1.draw(ax)
t2.draw(ax)
pp = PdfPages("../img/ex_figures.pdf")
pp.savefig()
pp.close()
#fig.show()
L’exécution de ce programme donne :
Center : (0.000000, 2.000000), Radius : 3.0
Perimeter of f: None
Surface of f: None
Circle Center : (0.000000, 2.000000), Radius : 3.0
Perimeter of c: 18.8495559215
Surface of c: 28.2743338823
Triangle ((0.000000, 0.000000)(3.000000, 0.000000)(0.000000, 4.000000))
Center : (1.500000, 2.000000), Radius : 2.5
Perimeter of t1: 12.0
Surface of t1: 6.0
Triangle ((-4.000000, 0.000000)(-2.000000, 0.000000)(-3.000000, 1.732051))
Center : (-3.000000, 0.577350), Radius : 1.15470053838
Perimeter of t2: 6.0
Surface of t2: 1.73205080757
Koch snowflake Center : (0.000000, 0.000000), Radius : 0.877382675302
Perimeter of k: inf
Surface of k: 1.8
6
5
4
3
2
1
0
1
2
4
2
0
2
4
6
Figure 5.1 – Affichage de trois objets sur pyplot
95
6
Pour aller plus loin
Sommaire
6.1
6.2
6.3
6.4
6.5
Analyse de texte par expressions régulières
Interrogation du web et format HTML
Interaction avec le système d’exploitation
Utilisation de fichiers par pickle
Bases de données
6.5.1 Connection
6.5.2 Requêtes SQL
6.6 Passage de Python 2.x à Python 3.x
96
97
98
98
99
99
99
100
A
u-delà des fonctionnalités présentées durant ce stage, Python offre de
nombreuses possibilités. Les expressions régulières et l’interrogation
du web étendent ce qui a été fait avec les chaînes de caractères et les
fichiers texte. La bibliothèque pickle permet de sauvegarder aisément toutes
les informations utilisées par un programme Python. La bibliothèque pyodbc
permet d’écrire un client pour une base de données.
Il en existe bien d’autres. pygame permet d’écrire des jeux (ou plus généralement d’interagir en temps réel avec l’utilisateur). pyopengl permet de créer
des scènes en 3D (connaître le C aide à comprendre la logique de sa syntaxe). socket permet de créer une connection entre deux programmes sur
deux machines distantes via le protocole TCP/IP, fournissant la base d’une
architecture client/serveur. ctypes et scipy.weave permettent de lier C et
Python pour accélerer les fonctions les plus utilisées et les plus gourmandes en
temps de calcul. cv est le port sous Python d’OpenCV : il permet l’acquisition
par caméra et le traitement d’image ; il s’interface aisément avec numpy et PIL.
unittest permet de formaliser les batteries de tests unitaires pour garantir 1
que le programme fonctionne ou au moins que son évolution n’entraîne pas de
régression.
6.1
Analyse de texte par expressions régulières
Le module re implémente en Python les expressions régulières, qui analysent une chaîne de caractère pour tester si celle-ci contient un certain motif.
1. Autant que possible : de façon générale, prouver le bon fonctionnement d’un programme est indécidable.
96
compile(str) transforme une chaîne de caractères en un objet expression
régulière, qui est spécialisé dans la recherche de ce motif particulier (et
donc plus rapide à exécuter).
search(str) ou search(motif, str) : vrai si la chaîne contient le motif
compilé ou le motif passé en paramètre. Renvoie un objet de type MatchObject.
motif.match(str) ou search(motif, str) : vrai si la chaîne correspond
dans son intégralité au motif compilé ou le motif passé en paramètre.
Renvoie un objet de type MatchObject.
MatchObject.group(k) : Renvoie la chaîne de caractères correspondant aux
k e paranthèses de l’expression régulière.
1
import sys, re
2
3
4
5
6
7
8
9
6.2
test42 =re.compile(".*4(.*)2.*")
while True:
s = sys.stdin.readline()
mo = test42.match(s)
if mo:
print "Between 4 and 2 lies ",
print mo.group(1)
Interrogation du web et format HTML
Le module urllib permet d’accéder à des pages web.
La fonction urlopen(url) prend comme paramètre la chaîne de caractère contenant l’url demandée (y compris “http://”) et renvoie la page web
correspondante. Il convient de la lire comme un ensemble de lignes.
1
2
import urllib
import sys
3
4
5
6
7
8
9
10
11
12
if __name__ ==’__main__’:
if len(sys.argv)>1:
if sys.argv[1][:7] ==’http://’:
url = sys.argv[1]
else:
url = ’http://’+sys.argv[1]
page = urllib.urlopen(url)
for line in page:
print line
La page web est livrée avec les balises HTML. Pour exploiter la structure
du code HTML, il faut utiliser le module HTMLParser. Si on préfère analyser la
page web comme un texte quelconque, on peut se limiter aux fonctionnalités
de la classe str ou de la bibliothèque re.
Le module HTMLParser définit une classe HTMLParser dont le rôle est
de traiter les informations contenues dans le fichier HTML. Les méthodes
adéquates du parser sont appelées lorsque des balises, des données, ou d’autres
éléments HTML sont rencontrés. Par défaut, le HTMLParser ne fait rien dans
ces cas : il convient de définir une classe-fille de HTMLParser qui s’en charge.
1
2
import urllib
from HTMLParser import HTMLParser
3
97
4
5
6
7
8
9
10
11
12
13
class MyHTMLParser(HTMLParser):
def handle_starttag(self, tag, attrs):
print "Debut de :", tag
def handle_endtag(self, tag):
print "Fin de :", tag
def handle_data(self, data):
if data[-1] !="\n":
print "Donnees :", data[0:]
else:
print "Donnees :", data[0:-1]
14
15
16
17
18
19
6.3
parser =MyHTMLParser()
url = ’http://www.google.com’
page = urllib.urlopen(url)
for line in page:
parser.feed(line)
Interaction avec le système d’exploitation
Le module os donne accès au système d’exploitation.
system(str) : exécute la commande unix/linux définie par la chaîne de caractères str et renvoie son code de sortie.
popen(str) : exécute la commande linux str et renvoie sa sortie standard.
On peut alors parcourir celle-ci par une boucle for.
1
2
3
4
import os
s = os.popen("ls")
for line in s :
print line ,
Il est désormais conseillé d’utiliser le module subprocess plutôt que os,
plus proche de la structure du système d’exploitation réel, mais à la syntaxe
plus lourde 2 .
6.4
Utilisation de fichiers par pickle
On utilise le module pickle pour réaliser la lecture et l’écriture de données
typées en Python. Cela permet d’écrire des données et lire des données en
conservant leur type (nombre, liste, chaîne de caractère, table de hachage,
array de numpy, . . . ).
Pour écrire :
>>>
>>>
>>>
>>>
>>>
import pickle
x=2
f = open ( " fichier " , ’w ’)
pickle . dump (x , f ) # é crit x
f . close ()
Pour relire :
2. . . . et que l’on ne comprend qu’une fois que l’on sait comment dont gérées les entréessorties et les redirections par le système.
98
>>>
>>>
>>>
>>>
2
f = open ( " fichier " , ’r ’)
x = pickle . load ( f ) # lit x
f . close ()
print x
6.5
Bases de données
Un système de gestion de bases de données (SGBD) est un programme
chargé de stocker de l’information structurée sur un serveur, ainsi que de
l’interroger et la mettre à jour.
Les SGBD libres les plus courants sont PostgreSQL, SQLite, MySQL ou
son fork récent MariaDB ; les SGBD commerciaux les plus courants sont Access
et Oracle. Tous sont accessibles depuis la bibliothèque pyodbc (Python Open
DataBase Connectivity).
Les données sont structurées sous forme de tables, dont les colonnes sont
fortement typées. Chaque ligne correspond à un enregistrement dans la table
(une personne, un cours, une facture, . . . ). Le serveur est interrogé en 3 SQL
(Structured Query Langage).
6.5.1
Connection
La première opération est de se connecter au serveur, ce qui se fait par la
fonction connect(). Il faut renseigner le driver à utiliser, c’est-à-dire le type
de SGBD, ainsi que la machine sur laquelle il se trouve, et l’identité du client.
On récupère ensuite un curseur sur cette connexion qui permettra d’envoyer
des requêtes SQL au serveur.
Une connection à un serveur MySQL installé sur le serveur web de l’école
pourrait être :
cnxn = connect ( driver = ’{ MySQL } ’ , server = ’ www . ensta - bretagne . fr ’ ,
database = ’ test ’ , uid = ’ osswald ’ , pwd = ’ posswd ’)
cursor = cnxn . cursor ()
6.5.2
Requêtes SQL
Une interrogation SQL commence par SELECT et renvoie une ou plusieurs
lignes composées d’une ou plusieurs colonnes.
SELECT colonne(s) FROM table(s)
[WHERE condition(s)]
[[GROUP BY colonne(s)] [HAVING condition(s)]]
[ORDER BY colonne(s)];
La requête est transmise par la méthode execute() du curseur. L’information renvoyée par le SGBD est disponible au travers de ce même curseur.
sqlreq = " SELECT etud_nom , note FROM etudiants WHERE spe = ’ MP ’ and
note > 8 . 5 ORDER BY note DEC ; "
cursor . execute ( sqlreq )
3. Chaque SGBD “parle” son propre idiome de SQL, se référer à la documentation du
SGBD cible pour écrire les requêtes.
99
Il est possible de récupérer l’information ligne par ligne par fetchone().
La ligne est de type Row ; ses colonnes peuvent être extraites par leur numéro
de colonne, comme un tuple, mais aussi par le nom de la colonne dans la
requête.
while True :
row = cursor . fetchone ()
if not row :
break
print ’ Nom : ’ , row . etud_nom , ’\ tNote : ’ , row [ 1 ]
La méthode fetchall permet de récupérer toute l’information renvoyée
dans une unique structure, que l’on peut parcourir par for.
sqlreq = " SELECT etud_nom , note FROM etudiants WHERE spe = ’ MP ’ and
note > 8 . 5 ORDER BY note DEC ; "
cursor . execute ( sqlreq )
rows = cursor . fetchall ()
for row in rows :
print ’ Nom : ’ , row . etud_nom , ’\ tNote : ’ , row [ 1 ]
Le curseur lui-même peut être utilisé comme un itérateur :
sqlreq = " SELECT etud_nom , note FROM etudiants WHERE spe = ’ MP ’ and
note > 8 . 5 ORDER BY note DEC ; "
cursor . execute ( sqlreq )
for row in cursor :
print ’ Nom : ’ , row . etud_nom , ’\ tNote : ’ , row [ 1 ]
Une requête peut aussi être une modification de la table. La méthode
commit() rend les modifications définitives sur le serveur.
sqlreq = " INSERT INTO etudiants VALUES ( ’ Kasparov ’, ’ MP ’, ’ Info ’,
15 . 6 ) ; "
cursor . execute ( sqlreq )
cnxn . commit ()
6.6
Passage de Python 2.x à Python 3.x
Mark Summerfield [Sum09] a réalisé un résumé efficace des différences entre
les dernières versions de Python.
100
Moving from Python 2 to Python 3
Introduction This document is aimed at Python 2 programmers wishing to start devel-
oping using Python 3. The document lists those objects and idioms that have changed
between the versions, showing how to change from Python 2-style to Python 3.1-style.
It also lists some of the most useful new features in Python 3.1. Note that if you
want to convert an existing program or module, the place to start is with the 2to3 tool
(docs.python.org/library/2to3.html). For a complete introduction to the Python 3
language (covering both 3.0 and 3.1, and vastly more than there’s room for here), see
Programming in Python 3 (Second Edition) by Mark Summerfield, ISBN 0321680561
(www.qtrac.eu/py3book.html).
Printing and Executing
Strings and String Formatting
Python 3 strings are Unicode; unicode() is gone
Python 2
Python 3.1
New functions print(), exec(); execfile() is gone
Python 2
Python 3.1
s = unicode(x)
s = str(x)
print a, b, c
print(a, b, c)
s = u"\u20AC"
s = "\u20AC"
print "%03d" % 7
print("{:03d}".format(7))
s = ur"\w"
s = r"\w"
print x,
print(x, end=" ")
String % operator is deprecated; use str.format()
"%d %s" % (i, s)
"%(i)d %(s)s" % (
{'i':i, 's':s})
print>>sys.stderr, x
print(x, file=sys.stderr)
"{} {}".format(i, s)
exec code
exec(code)
"{0} {1}".format(i, s)
exec code in globals exec(code, globals)
"{i} {s}".format(i=i, s=s)
exec code in (
globals, locals)
exec(code,
globals, locals)
execfile(file)
with open(file) as fh:
exec(fh.read())
"{0[i]} {0[s]}".format(
{'i':i, 's':s})
"{i} {s}".format(
**{'i':i, 's':s})
"{i} {s}".format(
**locals())
"%s-%s" % ("X", "X") "{0}-{0}".format("X")
"%(i)d %(s)s" % (
locals())
"{:.2f}".format(3.142)
"%.2f" % 3.142
"{0:.2f}".format(3.142)
"{π:.2f}".format(π=3.142)
"%.4s" % "Prime"
"{:.4}".format("Prime")
"{%d%%}" % 20
"{{{}%}}".format(20)
"%0*d" % (3, 7)
"{:0{}}".format(7, 3)
Representational Form
Backticks are gone; use repr() or str.format()
Python 2
Python 3.1
s = `x`
Division doesn’t truncate; long() is gone; octal
literals must start with 0o (zero-oh)
Python 2
Python 3.1
x = 5 / 2.0 # x==2.5
x = 5 / 2
x = 5 / 2
x = 5 // 2 # x==2
# x==2
# x==2.5
i = 2147483648L
i = 2147483648
j = long(i * 2)
x = 0123
# x==83
j = int(i * 2)
x = 0o123 # x==83
Iterators
New next(); iterators must have __next__()
Python 2
Python 3.1
s = repr(x)
x = iterator.next()
s = "{!r}".format(x)
class Iterator:
class Iterator:
def __init__(self):
def __init__(self):
self.i = -1
self.i = -1
def next(self):
def __next__(self):
self.i += 1
self.i += 1
return self.i
return self.i
s = "{0!r}".format(x)
s = "{z!r}".format(z=x)
Force ASCII representation with ascii()
s = `x`
Numbers
s = ascii(x)
s = "{!a}".format(x)
x = next(iterator)
fn.func_defaults
fn.__defaults__
An operator, an exception, a constant, some types,
several global functions, several dictionary methods, and some itertools functions are gone
Python 2
Python 3.1
fn.func_dict
fn.__dict__
fn.func_doc
fn.__doc__
fn.func_globals
fn.__globals__
fn.func_name
fn.__name__
if a <> b:
obj.method.im_func
obj.method.__func__
obj.method.im_self
obj.method.__self__
Removals and Replacements
if a != b:
fn(*args)
apply(fn, args)
apply(fn, args, kwargs) fn(*args, **kwargs)
obj.method.im_class obj.method.__class__
if isinstance(x,
basestring):
string.letters
string.ascii_letters
string.lowercase
string.ascii_lowercase
string.uppercase
string.ascii_uppercase
threading.Lock. \
acquire_lock()
threading.Lock. \
acquire()
threading.Lock. \
release_lock()
threading.Lock. \
release()
class Thing:
def __init__(
self, x):
self.x = x
def __nonzero__(
self):
return \
bool(self.x)
class Thing:
def __init__(
self, x):
self.x = x
def __bool__(self):
return bool(self.x)
if isinstance(x, str):
x = memoryview(y)
# this is similar
if hasattr(x,
"__call__"):
x = buffer(y)
if callable(x):
fh = file(fname, mode)
fh = open(fname, mode)
if d.has_key(k):
if k in d:
for k, v in \
d.iteritems():
for k, v in d.items():
for k in d.iterkeys():
for k in d.keys():
for k in d:
for v in \
d.itervalues():
for v in d.values():
for line in \
file.xreadlines():
for line in file:
x = input(msg)
x = eval(input(msg))
intern(s)
sys.intern(s)
f = itertools.ifilter(
f = filter(fn, seq)
fn, seq)
m = itertools.imap(
fn, seq)
m = map(fn, seq)
z = itertools.izip(
seq1, seq2)
z = zip(seq1, seq2)
dir = os.getcwdu()
dir = os.getcwd()
s = raw_input(msg)
s = input(msg)
r = reduce(fn, seq)
r = functools.reduce(
fn, seq)
reload(module)
imp.reload(module)
class MyErr(
StandardError):
class MyErr(
Exception):
sys.maxint
sys.maxsize
for i in xrange(n):
for i in range(n):
Exceptions
Catching exception objects requires the as keyword; raising exceptions with arguments requires
parentheses; strings cannot be used as exceptions
Python 2
Python 3.1
try:
process()
except ValueError, \
err:
print err
try:
process()
except ValueError \
as err:
print(err)
try:
try:
process()
process()
except (MyErr1,
except (MyErr1,
MyErr2), err:
MyErr2) as err:
print err
print(err)
raise MyErr, msg
raise MyErr(msg)
raise MyErr, msg, tb
raise MyErr(msg). \
with_traceback(tb)
Implement __bool__() instead of __nonzero__() to
return a custom class’s truth value
Python 2
Python 3.1
raise "Error"
raise Exception(
"Error")
generator.throw(
MyErr, msg)
generator.throw(
MyErr(msg))
fn.func_closure
fn.__closure__
fn.func_code
fn.__code__
generator.throw(
"Error")
generator.throw(
Exception("Error"))
Renamed Attributes and Methods
Renamed Modules
Python 3.1Idioms
Data read from a URL, e.g., using urllib.request.
urlopen() is returned as a bytes object; use
bytes.decode(encoding) to convert it to a string.
The bsddb (Berkeley DB library) is gone—but is
avaliable from pypi.python.org/pypi/bsddb3. See
PEP 3108 (www.python.org/dev/peps/pep-3108)
for module renaming details
Python 2
Python 3.1
Tuples need parentheses in comprehensions; metaclasses are set with the metaclass keyword; import
the pickle and string I/O modules directly; lambda doesn’t unpack tuples; set literals are supported
(the empty set is set(); {} is an empty dict); sorting is fastest using a key function; super() is better;
type-testing is more robust with isinstance(); use
True and False rather than 1 and 0
Python 2
Python 3.1
import anydbm
import whichdb
import dbm
import BaseHTTPServer
import \
SimpleHTTPServer
import http.server
import CGIHTTPServer
import __builtin__
import builtins
import commands
import subprocess
import ConfigParser
import configparser
import Cookie
import http.cookies
import cookielib
import http.cookiejar
import copy_reg
import copyreg
import dbm
import dbm.ndbm
import DocXMLRPCServer
import \
SimpleXMLRPCServer
import xmlrpc.server
import dumbdbm
import dbm.dumb
import gdbm
import dbm.gnu
import httplib
import http.client
import Queue
import queue
import repr
import reprlib
import robotparser
import SocketServer
import \
test.test_support
import Tkinter
urllib.robotparser
class A(
metaclass=MyMeta):
pass
class B(MyBase,
metaclass=MyMeta):
pass
try:
import cPickle \
as pickle
except ImportError:
import pickle
import pickle
try:
import cStringIO \
as StringIO
except ImportError:
import StringIO
import io
fn = lambda (a,): \
abs(a)
fn = lambda (a, b): \
a + b
S = set((2, 4, 6))
fn = lambda t: \
abs(t[0])
fn = lambda a: abs(a)
fn = lambda t: \
t[0] + t[1]
fn = lambda a, b: a + b
S = {2, 4, 6}
import socketserver
S = set([2, 4, 6])
import test.support
L = list(seq)
L.sort()
L = sorted(seq)
words.sort(
lambda x, y:
cmp(x.lower(),
y.lower()))
words.sort(
key=lambda x:
x.lower())
urllib.request, \
class B(A):
def __init__(self):
super(B, self). \
__init__()
class B(A):
def __init__(self):
super(). \
__init__()
urllib.error
if type(x) == X:
import tkinter
urllib.request, \
urllib.parse, \
urllib.error
import \
import urllib2
L = [x for x in (3, 6)]
class A:
__metaclass__ = \
MyMeta
class B(MyBase):
__metaclass__ = \
MyMeta
import \
import \
import urllib
L = [x for x in 3, 6]
import urlparse
import urllib.parse
import xmlrpclib
import xmlrpc.client
if type(x) is X:
while 1:
process()
if isinstance(x, X):
while True:
process()
New in Python 3.1
General Notes
Dictionary and set comprehensions; * unpacking; binary literals; bytes and bytearray types;
bz2.BZ2File and gzip.GzipFile are context managers; collections.Counter dictionary type;
collections.OrderedDict insertion-ordered dictionary type; decimal.Decimals can be created from
floats
Python 2
Python 3.1
Python 3 often returns iterables where Python 2 returned lists. This is usually fine, but if a list is really needed, use the list() factory function. For example, given dictionary, d, list(d.keys()) returns
its keys as a list. Affected functions and methods
include dict.items(), dict.keys(), dict.values(),
filter(), map(), range(), and zip().
Most of the types module’s types (such as types.
LongType) have gone. Use the factory function
instead. For example, replace if isinstance(x,
types.IntType) with if isinstance(x, int).
Comparisons are strict—x < y will work for compatible types (e.g., x and y are both numbers or
both strings); otherwise raises a TypeError.
Some doctests involving floating point numbers might break because Python 3.1 uses David
Gay’s algorithm to show the shortest representation that preserves the number’s value. For example, 1.1 in Python 2 and 3.0 is displayed as
1.1000000000000001, and in Python 3.1 as 1.1.
d = {}
d = {x: x**3
for x in range(5):
for x in range(5)}
d[x] = x**3
S = set(
S = {x for x in seq}
[x for x in seq])
Python 3.1
a, *b = (1, 2, 3)
# a==1; b==[2, 3]
# a==[1, 2]; b==3
*a, b = (1, 2, 3)
a, *b, c = (1, 2, 3, 4) # a==1; b==[2, 3]; c==4
x = 0b1001001
s = bin(97)
y = int(s, 2)
# x==73
# s=='0b1100001'
# y==97
u = "The
" # or: u = "The \u20ac"
# or: u = "The \N{euro sign}"
v = u.encode("utf8") # v==b'The \xe2\x82\xac'
w = v.decode("utf8") # w=='The '
x = bytes.fromhex("54 68 65 20 E2 82 AC")
# x==b'The \xe2\x82\xac'
y = x.decode("utf8") # y=='The '
z = bytearray(y)
z[-3:] = b"$"
# z==bytearray(b'The $')
with bz2.BZ2File(filename) as fh:
data = fh.read()
counts = collections.Counter("alphabetical")
# counts.most_common(2)==[('a', 3), ('l', 2)]
d = collections.OrderedDict(
(("x", 1), ("k", 2), ("q", 3)))
# list(d.keys())==['x', 'k', 'q']
dec = decimal.Decimal.from_float(3.75)
# dec==Decimal('3.75')
Special Methods
The slice methods (__delslice()__, __getslice()__, __setslice__) are gone; instead __delitem()__, __getitem()__, and __setitem__ are
called with a slice object.
The methods __hex__() and __oct__() are gone;
use hex() and oct(). To provide an integer, implement __index__().
String Format Specifications
strings have one or more replacement fields of form: {Name!Conv:Spec}. Name identifies the object to format. Optional !Conv is: !a
(ASCII repr() format), !r (repr() format), or !s
(string format). Optional :Spec is of form:
str.format()
: Fill Align Sign # 0 Width , .Prec Type
is any character except }. Align is: < (left), >
(right), ^ (center), or = (pad between sign and number). Sign is: + (force), - (- if needed), or “ ” (space
or -). # prefixes ints with 0b, 0o, or 0x. 0 means
0-pad numbers. Width is the minimum width. The
, means use grouping commas. .Prec is the maximum width for strs and number of decimal places
for floats. Type is: % (percent), b (binary), d (decimal), e or E (exponential), f (float) g or G (general
float) n (localized) o (octal), x or X (hex). Everything is optional, except that Fill requires Align.
Fill
"{:*=+10.1f}".format(12345.67)
"{:*>+10.1f}".format(12345.67)
"{:+010.1f}".format(12345.67)
"{:,.2f}".format(12345.678)
#
#
#
#
'+**12345.7'
'**+12345.7'
'+0012345.7'
'12,345.68'
An informIT.com
publication by
Mark Summerfield.
#3
Copyright  Qtrac Ltd. 2009.
License: Creative Commons Attribution-Share Alike 3.0 U.S.
Index
Symbols
* . . . . . . . . . . . . . . . . . . . . . . . . . . 18, 23, 30
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
_ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
2to3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
A
ABC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
abc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
abs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
addition . . . . . . . . . . . . . . . . . . . . . . . . . . 30
affectation . . . . . . . . . . . . . . . . . . . . . . . . 25
affichage . . . . . . . . . . . . . . . . . . . . . . . . . . 60
algèbre . . . . . . . . . . . . . . . . . . . . . . . . 22, 30
linéaire . . . . . . . . . . . . . . . . . . . . . . . 31
matricielle . . . . . . . . . . . . . . . . . . . . 86
and . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
animation . . . . . . . . . . . . . . . . . . . . . . . . . 46
anti-slash . . . . . . . . . . . . . . . . . . . . . . . . . 59
apostrophe . . . . . . . . . . . . . . . . . . . . . . . . 59
append . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
arange . . . . . . . . . . . . . . . . . . . . . . . . 26, 27
arguments . . . . . . . . . . . . . . . . . . . . . . . . 58
argv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
arithmétique . . . . . . . . . . . . . . . . . . 15, 21
array . . . . . . . . . . . . . . . . . . . . . . . . . . 23, 25
arrondi . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
as. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .17
B
base de données . . . . . . . . . . . . . . . . . . . 99
bibliothèque . . . . . . . . . . . . . . . . . . . . . . 17
bool . . . . . . . . . . . . . . . . . . . . . . . . . . . 12, 54
booléen . . . . . . . . . 12, 14, 17, 18, 53, 54
boucle . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
break . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
C
C..................................6
calculatrice . . . . . . . . . . . . . . . . . . . . . . . 11
caractère . . . . . . . . . . . . . . . . . . . . . . . . . . 59
casse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
close . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
cmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
commentaires . . . . . . . . . . . . . . . . . . . . . 51
comparaison. . . . . . . . . . . . . . . . . . .17, 53
compilateur . . . . . . . . . . . . . . . . . . . . . . . . 6
complex . . . . . . . . . . . . . . . . . . . 12, 14, 19
complexité . . . . . . . . . . . . . . . . . . . . 61, 67
dans le pire des cas . . . . . . . . . . . 62
moyenne . . . . . . . . . . . . . . . . . . . . . . 62
concaténer . . . . . . . . . . . . . . . . . . . . 51, 79
concatenate . . . . . . . . . . . . . . . . . . . . . . . 28
condition d’arrêt . . . . . . . . . . . . . . . . . . 57
connect . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
constructeur . . . . . . . . . . . . . . . . . . . . . . 87
continue . . . . . . . . . . . . . . . . . . . . . . . . . . 54
copie . . . . . . . . . . . . . . . . . . . . . . . . . . 26, 52
copy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
couleur . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
cursor . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
D
découper . . . . . . . . . . . . . . . . . . . . . . . . . . 59
del . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
dérivation . . . . . . . . . . . . . . . . . . . . . . . . . 84
dessin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
105
det . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
développement limité . . . . . . . . . . . . . 85
diag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
dict . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
dir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
division . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
dot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
double . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
dsolve. . . . . . . . . . . . . . . . . . . . . . . . . . . . .86
help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
héritage . . . . . . . . . . . . . . . . . . . 76, 87, 91
HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
HTMLParser . . . . . . . . . . . . . . . . . . . . . 97
I
if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
image . . . . . . . . . . . . . . . . . . . . . . . . . 75, 76
import . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51, 53
indice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
liste . . . . . . . . . . . . . . . . . . . . . . . . . . 27
négatif . . . . . . . . . . . . . . . . . . . . . . . . 26
infini. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12
insert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
instance . . . . . . . . . . . . . . . . . . . . . . . . . . 87
int. . . . . . . . . . . . . . . . . . . . . . . . .12, 19, 69
integrate . . . . . . . . . . . . . . . . . . . . . . . . . . 85
interpréteur . . . . . . . . . . . . . . . . . . . . . . . . 6
interactif . . . . . . . . . . . . . . . . . . . . 8, 9
inv. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .31
isinstance . . . . . . . . . . . . . . . . . . . . . . . . . 91
itérateur . . . . . . . . . . . . . . . . . . . . . 54, 100
E
échappement . . . . . . . . . . . . . . . . . . . . . . 59
eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
éditeur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
égalité . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
eig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
elif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
emacs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
empty . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
équation
algébrique . . . . . . . . . . . . . . . . . . . . 86
différentielle . . . . . . . . . . . . . . . 72, 86
résolution . . . . . . . . . . . . . . . . . . . . . 70
J
except . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Java
.
.
.
.
.
.
.
........................ 6
exception . . . . . . . . . . . . . . . . . . . . . . . . . . 6
extend . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
L
langage
F
compilé . . . . . . . . . . . . . . . . . . . . . . . . 6
False . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
interprété . . . . . . . . . . . . . . . . . . . . . . 6
fichier. . . . . . . . . . . . . . . . . . . . . . . . . . . . .74
interprété précompilé . . . . . . . . . . 7
file . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74, 76
len
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . 22, 51
filtre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
ligne
de commande . . . . . . . . . . . . . . . . . 9
flatten . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
float . . . . . . . . . . . . . . . . . . . . . . . . . . 12, 19 limite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
for . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54, 98 linspace . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
format . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 list. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .25
liste . . . . . . . . . . . . . . . . . . . . . . . 21, 51, 55
fraction
vide . . . . . . . . . . . . . . . . . . . . . . . . . . 52
rationelle . . . . . . . . . . . . . . . . . . . . . 83
from . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 logiciel libre . . . . . . . . . . . . . . . . . . . . . . . . 5
long . . . . . . . . . . . . . . . . . . . . . . . . . . . 12, 13
G
M
gedit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
math
.
.
.
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . 18
global . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
glue logicielle . . . . . . . . . . . . . . . . . . . . . . 6 matplotlib . . . . . . . . . . . . . . . . . 33, 45, 75
guillemet . . . . . . . . . . . . . . . . . . . . . . . . . 59 matrice . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
max . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
H
mémoire . . . . . . . . . . . . . . . . . . . 12, 52, 89
hachage
code . . . . . . . . . . . . . . . . . . . . . . . . . . 52 min . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
table . . . . . . . . . . . . . . . . . . . . . . . . . 52 module . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
haut niveau . . . . . . . . . . . . . . . . . . . . . . . . 6 Monty Python . . . . . . . . . . . . . . . . . . . . . 5
106
R
multiplication
matricielle . . . . . . . . . . . . . . . . 23, 31 r . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
terme à terme . . . . . . . . . . . . . . . . 30 raise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
mutable. . . . . . . . . . . . . . . . . . . . . . . . . . .52 ramasse-miette . . . . . . . . . . . . . . . . . 6, 89
randint . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
N
random . . . . . . . . . . . . . . . . . . . . . . . 30, 69
NaN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 range . . . . . . . . . . . . . . . . . . . . . . . . . 22, 54
nombre . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 rank . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
noms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 Rational . . . . . . . . . . . . . . . . . . . . . . . . . . 82
None . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 ravel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
not . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 re . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
numpy . . . . . . . . . . . . . . . . . 17, 18, 25, 69 read . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
récursivité . . . . . . . . . . . . . . . . . . . . . . . . 57
O
objet . . . . . . . . . . . . . . . . . . . . . . . . . . . 6, 87 regexp . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
odeint . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 remove. . . . . . . . . . . . . . . . . . . . . . . . . . . .51
ones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 repr. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .13
oo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 reshape . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
open . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 retour à la ligne . . . . . . . . . . . . . . . . . . . 59
OpenCV . . . . . . . . . . . . . . . . . . . . . . . . . . 75 return . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
opérateur . . . . . . . . . . . . . . 15, 30, 90, 91 rotation . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
or. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53 round . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
os. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .98
S
scipy . . . . . . . . . . . . . . . . . . . . . . . . . . 32, 33
série . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
series . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
SGBD . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
solve . . . . . . . . . . . . . . . . . . . . . . . . . . 31, 86
sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
split . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
spyder . . . . . . . . . . . . . . . . . . . . . . 7, 15, 18
SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
str. . . . . . . . . . . . . . . . . . . . . . . . .13, 58, 59
string . . . . . . . . . . . . . . . . . . . . . . . . . 59, 96
subprocess . . . . . . . . . . . . . . . . . . . . . . . . 98
summation. . . . . . . . . . . . . . . . . . . . . . . .85
suppression . . . . . . . . . . . . . . . . . . . . . . . 51
surcharge d’opérateur . . . . . . . . . . . . . 90
symbole. . . . . . . . . . . . . . . . . . . . . . . . . . .82
sympy . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
sys. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .58
system . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
P
paquet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
paramètre . . . . . . . . . . . . . . . . . . . . . 55, 57
pass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
pickle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
PIL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
pluma . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
pop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
popen. . . . . . . . . . . . . . . . . . . . . . . . . . . . .98
primitive . . . . . . . . . . . . . . . . . . . . . . . . . . 85
print . . . . . . . . . . . . . . . . . . . . . . 11, 13, 60
privée . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
produit
scalaire . . . . . . . . . . . . . . . . . . . . . . . 31
publique . . . . . . . . . . . . . . . . . . . . . . . . . . 91
PyDev . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
pylab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
pyodbc . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
pyplot . . . . . . . . . . . . . . . . . . . . . . . . . 33, 92
T
Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.* . . . . . . . . . 5, 15, 19, 53, 60, 100 tableau . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Python(x,y) . . . . . . . . . . . . . . . . . . . . . 6, 7 tabulation . . . . . . . . . . . . . . . . . . . . . . . . 59
temps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Q
quad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 transformation . . . . . . . . . . . . . . . . . . . . 77
quadrature numérique. . . . . . . . . . . . .71 transtypage . . . . . . . . . . . . 14, 27, 58, 89
quicksort. . . . . . . . . . . . . . . . . . . . . . . . . .66 tri. . . . . . . . . . . . . . . . . . . . . . . . . . . . .60, 67
107
bulles . . . . . . . . . . . . . . . . . . . . . . . . . 62
insertion . . . . . . . . . . . . . . . . . . 63, 64
segmentation . . . . . . . . . . . . . . . . . 66
sélection . . . . . . . . . . . . . . . . . . 60, 61
Shell . . . . . . . . . . . . . . . . . . . . . . 65, 66
trigonométrie . . . . . . . . . . . . . . . . . . . . . 19
hyperbolique . . . . . . . . . . . . . . . . . . 20
True . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
try . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
tuple . . . . . . . . . . . . . . . . . . . . . . . . . . 52, 56
typage
dynamique . . . . . . . . . . . . . . . . . 6, 12
fort . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
type . . . . . . . . . . . . . . . . . . . . . . . 14, 18, 91
U
url . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
urllib . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
UTF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
V
valeur
de retour . . . . . . . . . . . . . . . . . . . . . 56
par défaut . . . . . . . . . . . . . . . . . . . . 57
Van Rossum . . . . . . . . . . . . . . . . . . . . . . . 5
var . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
variable . . . . . . . . . . . . . . . . . . . . . . . 13, 16
globale . . . . . . . . . . . . . . . . . . . . 55, 56
locale . . . . . . . . . . . . . . . . . . . . . . . . . 55
vdot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
vecteur . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
W
write. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .74
Z
zeros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
108
Bibliographie
[Bre12]
Bressert, Eli: SciPy and NumPy. O’Reilly, 2012
[BS09]
Bicquelet-Salaün, Jean-Louis: PIL Frequently-Asked Questions.
http://jlbicquelet.free.fr/scripts/python/pil/
pil.php. Version: 2009
[CBCC11] Casamayou-Boucau, Alexandre ; Cauvin, Pascal ; Connan,
Guillaume: Programmation en Python pour les mathématiques.
Dunod, 2011
[CLRS94] Cormen, Thomas H. ; Leiserson, Charles E. ; Rivest,
Ronald L. ; Stein, Cliffort: Introduction à l’algorithmique. 2.
Dunod, 1994
[Kiu10]
Kiusalaas, Jaan: Numerical methods in engineering with python.
2nd. Cambridge, 2010
[Knu68]
Knuth, Donald E.: The art of computer programming. Bd. 1.
Addison-Wesley, 1968
[Knu73]
Knuth, Donald E.: The art of computer programming. Bd. 3.
Addison-Wesley, 1973
[Lan11]
Langtangen, Hans P.: A Primer on Scientific Programming with
Python. Springer, 2011
[Lut09]
Lutz, Mark: Learning Python. O’Reilly, 2009
[Lut10]
Lutz, Mark: Programming Python. O’Reilly, 2010
[Pet02]
Peters, Tim: Timsort explanations. http://bugs.python.org/
file4451/timsort.txt. Version: 2002
[Rou12]
Rougier, Nicolas P.: Matplotlib tutorial. http://www.loria.fr/
~rougier/teaching/matplotlib/#d-plots. Version: 2012
[Sol12]
Solem, Jan E.:
O’Reilly, 2012
[Sum09]
Summerfield, Mark: Programming in Python 3 (Second Edition)
A Complete Introduction to the Python Language. 2. AddisonWesley Professional, 2009
Programming computer vision with python.
109
Téléchargement