Formation python : initiation aux concepts de base
…
1.2 Utiliser Python
Que ce soit sur Windows ou sur UNIX et Linux, la mise en place de Python ne pose aucun problème. Après une installation réussie, vous avez surtout deux manières d’utiliser l’interpréteur :
1°) Interactivement, en saisissant des commandes Python l’une après l’autre. Par exemple, voici une session interactive dans une console Linux pour effectuer quelques divisions – dont certaines peuvent surprendre (“bash_$” est l’invite de mon système Linux, “>>>” celle de l’interpréteur Python; les textes tapés par l’utilisateur ont été reproduits en caractères penchés) :
bash_$ python
Python 2.3.4 (#1, Dec 11 2007, 05:27:57)
[GCC 3.4.6 20060404 (Red Hat 3.4.6-9)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 100 / 3
33
>>> 100 / 3.0
33.333333333333336
>>> 100 / -3
-34
>>> 100 / 0
Traceback (most recent call last):
File "", line 1, in ?
ZeroDivisionError: integer division or modulo by zero
>>> (ici on a tapéCtrl-D)
bash_$
Notez que sur Windows, le programme IDLE, qui s’installe en même temps que Python, ouvre une console particulièrement bien adaptée à la pratique de Python.
2°) En exécutant un programme (on dit volontiers un script) préalablement saisi. Par exemple, si on a écrit un script, dans un fichier nomméfactorielle.py, pour évaluer la factorielle n! = n x (n − 1) x • • • x 3 x 2 x 1 d’un nombre n lu au clavier, voici comment en obtenir l’exécution :
bash_$ python factorielle.py
nombre ? 40
40 ! = 815915283247897734345611269596115894272000000000 bash_$
Si vous lisez déjàle Python, le texte du fichier factorielle.py est visible à la section 5.4, page 20.
1.3 Se faire aider par eclipse
Une fois installés eclipse (il suffit de décompresser le fichier eclipse.zip téléchargé) et Pydev (làc’est plus compliqué; suivez les instructions de la rubrique Getting started dans, pour dé-velopper en Python il faut
1°) Activer eclipse en lançant le fichier nomméeclipse.exe sur Windows, eclipse ailleurs. Au bout d’un moment on obtient l’interface graphique représentée sur la figure 1.
2°) Lui faire adopter la perspective Pydev (menu Window D Open Perspective D Other... D Pydev ou bien la petite icône en haut à droite de la fenêtre principale).
3°) La première fois, créer un nouveau projet (menu File D New D Pydev Project). Dans l’exemple de la figure 1, le projet a été nommé Atelier Python.
4°) Créer un fichier source (menu File D New D Pydev Module). Dans l’exemple de la figure 1, le module s’appelle factorielle (le fichier source s’appelle donc factorielle.py).
Vous n’avez plus qu’à saisir le code du script en question. Constatez comment les erreurs sont signalées dès leur frappe et comment dans beaucoup d’occasions eclipse vous suggère les mots corrects qu’il vous est permis d’écrire.
2 Expressions
2.1 Constantes numériques
Une constante littérale est l’expression écrite d’une valeur connue; exemples : 12, -5, 3.5, 0, etc.
La donnée représentée par une constante a toujours un type qui détermine ses propriétés formelles (comme : quelles opérations la donnée peut-elle subir?) et matérielles (comme : combien d’octets la donnée occupe-t-elle dans la mémoire de l’ordinateur?). La manière la plus simple et la plus fiable de connaître le type d’une expression consiste à poser la question à Python. Exemple d’une session de telles questions et réponses :
>>> type(0)
>>> type(-5)
>>> type(2000000000)
>>> type(3000000000)
>>> type(-5.0)
>>> type(602.21417e+021)
>>>
En ignorant la présentation , délibérément biscornue, le dialogue précédent nous apprend, ou du moins nous suggère, que
– sans surprise, des constantes comme 0, -5 ou 2000000000 représentent des nombres entiers (type int),
– lorsqu’un nombre entier est trop grand pour être représenté comme un entier ordinaire, Python le code automatiquement comme un entier long (type long) ; c’est très pratique, mais il faut savoir que les opérations arithmétiques sur de tels nombres sont moins rapides que celles sur les entiers ordinaires,
– dès qu’une constante numérique comporte un point, qui joue le rôle de virgule décimale, Python comprend qu’il s’agit d’un nombre décimal, on dit plutôt flottant, et le représente en machine comme tel (type float),
– lorsque les nombres décimaux sont très grands ou très petits on peut employer la « notation scientifique » bien connue; par exemple, la constante 602.21417e+021 représente le nombre 6,0221417 × 1023 ou encore 602214170000000000000000,
– le caractère flottant d’un nombre est « contagieux » : si une opération arithmétique a un opérande entier et un opérande flottant, alors pour effectuer l’opération l’entier est d’abord converti en flottant et l’opération est faite selon les règles des nombres flottants; exemple : le résultat de la multiplication 1.0 * 5 est le nombre flottant 5.0.
2.2 Variables
Un identificateur est une suite de lettres et chiffres qui commence par une lettre et n’est pas un mot réservé(comme if, else, def, return, etc.). Le caractère _ est considéré comme une lettre. Exemples : prix, x, x2,
nombre_de_pieces, vitesseDuVent, etc. Majuscules et minuscules n’y sont pas équivalentes : prix, PRIX et Prix sont trois identificateurs distincts.
Une variable est constituée par l’association d’un identificateur à une valeur. Cette association est créée lors d’une affectation, qui prend la forme
variable = valeur
A la suite d’une telle affectation, chaque apparition de la variable ailleurs que dans la partie gauche d’une autre affectation représente la valeur en question... jusqu’àce qu’une nouvelle affectation associe une autre valeur à la variable. On confond parfois le nom de la variable (c.-à-d. l’identificateur) et la variable elle-même (l’association du nom à une valeur) ; c’est sans gravité.
Si un identificateur n’a pas été affecté(en toute rigueur il n’est donc pas un nom de variable) son emploi ailleurs qu’au membre gauche d’une affectation est illégale et provoque une erreur. Session Python de demonstration :
>>> nombre
Traceback (most recent call last):
File "", line 1, in ?
NameError: name ’nombre’ is not defined
>>> nombre = 10
>>> nombre
10
>>> nombre = 20.5
>>> nombre
20.5
>>>
Comme on le voit sur cet exemple, en Python:
2.3 Chaînes de caractères
Une donnée de type chaîne de caractères est une suite de caractères quelconques. Une constante chaîne de caractères s’indique en écrivant les caractères en question soit entre apostrophes, soit entre guillemets : ’Bonjour’ et "Bonjour" sont deux écritures correctes de la même chaîne.
Si la chaîne doit contenir un des caractères ’ ou " cela fournit un critère pour choisir l’une ou l’autre manière de l’écrire : ’"Oui" dit-il’ ou "L’un ou l’autre". Une autre manière d’éviter les problèmes avec le caractère d’encadrement consiste à l’inhiber par l’emploi de \, comme dans la chaîne ’Il n\’a pas dit "oui"’.
L’encadrement par de triples guillemets ou de triples apostrophes permet d’indiquer des chaînes qui s’étendent sur plusieurs lignes :
>>> s = """Ceci est une chaîne
comportant plusieurs lignes. Notez que
les blancs en tête de ligne
sont conservés"""
>>> s
’Ceci est une chaîne\ncomportant plusieurs lignes. Notez
que\n les blancs en tête de ligne\nsont conservés’
>>>
L’affichage basique d’une telle chaîne est décevant (voir ci-dessus) mais montre bien que les fins de ligne, représentés par le signe \n, ont été conservés. L’affichage à l’aide de la fonction print est plus esthétique :
>>> print s
Ceci est une chaîne
comportant plusieurs lignes. Notez que
les blancs en tête de ligne
sont conservés
>>>
CONCATÉNATION. L’opérateur + appliquéà deux chaînes de caractères produit une nouvelle chaîne qui est la concaténation (c’est-à-dire la mise bout-à-bout) des deux premières :
>>> ’Nabucho’ + ’donosor’ ’Nabuchodonosor’ >>>
ACCÈS À UN CARACTÈRE INDIVIDUEL. On accède aux caractères d’une chaîne en considérant celle-ci comme une séquence indexée par les entiers : le premier caractère a l’indice 0, le second l’indice 1, le dernier l’indice n − 1, n étant le nombre de caractères. Exemples :
>>> s = ’Bonjour’
>>> s[0]
’B’
>>> s[6]
’r’
>>> s[-1]
’r’
>>>
Le nombre de caractères d’une chaîne s est donné par l’expression len(s). Pour accéder aux caractères à la fin d’une chaîne il est commode d’employer des indices négatifs : si i est positif, s[-i] est la même chose que s[len(s) - i].
TRANCHES. On peut désigner des tranches dans les chaînes; la notation est chaîne[début:fin] où début est l’indice du premier caractère dans la tranche et fin celui du premier caractère en dehors de la tranche. L’un et l’autre de ces deux indices peuvent être omis, et même les deux. De plus, ce mécanisme est tolérant envers les indices trop grands, trop petits ou mal placés :
>>> s = ’Bonjour’
>>> s[3 :5]
’jo’
>>> s[3 :]
’jour’
>>> s[ :5]
’Bonjo’
>>> s[ :]
’Bonjour’
>>> s[6 :3]
’’
>>> s[-100 :5] ’Bonjo’
>>> s[3 :100] ’jour’
>>>
Les chaînes de caractères sont immuables : une fois créées il ne peut rien leur arriver. Pour modifier des caractères d’une chaîne on doit construire une nouvelle chaîne qui, si cela est utile, peut remplacer la précédente. Par exemple, proposons-nous de changer en ’J’ le ’j’ (d’indice 3) de la chaîne précédente :
>>> s
’Bonjour’
>>> s[3] = ’J’
Traceback (most recent call last):
File "", line 1, in ?
TypeError: object doesn’t support item assignment
>>> s = s[ :3] + ’J’ + s[4 :]
>>> s
’BonJour’
>>>
2.4 Opérateurs
OPÉRATEURS ARITHMÉTIQUES.
+, -, * : addition, soustraction, multiplication. Ces opérateurs obéissent à la règle dite « du plus fort » : si un des opérandes est flottant, l’autre opérande est converti si nécessaire en flottant et l’opération et le résultat sont flottants. Si, au contraire, les deux opérandes sont entiers, l’opération et le résultat sont entiers.
/ : division. Obéit à la même règle que les trois précédents, mais on prendra garde au fait que cela peut être surprenant : 3/2 vaut 1 et 2/3 vaut 0.
Pour obtenir un résultat flottant il faut se débrouiller pour qu’au moins un des opérandes soit flottant : 3.0/2 ou float(3)/2 valent bien 1.5.
Attention : float(3/2) vaut 1.0, car la conversion en float intervient après la perte des décimales.
% : reste de la division euclidienne, celle qu’on apprend à l’école élémentaire 3 : si a et b sont entiers alors a/b est le quotient et a%b le reste de la division de a par b.
En toute rigueur cette opération ne devrait être définie que pour deux opérandes entiers, mais Python se débrouille pour la faire marcher même avec des opérandes flottants.
** : puissance : a**b vaut ab, c’est-à-dire a x a x • • • x a si b est entier, eb×log a sinon.
...
3.4 Break et else dans les boucles
L’instruction break placée à l’intérieur d’une boucle while ou for produit l’abandon immédiat de la boucle et la continuation de l’exécution par la première instruction qui se trouve après la boucle. La clause else, si elle est présente, n’est alors pas exécutée.
acquisition de la chaîne s et du caractère c
for i in range(len(s)):
if s[i] == c:
break
else:
i = -1
ici, la valeur de i répond exactement à la question
ATTENTION, PIÈGE! Notez que else est indenté comme for. L’aligner avec if aurait complètement changé le sens de ce bout de code et l’aurait rendu faux.
4 Structures de données 4.1 Tuples
Un tuple est une séquence immuable : on ne peut pas modifier ses éléments ni lui en ajouter ou lui en enlever. En contrepartie de cette rigidité les tuples sont très compacts (i.e. ils occupent peu de mémoire) et l’accès à leurs éléments est très rapide.
On crée un tuple en écrivant ses éléments, séparés par des virgules et encadrés par des parenthèses. Si cela ne crée aucune ambiguïté, les parenthèses peuvent être omises. Un tuple constitué d’un seul élément a doit être écrit « a, » ou « (a,) ». Le tuple sans éléments se note « () ».
Dans les exemples suivants, la valeur de la variable t est un tuple de cinq éléments :
>>> t = 2, ’deux’, 2.0, True, (1, 2, 3, 4)
>>> t
(2, ’deux’, 2.0, True, (1, 2, 3, 4))
>>> t, type(t), len(t)
((2, ’deux’, 2.0, True, (1, 2, 3, 4)), , 5)
>>> t[1]
’deux’
>>> t[-1]
(1, 2, 3, 4)
>>>
Comme on le voit, un élément d’un tuple peut être un tuple à son tour. C’est tellement facile et pratique qu’on écrit des tuples sans s’en rendre compte : l’expression « t, type(t), len(t) » est elle-même un tuple de trois éléments.
Un tuple de variables peut figurer comme membre gauche d’une affectation, il faut alors que le membre droit soit un tuple de même taille:
>>> point = 3, 4 >>> point
(3, 4)
>>> x, y = point >>> x
3
>>> y
4
>>>
4.2 Listes
Une liste est une séquence modifiable : on peut changer ses éléments, lui en ajouter et lui en enlever. Cela rend les listes un peu moins compactes et efficaces que les tuples, mais considérablement plus utiles pour représenter des structures de données qui évoluent au cours du temps.
On construit une liste en écrivant ses éléments, séparés par des virgules, encadrés par les crochets. La liste vide se note [ ]. Voici quelques opérations fondamentales sur les listes (voir aussi § 7.1) :
liste[indice] désignation de l’élément de rang indice de la liste,
liste[indice] = expression remplacement de l’élément de liste ayant l’indice indiqué,
liste1 + liste2 concaténation (mise bout-à-bout) de deux listes,
liste.append(élément) ajout d’un élément à la fin d’une liste,
liste.insert(indice, élément) insertion d’un élément à l’emplacement de liste indiqué par l’indice donné, élément in liste test d’appartenance : élément E liste ?
for élément in liste parcours séquentiel (voir § 3.3).
N.B. Il y a donc deux manière de commander l’opération « ajouter un élément à la fin d’une liste ». On prendra garde à cette différence entre elles :
liste + [ élément] ne modifie pas liste, mais renvoie une nouvelle liste comme résultat,
liste.append(élément) modifie liste et ne renvoie pas de résultat.
borne = 100 # pour l’exemple
premiers = [ ]
for candidat in xrange(3, borne + 1, 2):
estPremier = True
for premier in premiers:
if candidat % premier == 0: estPremier = False
break
if EstPremier:
premiers.append(candidat) print premiers
4.3 Ensembles
Les ensembles sont des structures de données avec les caractéristiques suivantes :
– il n’y a pas d’accès indexé aux éléments, ni d’ordre entre ces derniers,
– il n’y a pas de répétition des éléments : un élément appartient ou non à un ensemble, mais cela n’a pas de sens de se demander s’il s’y trouve plusieurs fois,
– en contrepartie, le test d’appartenance est optimisé: le nécessaire est fait pour que le test élément ∈ ensemble ? (en Python : élément in ensemble) puisse être évalué de manière extrêmement efficace.
On construit un ensemble par une expression de la forme set( séquence ) où séquence est une donnée parcourable (liste, tuple, chaîne de caractères, etc.).
Exemple :
>>> s = set("abracadabra") >>> s
set([’a’, ’r’, ’b’, ’c’, ’d’]) >>>
Parmi les principales opérations des ensembles : élément in ensemble élément appartient-il à ensemble ?
ensemble.add(élément) ajout de l’élément indiqué à l’ensemble indiqué ensemble .remove(élément) suppression de l’élément indiqué de l’ensemble indiqué ensemble,.issubset (ensemble2) tous les éléments de ensemble, appartiennent-ils à ensemble2 ?
ensemble,.union(ensemble2) ensemble des éléments appartenant à ensemble, ou à ensemble2
ensemble,.intersection(ensemble2) éléments de ensemble, qui sont aussi éléments de ensemble2
ensemble,.difference(ensemble2) éléments de ensemble, qui ne sont pas dans ensemble2
Notez que les opérations a.issubset(b), a.union(b), a.intersection(b) et a.difference(b) peuvent aussi se noter, respectivement, a <= b, a | b, a & b et a - b.
texte = """Maitre Corbeau, sur un arbre perche
Tenait en son bec un fromage
Maitre Renard, par l’odeur alleche lui tint a peu pres ce langage"""
auMoinsUneFois = set()
auMoinsDeuxFois = set() for caract in texte:
if caract in auMoinsUneFois: auMoinsDeuxFois.add(caract) else:
auMoinsUneFois.add(caract)
print auMoinsUneFois.difference(auMoinsDeuxFois)
4.4 Dictionnaires
Un dictionnaire, ou table associative, est une collection de couples (clé, valeur) telle que
– il n’y a pas deux couples ayant la même clé,
– la structure est implémentée de manière que la recherche d’une valeur à partir de la clé correspondante soit extrêmement efficace.
...
4.5 Tableaux
Les tableaux les plus basiques 5, comme ceux des langages C ou Java, existent en Python mais ne font pas partie du cœur du langage. Définis dans le module array de la bibliothèque standard, pour pourvoir les utiliser dans un programme on doit écrire au début de celui-ci la directive
from array import array
Il s’agit de tableaux simples et homogènes. Cela veut dire que leurs éléments doivent avoir un type commun, et que ce doit être un type primitif de la machine sous-jacente (ou plutôt du langage C dans lequel la machine Python est écrite).
Lors de la création d’un tableau on doit indiquer le type de ses éléments; cela se fait par une lettre : ’i’ pour un tableau d’entiers, ’f’ pour un tableau de flottants, etc. Exemple, création d’un tableau d’entiers (il n’est pas nécessaire à ce niveau de donner la taille – nombre maximum d’éléments – du tableau) :
tableau = array(’i’)
Voici les principales opérations qu’un tel tableau pourra subir ensuite :
tableau[indice] obtention de la valeur de l’élément ayant l’indice indiqué,
tableau[indice] = valeur affectation d’une nouvelle valeur à l’élément ayant l’indice indiqué;
cet élément doit exister, sinon une erreur est déclenchée,
tableau.append(valeur) ajout de la valeur indiquée à la fin du tableau indiqué;
cette opération augmente le nombre d’éléments du tableau,
tableau.extend(séquence) allongement du tableau indiquépar les éléments de la séquence indiquée;
cela permet notamment de transformer une liste, un ensemble, etc., en un tableau, ou – à l’aide des fonctions range ou xrange – de donner à un tableau une taille quelconque,
texte = """Maitre Corbeau, sur un arbre perche
Tenait en son bec un fromage
Maitre Renard, par l’odeur alleche lui tint a peu pres ce langage"""
from array import array
compteurs = array(’i’)
compteurs.extend( [ 0 ] * 256 )
for c in texte:
compteurs[ord(c)] = compteurs[ord(c)] + 1
for i in range(256): if compteurs[i] != 0:
print chr(i), ’:’, compteurs[i], ’occurrence(s)’
On remarquera dans le programme précédent comment le tableau est initialiséavec une liste de 256 zéros (concaténation de 256 exemplaires de la liste [ 0 ]).