Hachette Spé NSI Term - Hachette
100% (1) 100% ont trouvé ce document utile (1 vote) 43 vues 360 pages Description améliorée par l'IA
Ce document est un manuel d'enseignement sur la programmation en Python, couvrant des concepts fondamentaux tels que les types de données, les opérations logiques et arithmétiques, ainsi que la syntaxe de base. Il présente également des structures de données comme les listes, tuples et dictionnaires, ainsi que des concepts avancés comme les classes et les fonctions. En outre, le manuel inclut des ressources en ligne accessibles via des QR codes pour un apprentissage interactif.
Permis
© All Rights Reserved
Formats disponibles
Téléchargez aux formats PDF ou lisez en ligne sur Scribd
@ SCIENCES
INFORMATIQUES
| (Caccesunne >)
Manuel enseignant gratuit
> Idéal pourla vidéoprojetion
Manuel ]
numérique =
Site fr]
collection ms
hachette
EDUCATIONTbe)
°
Les boolens sont les valeurs logigues True (val et False (aus)
Les opérations logiques sont le ou (or ou |), ie et (and ou), ete non (not)
(5<3) or (3>2) vaut True (5<3) & (352) autFalse not (5>3) vaut False
Les nombres peuvent étre enter (int, par exemple @ ou -5998) ou 8 vigule fortanie (Float, par exemple 1.0 cu 3.14)
Une opération entre un entier et un flottant produit en général un flottant.
Opérations arithmétiques : addition (+), soustraction (-), multiplication (*), division (/), puissance (**), division entiéne
(/D.t9ste de la division entiére (%).
Comparaisons :égale (=), diferent (
5), inférieur (<), supérieur (>), nfétieur ou égal (<=), supérieur ou gal (>=)
Les chaines de caractéres sont dslimitées par des quilemets droits simples * ou doubles ". Une chaine délimitée par " peut
Contenir "et inversement. Une chaine sur plusieurs lignes est délimitée par trois guillemets simples ou doubles.
Les caractéres spéciaux \n et \t dénotentrespectivement un retour ligne et une tabulation
CChaines de formatage ou « strings» f"Texte {var}" (attention au f) produit une chaine gui inclut a valeur de la
variable var (par exemple "Texte 23” si var vaut 23)
Opérations sur les chaines :
Concaténation (+) épettion (*) Acces (C1) Inclusion (in)
"abc" + "def! Mab" * 3 "be" in "abed"
vaul "abedef™ aut "ab!ab' ab!" vautTrue
(2]} Variables, affectation et expressions
Une variable est une référence nommiée vers une valeur ou un objet
Les nams de variables ne peuvent contenir que des signes alphanumériques (@-z, A-Z et 0-9) et des « blancs soulignés »
(underscore _), mals ne peuvent pas commencer par un nombye. Ils sont sensible dla casse : abe est dilférent de Abe.
affectation attibue une valeur Sune variable aide
du symbole =:nom_variable = expression texte = "Non premier texte”
{attention ne pas canfondre avec le test fégaité twoPi = 2 * pi
expression peut gue une valeur, une vatiable, un distance = sqrt(x**2 + y*2)
anpel de fonction, ou une combinaison dopérations.
Compréhension de liste: La syntaxe Liste = liste = []
[expression for i in conteneur] cores for i in conteneur:
ponda Liste. append expression)
Ainsi[#'{4*2}! for 4 in range(4)] produit: ['0', "2", 14", 16")
(3) Types structurés
Un tuple est une collection ordonnée d’éléments pouvant éxre de types différents. d = (14, "juillet", 1789)
Une liste (Li st) est une collection ordonnée d'éléments pouvantétre de types différents 1 = [1, 3, 5, 7]
Un tableau est une liste dont les éléments sont tous du meme type
Python ne defiit pas de type tableau, Cest au programmeur de contréler les types dans ses List.
Un dictionnaire ('ict) est une collection muable qui associe a des clés uniques de typesimmuables (en générales chaines
dle caractéres) des valeurs de nimporte quelstypes.d = {'j': 14, "mt: "juillet, tat: 1789}
‘tuple (immuable) List (muable) dict (muable)
initialisation val, val2,. Vs[valt, val, lélivall, cLé2:val2,u}
Acces vali, val2,.=t — Uentier] d[cté]
Ajout Impossible [Link] (van) d[clen] = valn
Suppression Impossible det U2] del dfcté]
Modification Impossible ‘Us}=vat d[etés]=vat
Talle Len(t) Ven(1) Ven(d)Syntaxe Py
Un bloc est une séquence dinstructions ayant routes la méme indentavion,
Une condition est une expression qui retourne un booléen, par exemple x < 3.ouest_pair(y).
Un conteneur est une valeur d'un type structuré ou un intervalle défin parla foncilon range
range(d, n, p) produit un conteneurdfentiers de d inclus m exclu par pas de p,
range(d, n) coresponda range(d, n, 1). range(n) correspond a range(®, n, 1)
ommm
Une conditionnelle (i f) exécute un bloc en fonction
de la véracité d'une condition Ele peut optionnellement
defini un autre bloc & exécuter sila condition est fausse
(else), cuencore « chainer» un nombre indéterminé de
testsavec des elif (else + if)
Une boucle non bornée (whi Le) exécute un bloc tant
‘qu'une condition est vrae (attention aux bouclesinfnes)
Une boucle bornée (For) exécute un bloc un nombre
'Brédeéfini de fois en changeant la valeur dune variable.
Un traitement d’exception (try) exécute un bloc et,en
cas derreur,traite celle-ci dans un bloc except corres-
pondant 3 sonniom
Une fonetion permet de donner un nom a un bloc de
cde. Elle se déciare comme suit
Lappel dune fonction a la forme ci-contre
paraml,
par les expressions expr,
if conditiont:
bloct
elif condition2: # optionnet
bloc?
els # optionnel
bloc3
nitile condition:
bloc
for var in conteneur:
bloc
try:
bloc
except erreur:
bloc
def non_fonction(param!, paran2,
corps
nom_fonction(expr1, expr2,
ones paramétres : des norns de vatables qui peuvent etre utlisées dans le bloc cor ps, et qui sont intialisés
‘passes en! arguments lorsque la fonction est appede. Les parameéties peuvent avoir une
valeur par défaut, param = val, qui est utlisée sila fonction est appelée sans argument correspondant. Le corps peut
ontenir une ou plusieuts instructions return expression, qui terminent lexécution de la fonction en renvoyant la
valeur de expression.
Toute variable déclarée dans le corps d une fonction est locale cette fonction et nest pas utlsable en dehors, instruction.
global. var permet de modifier dans une fonction une variable qui lui est externe.
omm
Une elasse définit un « moule » permertant de créer des
objets contenant des attributs.
Une classe contient un constructeur optionnel et un
ensemble de méthodes, qui doivent avoir seLf comme
premier paraméue. seLf référence objet de la classe pour
lequel on a appelé la méthode.
(On crée un objet en appelant saclasse comme une fonction,
On fait référence aux attributs et on appelle les méthodes
vec la notation pointée.
class C:
def _init_(self, params.
# constructeur
self.x = @# attribut
def m(self, parans.
# méthode
0 = Cargs..
print(o.x)
o.m(args. ..)
) # création d'objet
# accés 8 un attribut
f appel de méthodePTL a
Dans ce qui sult, et p sont des enters, x et y des nombres en virgule flotante, a un angle en radians, ch une chaine de
caractéres, b un booléen, Lune liste ou un tableau), d un dictionnaire, f une fonction et w un interacteur.
O imoonnron nn
Conversions:n = int('123!),x = float('12.3'),ch = str(1.23),1 = List(ch)
Fonetions numérques:n = round(x),x = abs(y),x = min(y, Z, =). = max(y, 2,
Saisieau clavier:ch = input('message')
Conteneurs:n = Len(1),[Link](),[Link](),[Link] ()
Conudledetype:isinstance (valeur, type),ol typeest int, Float, str, List, dict, tupleouunnomdeclasse
( 2} Importer une bibliothéque
Les bibliothéques permettent dimporter des variables et des fonctions depuis un autre fichier Python,
Code Commentaire
import math Importe le module math cammeune variable, via laquelle onaccéde
x = [Link]([Link]) § tous ses composants.
from math import * Import routes les variables et fonctions de math. Pratique, mals
x = sqrt(pi) pas recommands
from math import pi, sqrt as racine importe uniquement les fonctions et variables dont on a besoin et
x = racine(pi) renomme sqrt en racine.
(3 J) Fonctions mathématiques : bibliothéque
Arrondis inférieur et supérieur:n = floor(x),n = ceil(x)
Racine carrée:y = sqrt (x)
Trigonométrie: pi, sin(a), cosa), tan (a)
Exponentielle et logarthmes:y = exp(x),y = logie(x),y = Log2(x)
{4} Géneration aléatoire : bibliothéque
random()(0 Jupyter
permettant de l'exécuter de maniére interactive ;
+ au code source a télécharger pour la réalisation de l'activité diintroduction, du TP ou
des exercices manqués du picto de téléchargement why ;
+ 8 des exercices supplémentaires.
De la méme facon, les sujets de projets sont complétés par des ressources en ligne a téléchar-
ger, accessibles avec le OR-code de la page du projet.
© Avant de commencer
Un langage de programmation permet de donner des instructions 4 un ordinateur via du texte
ui peut étre lu et compris la fois par un étre humain et par un ordinateur. Ces instructions
peuvent étre trés simples, comme effectuer des opérations arithmétiques & la maniére d'une
calculette ; ou elles peuvent étre exirémement complexes, comme simuler des interactions
entre molécules ou faire tourner un jeu vidéo.
Le « code source » d'un programme est un texte qui doit suivre des régles trés strictes, sinon
Fordinateur ne saura pas /interpréter ni fexécuter, Pour faciliter l'écriture de code source, au
lieu dlutilser un traitement de texte, on utilise un environnement qui permet de contréler la
syntaxe du code, den exécuter tout ou partie, voire daider 4 son écriture
Trois environnements permettent décrire et d'exécuter du code Python : linterpréteur en
ligne de commande, environnement EduPython et les « notebooks » Jupyter
* Programmer et exécuter du Python en ligne de commande
La premiére solution est dlutiiser un interpréteur dans un terminal, Un terminal est une
interface textuelle permettant de saisir et d’exécuter des instructions en ligne de commande.
Systéme dexploitation Lancement
Windows Taper Win + R pour faite apporsie Vout Exéuter (tur)
puis taper cmd suiv dea touche Entiée dans le champ de texte
Ubuntu (Linu) Taper Ctrl + ALt + T pour ouvir terminal
acos Taper Cmd_+ Espace pour fire appaaiteFoutl Spovkaht
puis entrer Terminal et sélectionner [application correspondante,
Une fois dans un terminal, la commande py thon (suivie de la touche Entrée) lance lemode
interactif, dans lequel toute commande est interprétée comme une instruction Python,
jusqu’a ce que l'utilisateur entre la commande qui t () ou ferme le terminal, Aprés chaque
commande, linterpréteur affiche le résultat de l'instruction,Si environnement iPython est installé sur votre systéme, la commande i python remplace
avantageusement le mode interactif par défaut (py thon), en offrant par exemple la coloration
syntaxique et l'auto-compiétion. La coloration syntaxique rend le code plus lisible en utilisant
des couleurs différentes pourles mots-clés du langage, les chatnes de caractéres, etc, ’auto-
completion est la capacité d'un éditeur de texte a suggérer la fin d'un mot ou d'une expression.
Dans iPython, cela s‘obtient a l'aide de la touche Tabulation Sj
ee eer)
sie rer
eet aera Coe
Sestonoey |
Le mode interactif devient rapidement limité lorsque l'on doit réaliser des programmes
complexes. La commande python permet également dexécuter le code contenu dans un
fichier texte, de suffixe . py par convention. Ainsi la commande python mon_code. py
exécute le code Python contenu dans le fichiermon_code . py, ce qui permet dlutiliser des
éditeurs de texte adaptés a la programmation, comme celui de EduPython.
* Programmer et exécuter du Python avec EduPython
EduPython est une application que on peut installer uniquement sous Windows et qui fournit
un environnement de programmation complet. Une fois install il suffit de double-cliquer un
fichier Python (suffixe « py) pour quil s‘ouvre dans EduPython
La partie gauche de la fenétre permet de gérer les fichiers qui contiennent les programmes,
la partie droite est un traitement de texte spécialisé pour le code Python (avec coloration
syntaxique et auto-complétion) et la partie inférieure est similaire au terminal et permet diexé
cuter le code, Les menus et la barre d'outils contiennent un ensemble de commandes tres
complet. II suffit par exemple de cliquer le bouton « Play » ) pour lancer 'exécution du
programme.EduPython facilite la mise au point d'un programme grace au « debugger » J. On peut
cliquer dans la marge en face d'une instruction pour mettre un point d’arrét. On lance ensuite
Vexécution en mode mise au point (! ‘oouton a droite du bouton ll ). Le programme
Sarréte lorsquil rencontre une instruction marquée d'un point dlarrét et EduPython affiche
les valeurs des différentes variables. On peut ensuite continuer l'exécution ligne & ligne ou
jusqu‘au prochain point d'arrét
* Programmer et exécuter du Python avec Jupyter
Lenvironnement Jupyter s‘exécute dans un navigateur Web. Selon linstallation, on peut le
lancer depuis EduPython (menu Outils > Outils > Jupiter) ou depuis la ligne de commande,
via un terminal, grace ala commande «notebook» jupyter ou jupyter Lab selon
la configuration du systéme (Lab est une version plus /écente de notebook)
Un Jupyter (« notebook ») est un environnement de programmation constitué decellules qui
contiennent du code source ou du texte non interprété. Comme iPython (dont il est dérivé),
Jupyter est destiné 8 faciiter 'écriture et lexécution de code, en offrant la coloration syntaxique
et 'auto-complétion. Jupyter permet d’éditer directement le contenu des cellules et d’exécuter
le contenu des cellules de code (avec la combinaison Ctr l+Entrée). Le résultat saffiche
alors en-dessous de la celiule.
Nom du notebook _ Type de cellule (texte, code,
ellule de texte
Cellule de code
ws Ss «Sortie »
de la cellule
Navigateur Nombre d'exécutions de cellules
de fichiers depuis le lancement du notebook
Les environnements Jupyter sont généralement composés d'une barre latérale a gauche qui
peut afficher les fichiers contenus dans le dossier depuis lequel |a commande Jupyter a été
exécutée ou différentes options et interfaces de configurations, Le cadre principal, a droite,
S‘ouvre par défaut sur un onglet « Launcher » (lanceur) qui permet par exemple de créer un
nouveau notebook, de lancer une console Python (similaire au made interactif en ligne de
commandes) ou de créer dautres fichiers texte. L'utlisateur pourra par exemple créer et éditer
des fichiers . py directement, sans passer par un programme d’éditioncHaprTre 1 EUs)
1.
2.
3.
4.
i
ee
Interface et implémentation
Les listes,
Les piles
Les files
Les dictionnaires.
cuapitre 2 Teor)
1.
2.
3.
4.
eee aud
Objets et attributs
Classes et méthodes
Programmer avec des objets
Objets et structures de données
cuaprtre 3 [Jivesy nian)
a
2.
3.
4.
Ene)
Modularité
Tester et mettre au point
Types d’erreurs
Construire et exécuter
des jeux de tests
cHaprTre 4 Eee eaMaeeh aes
- SGBD et SOL
Le modéle relationnel
Mises a jour
Cohérence
Conception de schéma
Les autres problemes
des bases de données
12
12
14
16
17
30
34
35
37
39
52
56
57
58
61
70
74
75
75
77
79
81
cHAPITRE S FlR=1)N
pee ey
ET MODE PROGRAMME [EES
1. Interroger des tables en SQL : SELECT..96
2, Mode programme
et traitements complexes 101
CHAPITRE 6 [33ers 114
1. Les fonctions récursives 118
2, Récursion simple et multiple tai
3. Les algorithmes du type
«cdiviser pour régner » 122
cHaprtre 7 Etta 136
1. Les arbres : définition 140
2. Les arbres binaires 141
3. Les arbres binaires de recherche... 143
cHaprtre 8 [etary 158
1. Aspects fondamentaux
des graphes. 162
2. Les graphes en programmation 164
3, Parcours de graphes. 166
cuapitre 3 [tet 176
1. Allocation d’adresses 180
2. Plan de données
et plan de contréle 181
3. Protocoles de routage 162CHAPITRE 10 [Nea
ee ital i 196
Un peu d'histoire 200
. Le chiffrement symétrique. 202
La cryptographie asymétrique
pour distribuer des clefs 203
Le protocole HTTPS 206
CHAPITRE 12 [e)=-eC)
Definition d'un systéme sur pce. 222
Historique de l'intégration
dans le monde des ordinateurs....... 222
Eléments des systémes sur puce
et leur évolution 223
Exemples des SoC
microcontréleurs, 224
Exemple des SoC
de smartphones 226
SoC et communications externes..... 228
Pee eet sy
ese) 240
Programme et processus 244
Ordonnancement 244
Ressource 245
Etat d'un processus 245
Verrou 246
Interblocage 246
Manipulation de processus
et verrous 249
(irate ALGORITHMES
Cis)
1. Programmation dynamique 268
2. Recherche textuelle 270
(ir oattaety CALCULER SUR
Beet anes) 284
1. Dualité entre programmes
et données
2. Calculabilité
288
290
CHAPITRE 15 [vaya} yes} 302
1. Les paradigmes impératif et objets 306
2. Le paradigme fonctionnel 307
3. Usages et propriétés 311
Vers le Bac 318
Propositions de projets 323
Corrigés des exercices 327
* Les exercices conigés sont signalés
parlapuce( 1 Jou 2}
Le picto (S) indique les exercices faire en débranché.
Le picto a¥s indique qu'un fichier est a télécharger.
PEELE
Lasyntaxe Python
Les bibliothéques utilisées
Chronologie historique
Généalogie des langages
Commandes fréquentes
et raccourcis-claviereae e
@))) Le pitch
La résolution de probléme par des programmes informatiques nécessite de bien
définir les données manipulées par ces programmes. Pour cela, on utilise des
types abstraits de données adaptés au probléme. Un type abstrait est spécifié
par son interface de programmation, qui est indépendante de son implémenta-
tion, Grace a cette modularité, il est possible de remplacer une implémentation
dun type abstrait par une autre, par exemple plus efficace, sans toucher au
reste du programme. Ce chapitre présente quatre types abstraits classiques :
les listes, les piles, les files et les dictionnaires, et montre plusieurs implé-
mentations de chacun d'eux
hochetecch
inet)TEST
© Xe; sont les types structures de Python ?
a) Chaine de caractéres b) Dictionnaire) Nombre entier
d) Nombre a viguleflottante —e) Tableau f) Tuple
© duclestleiype de chacune des expressions suivantes?
[10, 20, 30) {ta 30} | (at, "bt, *e")
a) Tuple a) Tuple 2) Tuple
b) Tableau b) Tableau b) Tableau
Dictionnaire |) Dictionnaire Dictionnaire
d)Chaine d) Chane ) Chaine
8 Quelles méthodes Python s'appliquent aux types Python suivants ?
+ Tableau + Dictionnaire
a) append 9) append
b) insert h) insert
©) items i) items
d) keys i) keys.
e) sort k) sort
values D values
© Luebs types sont immuaties en Python ?
a) Chatnede caractéres 6) Dictionnaire) Tableau) Tuple
© ceelles affirmations sont comrectes ?
a)
b)
°
d
e)
#
© Acvelts syPe(9 Python sapplique le code ci-contre ?
a)
b)
°
d
Un élément d'un tuple peut étre un tuple.
(On peut ajouter un élément a un tuple.
Les éléments dun tableau sont immuables.
Les éléments dun tableau peuvent etre des tableaux.
Les clés d'un dictionnaire peuvent étre muables.
Les valeurs d'un dictionnaire peuvent étre muables,
for e in x:
x est une chaine de caractires print(e)
x est un dictionnaire
xest un tableau
x est un tuple
Réponses page 327.
(CHAPITRE 1 | STRUCTURER LES DONNEESz
f=)
=
E
o
=)
r=]
oO
o
=
z
[Fl
r=)
Lu
=
u
—)
=
o
<
10
n peu de géométrie
OBJECTIFS Spécifier et implémenter quelques types abstraits de la geométrie.
@© Points
En géométrie, un point du plan est souvent représenté par ses coordonnéesx et y.
1. Proposer deux implémentations d'un point avec les types structurés Python.
2. Définir quelques opérations élémentaires sur les points sous forme de fonctions :
créer un pointa partir de ses coordonnées, calculer la distance de l’origine a un point,
translater un point par les coordonnées d’un autre point (considéré alors comme un
vecteur), calculer la distance entre deux points.
3. Coder et tester ces fonctions avec les deux implémentations proposées. Quels sont
les avantages et inconvénients de chaque implémentation ?
Lensemble des opérations s‘appelle un type abstrait de données car elles sont définies
indépendamment du choix a'implémentation, Ces opérations définissent linterface d'une
structure de données, ici le point,
@ Segments
Un segment de droite est défini par deux points
1.Dé iterface d'un segment, c’est- les opérations permettant de créer un
segment, de changer ses extrémités, de calculer sa longueur et de le translater par
les coordonnées d’un point.
Proposer deux implémentations d’un segment en utilisant le type abstrait défini
ci-dessus pour les points.
3. Coder les opérations ci-dessus avec chacune des implémentations proposées et
vérifier que chacune fonctionne avec les deux implémentations des points.
@ Polygones
Un polygone est une figure fermée constituée d'une suite de sommets (des points)
1. Définir interface d’un polygone, avec notamment une opération qui retourne la
longueur du polygone.
2. Proposer deux implémentations d’un polygone, comme une séquence de points ou
une séquence de segments.
3. Coder les opérations avec ces deux représentations. Quels sont les avantages et
inconvénients de chaque implémentation ?
@ J, Dessiner
Le fichier dessin. py contient les fonctions croix (x, y, couleur) et trait (x1,
Y1, x2, y2, couleur) qui dessinent une croix et un trait de la couleur donnée
© Modifier les interfaces et implémentations des trois types abstraits (point, segment,
polygone) pour ajouter une fonction de dessin.Expressions bien pa We)
OBJECTIF Déterminer si une expression est bien parenthésée.
Les expressions mathématiques utilisent des parenthéses (), des crochets [] et des accolades
{} qui doivent étre correcternent imbriqués. Ainsi lexpression (3 * (4 + 5) estincomrecte car
il manque une parenthése fermante. En Python, les expressions doivent également étre bien
parenthésées, par exemple un dictionnaire qui contient des tableaux et des tuples :{"a! :
[(10, 20), (5, 6)], 'b': ([10, 20], 30)}.
© Compter les parenthéses
Dans un premier temps, on considére une expression qui ne contient que des parenthéses,
1. Ecrire un programme qui lit une expression (sous forme de chaine de caractéres) et
indique si le parenthésage est correct.
2. Modifier le programme pour qu'il indique, en cas de mauvais parenthésage, s'il
manque des parenthéses ouvrantes ou fermantes et leur nombre.
@ Cas général
Lorsque lexpression contient des parenthéses, crochets et accolades, on ne peut pas seule-
ment compter leur nombre comme dans le cas précédent. On doit mémoriser les caractéres
ouvrants au furet a mesure quel'on analyse expression et verifier que chaque fermant corres-
pond & louvrant le plus récent qui n'est pas encore fermé
‘© Appliquer cette méthode & la main sur les exemples donnés plus haut. Quels sont
les différents cas d’erreur ?
© |mplémentation avec une pile
Un type abstrait qui répond a ce besoin est la pile : comme une pile diassiettes, elle permet
diempiler des valeurs de telle sorte qu'elles sont dépilées dans ordre inverse de leur empile-
ment. interface d'une pile est la suivante
+ p=creer_pile() crée une pile vide;
+ p=empiler(p, e) empile 'élément e;
+ p=dépiler (p) retire lélément au sommet de la pile;
+s = sommet (p) retourne élément au sommet de la pile (sans le retirer);
+ b= pile_vide(p) indique sila pile est vide;
+ t=elements_pile(p) retourne un tableau Python avec le contenu de la pile.
abs Télécharger le fichier pi Le. py qui contient les fonctions ci-dessus.
© Utiliser une pile pour écrire un programme qui vérifie le bon parenthésage d’une
expression. S'il trouve une erreur, le programme indique celle-ci et s'arréte.
@ Corriger les erreurs
Lorsque le programme précédent détecte une erreur de parenthésage, il sarréte sans analyser
la suite de expression. Le programme peut cependant tenter de corriger erreur.
‘© Modifier le programme pour quil tente de corriger les erreurs en insérant ou suppri-
mant des caractéres.
(CHAPITRE 1 | STRUCTURER LES DONNEES
itcle eM Celia)
Le langage Python dispose, comme tous les langages de haut niveau, d'un ensemble
de types de base et de types structurés vus dans le programme de Premiére
nombres, chaines de caracteres, tuples, tableaux, dictionnaires. Ces types sont des
briques de base qui permettent de créer des structures de données plus complexes.
Pour deéfinir ces structures de données, on utilise des types abstraits de données
Un type abstrait est caractérisé par une interface de programmation, cest-a-dire
un ensemble d’opérations qui permettent de manipuler les données de ce type.
On distingue
+ les constructeurs, qui permettent de créer une nouvelle structure de données ;
+ les opérateurs, qui permettent de modifier la structure de données, par exernple
en ajoutant ou retirant des données ;
+ lesaccesseurs, qui donnent de linformation surla structure de données, comme
son nombre diéléments ;
+ lesitérateurs, qui permettent dénumérer les éléments de la structure de données.
Spécifier un type abstrait, Cest définir son interface, sans préjuger de la fagon dont
ses opérations seront implémentées, Implémenter un type abstiat, c’est fournir le
code de ces opérations en utilisant des types existants, Plusieurs implementations
peuvent répondre a la méme spécification. Le programmeur peut alors choisir celle
qui lui convient le mieux. Certaines implémentations peuvent étre plus ou moins
rapides, plus ou moins économes en mémoire ou plus ou moins adaptées 3 des
données de grande taille
En séparant la spécification de implémentation, il est plus facile de diviser le travail
des programmeurs et d organiser la structure générale du programme. Certains types
abstraits trés souvent utilises, comme ceux présentés dans ce chapitre, sont égale-
ment disponibles dans des bibliothéques logicielles || sufit alors de connaitre leur
interface pour les utiliser, sans avoir entrer dans les détails de leur implé mentation.
Les quatre types abstraits présentés dans ce chapitre sont utlisés tres fréquemment
dans toutes sortes de programme. Ils servent aussi de base & d'autres types abstraits.
Nous verrons ainsi qu'une file peut étre implémentée avec deux ples, elles-mémes
implémentées par des listes, ou qu'un dictionnaire peut étre implémenté avec
des listes,
Les implémentations présentées dans ce chapitre utlisent un style deprogramma-
tion fonctionnelle : les opérations sont des fonctions qui prennent la structure de
données en paramétre et, pour les constructeurs et opérateurs, retournent la struc-
ture résultant de lopération. Le chapitre suivant présentera des impiémentations
utilisant un style de programmation par objets
Une liste est une séquence ordonnée d’éléments. Son interface minimale est la
suivante
+ creer_liste() :constructeur qui retourne une liste vide;
+ liste_vide(): accesseur qui retourne Vrai sila liste lest vide;
+ insérer(I, e) : opérateur qui insére e en téte de liste et retourne la nouvelle liste
+ téte(I): accesseur qui retourne lélémenten téte de liste (si celle-ci r’est pas vide);
+ queue(|): accesseur qui retourne la liste privée de son premier élément (sila liste
nest pas vide) ;
+ éléments _liste(!):itérateur qui retourne un tableau contenant les éléments de
la liste, que on peut ensuite énumérer avec une boucle For.
122.1. Implémentation par des tuples
On peut implémenter une liste en Python en utilisant des tuples. Comme les tuples
Python sont immuables, la liste elle-méme sera immuable, ce qui peut étre intéres-
sant dans certains cas (voir exercice 22).
Une liste est représentée par un tuple (téte, queue) od téte est le premier
élément de la liste et queue est le reste de la liste, qui estelle-méme une liste (donc
un tuple),
Limplémentation est ts simple
def creer_liste():
return () # 1a Liste vide est le tuple vide
def Liste_vide(Liste):
return Liste is () # la Liste est vide si c'est le tuple vide
def inserer(Liste, element)
return (elenent, Liste) # nouvelle Liste = tuple avec 1'élément en t@te
def tete(Liste):
assert not Liste vide(liste), "tete : liste vide !"
elenent, = liste # 1a t8te de Liste est le ter élément du tuple
return element
def queve(liste):
assert not liste vide(liste), "queue : liste vide !*
_, reste = Liste # 1a queve de 1a liste est le 2e élément du tuple
return reste
def elenents_Liste(Liste):
res = [] 4 le tableau résultat
while Liste is not (): 3 chaque itération :
tete, liste = liste # extraire L'élénent et la nouvelle liste
[Link](tete) # L'ajouter 1'élénent au résultat
return res # retourner le résultat
On peut utiliser la liste de la maniére suivante
Liste = creer_liste()
liste = inserer(Liste, Alice")
liste = inserer(Liste, "Bob")
liste = inserer(liste, Charlie”)
elem = tete(Liste) # elem vaut “Charlie”
reste = queue(Liste) # reste est 1a liste "Bob", “Alice”
liste_vide(Liste) # False
for in elements liste(Liste):
print(e) # Charlie Bob Alice
Létat de la liste apréslaligne 4 est ("Charlie", ("Bob", ("ALice", ()))).
Conventionnellement, on représente leslistes par une chatne de maillons reliés par
des fléches. La liste ci-dessus est représentée ainsi
liste ——® Charlie | @—®} Bob | @}-— Alice
(CHAPITRE 1 | STRUCTURER LES DONNEES
132.2. Implémentation par un tableau
Une autre implémentation possible d'une liste consiste a utiliser un tableau. La liste
est alors représentée par un tuple constitué du tableau et du nombre d'léments
de la liste. La représentation de la liste de exemple précédent avec un tableau de
taille 5 est alors la suivante
Liste = (["Charlie", "Bob", "Alice", None, None], 3)
Cette implémentation est laissée a titre d'exercice (n® 2)
Le tableau ayant une tale fixe il faut prévoir que la capacité della liste est limitée ala
taille du tableau. Il est aussi possible de créer un tableau plus grand et dy recopierla
liste lorsque nécessaire. Dans ce cas, on peut vouloir recopier la liste dans un tableau
plus petit lorsque la taille de la liste devient trop petite
2.3. Etendre interface
(On peut enrichir interface d'une liste de plusieurs opérations
+ taille({) : accesseur qui retourne le nombre d’éléments de la liste ;
sme(|, i) : accesseur qui retoumne le -me élément de la liste ;
+ ajouter_fin(l, e) : opérateur qui ajoute e ala fin de la liste
Dans implémentation avec les tuples, les opérateurs ci-dessus sont couiteux a réali-
ser car les tuples sont immuables et il faut donc créer une nouvelle liste complete
Une pile est un ensemble ordonné ’éléments qui se comporte comme une pile
dlassiettes:on peut ajouter une assiette sur pile ou prendre lassiette surle dessus
dela pile.
Son interface minimale est la suivante
+ creer_pile() :constructeur qui retourne une pile vide ;
le_vide(p) : accesseur qui retourne Vrai sla pile p est vide ;
+ empiler(p, e) : opérateur qui ajoute e au sommet de la pile p;
+ dépiler(p) : opérateur qui retire élément en sommet de pile (si elle n’est pas
vide) et retourne la nouvelle pile ;
+ sommet(p) : accesseur qui retourne le sommet de la pile (si elle n'est pas vide) ;
+ elements_pile(p): itérateur qui énumére les éléments de la pile
3.1. Implémentation par une liste
Une liste permet diimplémenter une pile de fagon quasiment immeédiate pulsque
les opérations insérer (), téte() et queue () correspondent respectivement
2empiler(), sommet () et dépiler (). Cette implémentation est laissée en
exercice (n° 5)
3.2. Implémentation par un tableau
Une autre implémentation consiste a utiliser un tableau. De fagon similaire a l'im-
plémentation d'une liste par un tableau, on utilise un tuple contenant le tableau
lui-méme et le nombre d'léments dans la pile, qui est aussi lindice auquel sera
ajouté le prochain élément.
14Comme un tableau a une taille limitée, on spécifie la capacité maximale de la pile &
sa création et une opération daccés pour tester sila pile est pleine
+ creer_pile(n) : constructeur qui retourne une pile vide, de capacitén éléments;
+ pile_pleine(p) : accesseur qui retourne Vial sila pile p est pleine.
def creer_pile(n): # une pile vide est un tuple forme
return ([None] * n, @) # d'un tableau den éléments et d'une taille de a
def pile_vide(pile):
_, top = pile
return top == 0 # 1a pile est vide si sa taille est 0
def pile_pleine(pite):
t, top = pile
return top
Ten(t) 1a pile est pleine si sa taille = sa capacité
def empiler(pile, eLenent):
assert not pilepleine(pile), “enpiler : pile pleine !*
t, top = pile
t{top] = elenent # on ajoute 1'élément au bout du tableau
return (t, top +1) # on retourne 1a nouvelle pile
def depiler(pile):
assert not pilevide(pile), "depiler : pile vide !"
t, top = pile
return (t, top-1) # on retourne 1a nouvelle pile
def somet (pile
assert not pilevide(pile), "sonnet : pile vide !”
t, top = pile # récupérer le tableau et 1a taille
return t{top-1] # le somet est en-dessous de 1’ indice top
def elenents_pile(pile):
res = [] # Le tableau résultat
t, top = pile
for i in range(top, @, -1): # on parcourt du sonnet vers la base
[Link](t[i-1]) # i va de top 1, d'od le i-1
return res # on retourne le tableau résultat
On peut utiliser la pile de la maniére suivante
pile = creer_pile(10)
1
2 pile = empiler(pile, "Alice”)
3 pile = empiter(pite, "Bob")
4 pile = empiler(pite, "Charlie")
5 elem = sonmet(pile) ¥ elem vaut “Charlie”
6 pile = depiler(pite) # la pile a 2 éléments
7 pile_vide(pite) # False
8 for e in elements pile(pile):
9 print(e) # Bob Alice
Létat du tableau représentant la pile aprés chacune des lignes 184 et aprés la
ligne 6 est le suivant :
4 3 4
7 1 q op
1 1 1
a | o
ee
3i
2 lop
1
a
(CHAPITRE 1 | STRUCTURERLES Données 15
lopCOURS
Rei
Une file est un ensemble ordonné d'éléments qui se comporte comme une file d'at-
tente : un nouvel arrivant se met a la fin de la file, tandis que la prochaine personne
servie est celle en téte de file, La différence avec une pile est que dans une pile, le
dernier arrivé est le premier servi — on parle d'une liste LIFO :Last in, First Out, alors
que dans une file, le premier arrivé est le premier servi — on parle d'une liste FIFO
First in, First Out,
interface minimale d'une file est la suivante:
+ creer_file() :constructeur qui retourne une file vide ;
+ file_vide(f) : accesseur qui retourne Vraisia file est vide ;
+ enfiler(f, e): opérateur qui ajoute e dla fin de la ile ;
+ défiler(f) :opérateur qui retire 'élément en début de file (si elle n'est pas vide) ;
+ téte_file(f) : accesseur qui retourne le premier élément de la file (si elle r’est pas
vide)
+ elements _file(f) : itérateur qui énumere les éléments de la file
41, Implémentation par un tableau
Comme la pile et la liste, on peut implémenter une file avec un tableau, en lul
donnant une capacité limitée. Comme pour la pile, on représente la file par un
tuple (tableau, taille) et on ajoute les éléments a lindice tai lle (sauf
sile tableau est plein). Contrairement ala pile, on doit retirer les éléments audébut
du tableau
Une solution simple est de décaler les éléments du tableau :
def defiler(file):
assert not file_vide(file), “defiler : file vide !"
t, taille = file
taille -= 1 # 1a file a un élénent de moins
for i in range(taille): # on décale les élénents d'un cran vers la gauche
tli] = tCist]
return (t, taille) # on retourne 1a nauvelle file
Lillustration ci-dessous monte la file avant et apres le décalage des éléments (les
flaches bleues indiquent la copie des éléments du tableau)
i t
(= T=]
4.2. Implémentation par un tableau circulaire
Limplémentation précédente est cotteuse si |a file est grande puisqu’a chaque
retrait, il faut recopier tous les éléments restants, Une implémentation plus efficace
consiste a considérer le tableau comme un anneau dont la fle occupe les éléments
de indice debut a indice Fin -1.
On ajoute les éléments & Indice Fin, comme pour une pile, mais lorsqu'on arrive
la fin du tableau, on continue a remplir au début (si le tableau n'est pas plein)
Similairement, on retire les éléments & indice debut, et lorsque celui-ci arrive ala
fin du tableau, on le replace au début.
Ainsi, aprés plusieurs ajouts et retraits, les éléments de la file occupent la fin du
tableau puis le début de celui-ci, comme illustré ci-dessous. Les éléments verts sont
les éléments du tableau qui appartiennenta la file, cast-a-diree1, e2, e3, e4:
16Limplémentation en Python est laissée a titre d’exercice (n°9),
4.3. Implémentation par deux piles
Une autre implémentation d'une file consiste & utiliser deux piles, entree et
sortie, On ajoute les éléments sur la pile entree et on les retire de la pile
sortie. Sila pile sortie est vide, on y transfére les éléments de la pileentree.
Lillustration ci-dessous montre les deux piles au départ, puis aprés avoir ajouté
Alice, Bobet Char Lie, puis avoir retiré la téte de file (AL ce), ce quia provoqué
letransfert de la pile d’entiée vers a pile de sortie, et enfin aprés larivée deDenise.
On voit qu’a toutes les étapes, les éléments sont dans ordre de leur arrivée.
entiter
(,2 1 0 0 1 2
caine sonia
Limplémentation en Python est laissée a titre d'exercice (n° 10)
Lavantage de cette méthode est que si 'on utilise l'mplémentation des piles
entree et sortie par des tuples, an obtient une file sans limitation de capacité.
5. Les dictionnaires
Un dictionnaire associe des clés a des valeurs, de méme qu'un dictionnaire francais-
anglais, par exemple, associe 4 chaque mot sa traduction.
Linterface minimale d'un dictionnaire est la suivante :
+ creer_dico() : constructeur qui retourne un dictionnaire vide ;
+ ajouter(d, cle, valeur) ; opérateur qui ajoute cle au dictionnaire et lassocie &
valeur;
+ valeur_cle(d, cle) : accesseur qui retourne la valeur associée a cle, si elle est
présente ;
+ cles_dico(f): itérateur qui énumére les clés du dictionnaire,
(CHAPITRE 1 | STRUCTURERLES Données 17Le langage Python fournit directement le type structuré dict qui implémente un
dictionnaire
+ creer_dicol):d = dict() oud={}
+ ajouter(d, cle, valeur) :d[cle] = valeur
+ valeur_cle(d, cle): d[cle]
+ dles_dico(d): for cle ind:
lIn'y a donc pas d'intérét particulier & fournir une autre implémentation, sauf éven-
tuellement dans des cas particuliers ati les performances ne seraient pas satisfaisantes.
5.1. Implémentation par une liste
Hormis l'utilisation directe du dct Python, une implémentation simple consiste
créer une liste de tuples (cLe, valeur). L’ajout d'une nouvelle entrée se fait au
début et la recherche d'une clé se fait en parcourant a liste.
Cette méthode est peu efficace lorsque la taille du dictionnaire augmente. Elle peut
étre améliorée sil existe un ordre sur les clés, en utilisant un tableau classé par ordre
croissant de clé et une recherche dichotornique.
Limplémentation est laissée a titre dlexercices (n° 12 et 33).
5.2. Implémentation par une table de hachage
Une implémentation plus efficace consiste a utiliser un tableau et a transformer la
cléen un indice dans le tableau grace a une fonction de hachage. Par exemple, si
lon considére des clés qui sont des chaines de caractéres, une fonction de hachage
peut consister 8 ajouter les codes de chaque caractére, modulo [a taille du tableau
HTAILLE = 109 ¥ taille des tables de hachage
def hachage(cle):
code = 0
for car in cle:
code 42 ord(car)
return code % HIATLLE
Cela permet de trouver directement emplacement d'une clé dans le tableau, sans
avoir besoin de le parcourir. II suffit alors de stocker la valeur assaciée a la clé a cet
indice du tableau.
Cependant, il est possible que deux clés différentes alentle méme code de hachage
On appelle cela une collision. Il existe plusieurs méthodes pour traiter les collisions
La méthode illustrée ci-dessous consiste a stocker dans chaque élément de la table,
Lh], une liste des paires (cle, valeur) qui ont méme code de hachage h
Une implémentation est la suivante
def creer_dico():
return [None] * HTAILLE # tableau de HTAILLE éléments
def ajouter_cle(dico, cle, valeur):
h = hachage(cle) H calculer le code de hachage de 1a clé
if dicofh] is None: # si L'entrée du dictionnaire est vide,
dicofh] = creer_liste() # l'initialiser avec une liste vide
4 insérer 1a paire (cle, valeur) en tte de 1a Liste des collisions
dico[h] = inserer(dicofh], (cle, valeur))
return dico
18def valeur_cle(dico, cle):
h = hachage(cle) # calculer le code de hachage de 1a clé
if dico[h] is None # si L'entrée du dictionnaire est vide
return None # one indique que 1a clé n'est pas présente
for c, v in elements liste(dico[h]): # parcaurir 1a Liste des collisions
if cle =e: # si 1a clé correspond
return v # retourner 1a valeur
return None # sinon la elé n'est pas dans Le dictionnaire
def cles_dico(dico):
ro # tableau des clés
for Liste in dico: # pour chaque élément du tableau
if Liste is not None: # s'il n'est pas vide
for cle, _ in elements_liste(Liste): # parcourir les collisions
teappend(cle) # ajauter la clé
return t # retourner Le tableau des clés
On peut utiliser le dictionnaire de la maniére suivante
dico = ereer_dico()
dico = ajouter_cle(dico, "Alice", 1234)
dico = ajouter_cle(dico, "Bob", 246)
dico = ajouter_cle(dico, "Charlie", 357)
valeur_cle(dico, "Bob") #246,
valeur_cle(dico, "Danny") # None car 1a clé n'est pas dans dico
for cle in cles_dico(dico):
print(cle, valeur_cle(dico, cle))
# "Bob", 246, "Alice", 1234, "Charlie", 357
La figure ci-contre
illustre le dictionnaire
correspondant (avec
HTATLLE=7). Le code
de hachage de Alice est
2,de méme que celui de
Bob, créant une collision
Celui de Charlie est 3.
fr{ (Bob, 236) |e fel Clice, 1254)
+e{ (Charlie, 357)
5.3. Etendre l'interface
On peut étendre I'interface d'un dictionnaire en autorisant le changement d'une
valeur associée a une clé et le retrait dune clé
+ de_presente(d, cle): accesseur qui retoume Vraisi la clé est dans le dictionnaire ;
+ changer_valeur(d, cle, valeur) : opérateur qui remplace la valeur de la clé, si
elle existe;
+ retirer_cle(d, cle) : opérateur qui retire la clé du dictionnaire, si elle existe.
En Python, ces opérations sont directement accessibles
+ dle_presente(d,cle):cle ind
+ changer_valeur(d, cle, valeur) :d[cle] = valeur
+ retirer_cle(d, cle) del d[cle]
Dans limplémentation par table de hachage illustrée plus haut, comme les listes
de collisions sont immuables, il faut recréer la nouvelle liste de collisions aprés avoir
change la valeur ou retiré la clé.
Limplémentation est laissée a titre d'exercice (n° 35).
(CHAPITRE 1 | STRUCTURER LES DONNEES
19eae
Un type abstrait est spécifié par une interface, constituée de:
+ Constructeurs, pour créer une nouvelle structure;
+ Opérateurs, pour modifier la structure ;
+ Accesseurs, pour obtenir de l'information surla structure ;
+ Itérateurs, pour énumérer les éléments de la structure
Plusieurs implémentations peuvent répondte a la méme spécification,
simplemente par AI Type aban
tse (_) simoementaton
ype de base
© Parcours d'exercices nn
Spécfier une structure de données parson interface
Distinguer interface etimnplémentation
ferireplusiurs implémentations dune méme structure de données
Distinguer des structures parle jeu des méthodes quiles caracteisent
hoi
une structure de données adaptée la situation a modéliser
20Choi
sir la (ou les) bonne(s) réponse(s)
Quelles affirmations sont vraies ?
| Linterface dun type abstrait est
indépendante de son implé mentation.
b| Limplémentation dun type abstrat est
indépendante de son interface.
La spéeification d'un type abstrait conceme
seulement son interface,
[| Vutilisation de types abstraits complique le
travail des programmeurs
Un type abstrait peut étre utilisé pour
implémenter un autre type abstait.
Associer chaque type d'opération 8 son réle.
Constructeur [1] Donner de information
surla steucture
b] Opérateur [2 | Modifier une structure
cl Accesseur [3] Enumérerles éléments
= de la structure
| térateur [4] créer une nouvelle
structure
Quel estle ble de chacune des opérations suivantes
sur une liste ?
a] liste_vide 1) Constructeur
‘b] queue Opérateur
créer_liste Itérateur
[2]
éléments_liste [3 | Accesseur
(4)
‘insérer
téte
Quels types de base peut-on utiliser pourimplémen-
teruneliste?
[a] Chatne de caractéres [¢ | Tableau
[ [d) Tuple
b| Dictionnaire
Réponses page 327.
Dans limplémentation d'une pile par une liste,
quelle est la correspondance entre les opérations
dela pileet celles de la liste ?
Pile Liste
a| sommet 1) insérer
b| empiter 2| téte
¢| dépiter 3| queue
Quelles affirmations sont vraies concernant une file ?
| Une file est une structure FIFO (first-in,
first-out).
Une file est une structure LIFO (last-in,
first-out)
[ ¢ | On peut implémenter une file par un tableau.
| On peut implémenter une file par une ple,
(On peut implémenter une file par deux piles.
On ajoute n éléments & une file vide, puis on retire
ensuite ces n éléments. Classer les trois implémen-
tations suivantes par ordre dlefficacité décroissante ?
a] Tableau simple
Tableau circulaire
Double pile
Quelle est la correspondance entre linterface d'un
dictionnaire et les instructions Python suivantes ?
[a] d=creer dicot) (1 dictey
_b ajouter(d, cle, val) (2 del dfcte}
c | valeur_cle(d, cle) (3) d=0
(d) cles dico(a) (4) dictel=val
[| cle_presente(d, cle) (5 | forclein
f
retirer_cle(d, cle)
(6) cleind
CHAPITRE 1 | STRUCTURERLES DoNNEeS 21.TRAVAUH PRATIQUES
0 Simulation de file d'attente
Les files d’attente sont un domaine largement étudié en informatique. Quil s'agisse de déterminer le nombre
de caisses 8 ouvrir dans un magasin ou le nombre d'antennes téléphoniques & installer dans une ville, la théo-
rie des files d'attente fournit des outils mathématiques puissants. On utilise souvent dessimulations de files
dattente afin d’étudier le comportement d'un systéme selon différentes hypothases,
p |mplémenter une file
On simule une simple file d'attente d'un magasin, avec une seule caisse, Comme on I'a vu dans le cours, une
file est caractérisée par deux opérations principales :enfiler, qui ajoute un élément la fin de lafile, et défiler,
qui retire élément en téte de file. Bien sdr, on ne peut pas retirer d'élément si la file est vide. Diautre part,
beaucoup de files d'attente ont une capacité limitée : on ne peut alors ajouter délément sila fle est pleine
1. Spécifier l'interface d'une file d’attente a capacité limitée.
2. Ecrire 'implémentation de la file par un tableau circulaire et la tester.
=p Créer la simulation
Pour simuler le comportement d'une file d'attente, on découpe le temips en tranches (appeléesunités de temps
0u pas) et on détermine ce qui se passe & chaque pas. Ici, chaque pas, des clients peuvent arriver dans la file,
tandis que le caissier traite le client en cours sil en a un, ou prend un nouveau client sil est libre et que la file
diattente n’est pas vide. La simulation est caractérisée par trois paramétres
+ la capacité de la file d'attente :5i un client arrive et que la file est pleine, il part, mécontent;
+ le flux moyen d'arrivée de nouveaux clients (nombre moyen d'arrivées par unité de temps) ;
+ le nombre moyen d’achats de chaque client, qui détermine le temps de traitement en caisse.
ab, Télécharger les fichiers du TP. Lois . py contient trois fonctions permettant de simuler les arrivées
aléatoires dans a file: init_lois(flux, articles) initialise le générateur aléatoire avec le nombre
moyen dartivées par unité de temps et le nombre moyen diarticles par client ;nb_arrivees() retourne un
nombre aléatoire diarrivées par unité de temps ;nb_articles() retourne un nombre aléatoire d’articles.
1. Etudier le fichier magas‘in. py et le compléter afin d’implémenter la simulation.
2. Visualiser la simulation en décommentant les deux derniéres lignes demagas‘[Link].
Représentation de état de la simulation, La barre verte représente le nombre darticles
restant a traiter par le caissier Les barres bleues représentent les clients dans la file dattente,
Ia hauteur de la barre représentant leur nombre dachats
B® Instrumenter la simulation
Pour avoir une idée du comportement de la simulation, on souhaite collecter les informations suivantes et les,
afficher a lissue de la simulation
+ le nombre de clients qui ont été servis;
+ lenombre de clients mécontents
+ lenombre dunités de temps ott la caisse était vide ;
+ lalongueur moyenne de la file d'attente.
221. Spécifier un type abstrait Stats permettant de représenter et mettre a jour ces informations.
2. Choi
3. Modifier le programme en uti
afficher a la fin de l'exécution.
ir une structure de données et implémenter ce type abstrait.
ant une variable globale stats pour collecter ces données et les.
xp Etudier le comportement de la simulation
Comme la simulation repose sur la génération aléatoire des arrivées des clients et de leurs nambres d’achats,
‘on veut exécuter la simulation de nombreuses fois et visualiser les distributions des données ci-dessus.
Nombre de clients servis Nombre de clients mécantents __Durée caisce libre Longueur moyenne de la fle
500 250
uo 20.
8, 400 200
300 oo
200. 150
0
40
60 200 100
. 100 50 20
0
° ° 6 °
Distribution des données colectées pour 1000 simulations de 500 pas avec les paramétres suivants:
capacté dea file dattente = 20; fluxde nouveaux clients = 08 par pas de temps; nombre moyen dachats par cient = 3
1. Spécifier un type abstrait Multistats permettant de collecter les données ci-dessus pour chaque
simulation, sous forme de listes.
2. Quelle impémentation de liste choisir pour représenter ces séries de valeurs ?
3. Implémenter ce type abstrait et écrire un programme qui répete une simulation fois, collecte les
données dans une variable mult istats et les affiche sous forme d’histogrammes avec la fonction
affiche_histogrammes du fichier plots. py.
4. Commenter ces résultats.
@m Etudier la sensibilité aux paramétres
Ce qui intéresse le modélisateur est de voir comment ces statistiques sont sensibles aux trois paramétres.
1. Ajouter a l'interface du type abstrait Multistats une opération qui calcule la valeur moyenne de
chacune des données collectées.
2. Modifier le programme pour exécuterm ensembles de n simulations en variant la valeur d'un des
paramétres et collecter dans quatre tableaux les valeurs moyennes de chaque ensemble. Les afficher
avec la fonction af fiche_moyennes du fichier plots. py.
Nombre de clients servis Nombre de clients mécontents __Durée caisse libre Longueur moyenne de la file
ws
ae 20 ir
100 ii 15.0
wo ns as
©. o 100 hoo
1 1s
“0
“ 50. 50)
20 20 2 25
° ° ° oo
cede vo a2 “os os av 2 “oe oa a0 t2°"Gs oe a0 a2
Evolution des statistiques lorsque le flux passe de 0.6 4 1.2
CHAPITRE 1 | STRUCTURER LES DoNNEES 23te EXERCICES NEWBIE
aby Plusieurs exercices ut
‘vues en cours :
+ Liste_tuple. py: implémentation d’une
par des tuples (section 2.1)
+ pile_tabLeau . py:implémentation d'une pile
par un tableau (section 3.2);
+ dico_tabLeau. py: implémentation d'un dic-
tionnaire par une table de hachage (section 5.2).
Dans tous les exercices oi on demande de coder une
implémentation, celle-ci doit étre validée par des tests
de chacune des fonctions, en testant les cas normaux
(inséreren téte deliste, etc.) etles cas limites ou devant
provoquer des erreurs (liste vide, etc.)
B® a écrive une fonction qui retourne une liste
privée des éléments d’une valeur donnée v en utilisant
uniquement les opérations de linterface d'une liste
(section 2 du cours).
b. _ Eecrire une fonction qui épare les éléments d'une liste
en deux lstes selon qu’ils sont inférieurs ou supériewrs &
une valeur v,
1a. Coderen Python les opérations de interface d'une
liste (section 2du cours) en utlsant un tableau de tale fixe
de 10 éléments.
b. Dans quel ordre a-t-on intérét ranger les éléments de
laliste dans le tableau ?
& Comment gérer le cas oi le tableau est plein?
ED a. coder les opérations suivantes de I'inter-
face étendue des listes (section 23 du cours) avec
Timplémentation de lexercice précédent taille, jeme,
ajouter_fin, remplacer.
b. Compléter limplémentation avec les opérations
‘inserer_ieme el suppr-imer_ieme,
(4) ©& auelest rérat de la pile & chaque étape de ce
programme?
p = creer_pile()
for v in [2, 4, 3, 6, 8, 5, 7, 18, 1]
if v82== 0:
p= empiler(p, v)
else:
p= depiler(p)
Ba implementer une pile par une liste en utilisant
uniquement ies fonctions de interface d'une liste présen-
t€es dans le cours (section 3)
b. hy Tester ce code avec les deux implémentations
lune liste : par des tuples (Liste_tupLe..py),ou par
un tableau (exercice 2).
24
(6) [Link]éter interface d'une pile par une opération
permettant dobtenir sa all et une opération permettant
obtenir son -éme élément (a partir du some),
b. implémenter ces deux fonctions en utilisant unique-
ment les autres opérations de Vinterface d'une pile,
. hy Tester ces fonctions avec limplémentation vue
en cours (pile_tableau. py).
4d. Ces implémentations sont-elles efficaces ?
© [Link] une fonction qui prend une fle en para-
metre ransfere son contenu dans une pile, puis transfere
le contenu de la pile vers lle et renvoie cele
b. Quelest leffet de cette fonction surla file?
8) a. Compléter limplémentation d'une file par un
tableau vue en cours (section 4)
b. Sifonajoutem éléments dans|a file puis qu‘on les rete,
combien d’éléments auront été recopiés dans le tableau?
BD a. coder rimplsmentation d'une file par un tableau
cculare tele que décrte dans le cours (section 42)
b. Ajouter une implémentation de l'opération
taille () qui retourne le nombre d’élémnents de lie
BD a. coder implémentation d'une file par deux piles
relle que décrite dans le cours (section 4.3)
b. Ajouter une implémentation de l'opération
taille (F) qui retourne le nombre d'éléments de lafile.
uw ® On appelle chaine dans un dictionnaire d une
série de clés ;,....Cotelles que la valeur associée & chaque
clé est elleméme une clé: fe] = Gu.
+ Ectire une fonction qui prend un dictionnaire et une cle
Cen parametres et retoure la demiére clé de la chaine
commengant par c
[Link]émenter un dictionnaire par une liste comme
décrt dans le cours (section 5), en utilisant uniquement les
fonctions de linterface dune liste (ection 2)
b. By Tester cette implémentation avec les deuximplé-
mentations d'une liste : par des tuples (Liste_tuple.
Py) et par un tableau (exercice 2)
aby a. Utliserimplémentation d'un dictionnaire par
une table de hachage vue en cours (di co_tableau.
Py) pour créer un répertaire des départements associant
leur nom & leur population, & partir du fichier CSV pop_
dept. csv.
b. Enutlisant une table de 100 entrées, combien a-ton de
collisions ? Mame question avec une table de 200 entrées.aw an
(
‘a, Comparer les interfaces des types abstrats Liste,
Pile et File, Quelles sont les similarités et les diférences ?
b. Lexpression tete(inserer(1, e)) == est un
invariant, Cest-2-dire quielle est toujours vraie quelle que
soitla liste L.¥ a-tildes invariants similaires pour les types
abstraits Pile et File ?
Donner un invariant du type abstrait Dictionnaire.
(15) Tableaux et tableaux dynamiques
a. Spécifier le type abstrait d'un tableau de taille fixe. On
appellera lopération d'accés a un élément get et opéra-
tion permettant de changer la valeur dun élément set.
b. Implémenter ce type abstiat par un tableau Python,
& Spécifierle type abstrat d'un tableau dynamique, 'est-
a-dire un tableau dont on peut changer la taille aprés sa
création afin de lagrandir ou de le réduire
d. Implémenter le tableau dynamique par un tableau
Python et fopération de changement de taille en recopiant
le tableau dans un nouveau tableau. On n'utilisera pas les
méthodes append et pop des tableaux Python,
. Modifier limplémentation de lopération set de telle
sorte que le tableau s‘agrandisse automatiquement sion
affecte un élément dindice supérieur a sa taille,
tableaux dynamiques Python
Les tableaux Python sont des tableaux dynemiques : leur
tall peut tre modfige aveclesméthodes t «append (e)
(gjout diun élément afin) ett. pop() (etrait du dernier
élément)
a. Spécifier le type abstrait d'un tableau dynamique avec
ces deux opérations,
b. Implémenter ce type abstrait par un tableau de taille
fixe, en recopiant le tableau lorsquil change de taille.
Modifier implémentation pour réduire le nombre de
fois ou l'on doit recopier le tableau : A la création, on
alloue un tableau plus grand que la taille demandée, de
telle sorte que l'on puisse ajouter des éléments sans reco-
pier le tableau, Lorsque l'on doit agrandir le tableau, on
double sa taille. A inverse, lorsque le tableau est aux 2/3
inutilisé (apres le retrait d'éléments), on diminue sa taille
de mot
Tranches de tableau
On appelle une tranche de tableau une structure de
données qui représente une partie d'un tableau. Ain, la
tranche s = tranche(t, 10, 20) d'un tableau t de
100 éléments représente les éléments ciindice 108 19.s
se comporte comme un tableau de 10 éléments, dindices
089:get(s, ©) == t[10]. Lorsque fon modifie un
élément de s, par exemple 'élément dindice 0, élément
correspondant de t, ici t [1] est modifié,
a. Spécifier le type abstrait Tranche de telle sorte quill
resemble au type abstrait Tableau.
b. lnplémenter ce type abstiait en Python,
© Modifier fimpiémentation afin quil soit possible de
créer une tranche & partird'une autre tranche et pas seule-
ment d'un tableau.
{© implementation dune liste par un tableau
dynamique
‘a. Modifier limplémentation d'une liste par un tableau
(exercice 2), en recopiant la liste dans un tableau de taille
double lorsque nécessaire. On n‘utlsera pas la méthode
Python t. append.
b. Compléter lmplémentation pour réduire la taille du
tableau lorsque le nombre d'éléments de la liste est infé-
rieur & la moitié de la taille du tableau.
B_imptementation a’une liste par un tableau dyna-
mique Python
‘a. Implémenter une liste par un tableau Python en utii-
sant les méthodes append et pop.
b. Comparer cette implémentation & celle du cours
(ection 2.1),
BD performance des implémentations de liste
On considére trois implémentations de la liste: par des
tuples (yue en cous, section 2.1), par un tableau dyna-
mique (exercice 18) et por un tableauPython (exercce 19).
a. fcrire un programme qui crée une liste et effectue
100.000 fois fopération suivante :tier un nombre au hasard
entre -20 et +20. Sin est posit, insérer dans la liste les
valeurs de 11; sin est négatif,effectuer n fois lopération
L= queue (L) (ne rien faire sila liste est vide)
b. Mesurer le temps d’exécution du programme avec
chacune des trois implémentations. Que conclure sur ref
ficacité de chaque implémentation ?
Rappel : La bibliothéque Python random contient la
fonction randint (min, max) qui retoure un entier
aléatoire entre min et max (inclus).La biblioth&que time
contient a fonction process_time() qui retourne le
temps de calcul depuis le début du programme.
CHAPITRE 1 | STRUCTURERLES Données 25aaa an
(
Inversion et concaténation de liste
a. Spécifier une opération qui inverse une liste, Cest-dire
qui renvoie une liste avec les mémes éléments dans ordre
inverse,
b. Implémenter cette opération en utilisant uniquement
les opérations de linterface de base d'une liste
&Spécifier une opération qui concaténe deux lstes, Cest-
dire qui renvole une liste constituée des éléments de la
premiere liste suivis des éléments de la deuxiéme liste,
. Impiémenter cette opération en utilisant uniquement
les operations de linterface de base d'une liste et, si besoin,
Hinversion d'une liste
@. Peut-on implémenter cette opération de facon plus
efficace lorsque la liste est implémentée par un tableau ?
Aliassage et structures de données muables
a. Que doit afficher le programme suivant ?
U1 = creer_liste()
11 = inserer_Liste(11, "Alice")
12 = inserer_liste(11, "Bob")
U1 = inserer_liste(11, "Charlie")
print("11 =", elements Liste(11))
print("12 =", elements_liste(12))
b. Quiffiche-til lorsque l'on utilise limplémentation
une liste par des tuples ? Et lorsque 'on utilise limplé-
mentation par un tableau Python de l'exercice 19 ?
. Expliquerla raison de la diférence de résultats,
. Corriger limplémentation défaillante pour obtenit le
bon résultat.
e. Est-ce que cette modification rend limplémentation
plus ou moins performante ? On pourra reprendre Vexer-
cice 20 avec cette implémentation modifiée.
Implémentation de linterface étendue d'une liste
a. Implémenter les opérations taille, ieme,
ajouter_fin et remplacer de interface étendue
cdlune liste dans limplé mentation par des tuples.
b. Compléter par I'implémentation des opérations
‘inserer_ieme et supprimer_ieme
& Que peut-on dire de leur efficacité par rapport aux
implementations par un tableau (exercice 3).
(24 Liste a capacité limitée
a. Modifier Vinterface d'une liste pour intégrer une capa-
ité limitée, comme dans Yexemple de la pile wu dans le
cours (section 32)
b. Modifier limplémentation par tuple en consequence.
26
BB Pite mystare
a. Que fait la fonction suivante ?
def mystere(p)
p2 = creer_pile()
n= taille_pile(p)
for i in range(n-1, 0, -1
t = somnet (p)
p = depiler(p)
for j_in range(i):
p2 = empiler(p2, sonmet(p))
p = depiler(p)
p = empiler(p, t)
for j in range(i):
p= enpiler(p, sonmet (p2))
p2 = depiter(p2)
return p
b. lmplémenter cette fonction de maniére plus simple
EB _ implementation d'une file par un tableau glissant
a. Modifier limpiémentation d'une file par un tableau
circulatre (section 4.2 du cours) de facon a éviter que la file
soit coupée en deux parties.
Pour cela, on recopie la fle au début du tableau lorsque
son dernier élément arrive a la fin du tableau.
b. On considére une file de n éléments dans un tableau
de m éléments, On alterne les appels 4 enfiler et
défiler.
Au bout de combien d’opérations a lieu la recopie ?
Comparer avec limplémentation par un tableau simple
Gection 4.1 du cours).
Implémentations d'une file par des tableaux
dynamiques
Modifier les implementations dune file par un tableau de
taille fixe et par un tableau circulire exercices 8 et 9) pour
recopier la fle dans un tableau plus grand ou plus petit
selon sa taille et s'affranchir ainsi dela capaciélimitée de
lafle
implementation d’une file par une double pile
a. implémenter une file par une double pile selon le prin-
cipe décrt dans le cours (section 43)
b. Vérifier que cette implémentation fonctionne avec
des piles implémentées par des tuples ou bien par des
tableaux
€. On considere une file de den éléments, On alterne les
appels a enfiler et défi Ler. Au bout de combien
dopérations a lieu la recopie d'une pile & fautre ? Comparer
avec lexercice 26.aw an
Implémentation d'une file par une liste
a. En utilisant interface étendiue dune liste vue en cours
(ection 23), implémenter une fleet la tester avec plusieurs
implementations de cette liste.
b. Quelle implémentation est a plus efficace ?
ED) performance des implémentations de file
On considére trois implémentations d'une file: par un
tableau dynamique, par un tableau citculsire dynamique
expar une double pile,
a. Prédire quelle implémentation est la plus efficace et
quelle implémentation est la moins efficace lorsque on
ajoute et lon retire des éléments de maniére aléatoire,
comme dans lexercice 20.
b. Ecrire un programme similaire a lexercice 20 et
Vexécuter pour mesurer les performances des trois
implémentations
Les résultats confirment ils vos prédictions ?
File avec priorité
Une file avec prioité est une file normale avec une opéra-
tion supplémentaie:enfiler_priorite(f, e), qui
ajoute e 8 lafile F devant tous [es éléments sans pririté
mais derive tous ceux avec priorté
a Une premiére implémentation utilise un tableau de
taille fixe dans lequel les éléments sont des paires (e p)
ol pest un booléen indiquant si e est prioritaire
Coder cette implémentation.
b. Une seconde implémentation utilise deux files: la file
normale et la file des éléments priontaires.
Coder cette implémentation.
& Comparer les deux implémentations,
EB suite «look-and-say » de Conway
La suite « look-and-say » (aussi appelée « commentaire
numérique ») due au mathématicien etinformaticien John
Conway, consiste lire & haute voix une série de chiffres en
les groupant :ainsila suite 11121223 est lue « trois 1,un 2,
Un 1, deux 2, un trois », que lon éerit 3112112213.
a. Ecrite une fonction etape qui prend deux files,
entreeet sortie, ct effectue une étape du traitement,
en retirant les n premiers chiffres identiques ¢ de la file
entree et en ajoutant es chitfres net 8 sortie
b. Ecrire une fonction look_and_say qui prend une
file et retourne la file transformée.
Afficher les 10 premiéres valeurs de la suite « look-and-
say > partir dune file contenant seulement un 1
Implémentation d’un dictionnaire par un tableau
ti
Siles clés d'un dietionnaie, par exemple des chaines de
caracteres, peuvent etre comparées, on peut ameéliorer m=
plémentation dun dictionnaire par une liste en utilisant &
laplace un tableau tré dans ordre des clés, et en utilisant
la recherche dichotomique pour ajouter une entrée dans
le dctionnaire et pour rechercher une entrée par sacl
a. implémenter un dictionnaire par un tableau tié par
ordre de clé
b. Comparer ia performance de cette implémentation &
limplémentation par une liste simple et limplémentation
par un dictionnaire Python.
54 Ajout de clé dans un dictionnaire
Liimplémentation de la fonction ajouter_cle dans le
cours (section 5.2) ne vérifie pas si la clé est déja présente
dans ledictionnaire
a. Que se passe-til si an ajoute une clé qui est déja
présente ? Quelle valeur retournera valeur _cle pour
cette clé ? Est-ce le résultat attendu ?
b. Que retournera cLes_dico si une clé a été ajoutée
plusieurs fois ? Est-ce le résultat attendu ?
¢. Modifier limplémentation de aj outer_cle pour
comtiger ce probleme.
EB interface étendue d'un dictionnai
Implémenter interface étendue d'un dictionnaire (section
5.) implémenté par une table de hachage
+ test de présence dune clé
+ reurait dune clé;
+ modification de la valeur associée a une clé.
EB. type abstrait Ensemble
a, Défnir interface dun type abstaitreprésentant un
ensemble déléments:un ensemble ne peut pas contenir
le méme élément plus d'une fois.
b. Coder une implémentation par un dictionnaire.
Coder une implémentation par un tableau dans le cas,
oii es elements de ensemble sont des enters posits ou
nul entreo et 100
d._Définir les opérations d'union et d'intersection et les
implémenter en utilisant uniquement les opérations de
base de interface,
e. Coder les opérations d’union et d'intersec-
tion de maniére optimisée pour chacune des deux
implémentations.
CHAPITRE 1 | STRUCTURERLES DoNNEES 27aaa an
(
Type abstrait Multi-ensemble
Un mult-enserble (aussi appelé « sac») est un ensemble
dans lequel chaque élément peut apparaitre plusieurs fois,
a. Peut-on garder la méme interface que pour le type
abstrait Ensemble de lexercice 36 ?
b. Modifier les deuximplémentations delexercice 36 pour
implémenter un mult-ensemble au lieu d'un ensemble
simple.
Fenétre et moyenne glissante
Une fenétre est une structure de données qui garde en
mémoire un nombre fixe de valeurs et permet de calculer
leur moyenne. Lorsqu'une nouvelle donnée est ajoutée &
la fenétre, si celle-ci est pleine, la donnée la plus ancienne
est retire.
Cette structure de données permet de calculer une
moyenne glssante, cest-a-dire de remplacer une série de
données par la moyenne autour de chaque point, comme
ilustré dans la figure ci-dessous, oti la moyenne glissante
(en orange] lisse la courbe des données (en bleu).
4000:
3000.
2000:
2000
° 100 200 300 “400
Nombre d'hospitatisations dues au COVID-19
de mars 20204 juin 2021
a. Spécifierle type abstrait Fenétre,
b. Quel type abstrait du cours est le plus adapté a repré-
senter une fenétre ? Quelle implémentation de ce type
abstrait est la plus appropriée ?
c Coder la fenétre en utilisant cette implémentation.
d._ Sila fenétre est de longueur n et que sa moyenne est
M, quelle est la valeur de la moyenne aprés avoir ajouté
une nouvelle donnée d a la fenétre, sachant que la valeur
sortante est s?
Utiliser cette formule pour calculer la moyenne de la
fenétre de maniére efficace.
bs On pourra utiliser le tableau de données dans le
fichier moyenne_glissante.py pour reproduire
exemple de la figure.
28
39 Historique du navigateur Web
Uistorique du navigateur Web enregistre adresse de
chaque page que Von visite et permet de revenir 8 une
page antérieure. Si fon est revenu en arriére dans 'his-
Torique, on peut repartir en avant si fon r’a pas navigué
entre-temps vers une nouvelle page.
a. Spécifier interface du type abstrait décrivant
Historique
b. Implémenter cette interface en utilisant les structures
de données Liste, Pile e/ou File,
& Implémenter cette interface de maniére « native », en
utilisant directement un tableau Python
© tortue
a. Spécifier interface des principales fonctions de la
tortue Python : avancer, reculer, tourner, lever/balsser le
crayon.
b Quelle structure de données est la plus adaptée pour
implémenter ces opérations ? On pourra utiliser les struc-
tures de données de géomeéttie de Factivité dintroduction.
On rappelle que le résultat de la translation d'un point de
coordonnées (x y) dlune distance d selon un angle a (en
radians) est le point de coordonnées (x + d costal, y +d
sin(a))
aby Implémenter le type abstrait Tortue sans utiliser
les fonctions de la tortue standard de Python. On utilisera
Ia fonction trait de la bibliothéque dessin. py de
lactivité d'introduction pour dessiner la trajectoire de la
tortue
® agenda
Un agenda permet d’associer des actions (réunion, cours,
rendez-vous, etc) des dates et heures données, avec une
durée donnée. Une action peut &tre prograrnmée pour
un jour donné, et dans ce cas elle doit avoir une heure
de début et de fin, ou bien pour une période de plusieurs
jours, et dans ce cas elle doit avoir une date de début et
Une date de fin (mais pas dheure).
‘a, Spécifier interface du type abstrait Agenda de telle
sorte que lon puisse créer des actions, les supprimer, et
obtenir la liste des actions d’une date donnée. On pourra
définir autres types abstraits si nécessair.
b. Quelles structures de données sontles plus appropriées
pour implémenter eficacement'agenda et les autres types
abstraits éventuels ?
c._Ectire le pseudo-code des opérations de création dune
action, de suppression d'une action, et de recherche des
actions d'une date donnée,EXERCICES TITAN
«
Notes des éléves d'une classe
Pe ea
ree) Py
Afin de gérer les notes des éléves d'une classe, on veut
définir un type abstrait qui peimettra les operations
suivantes
+ le professeur principal doit pouvoir définir Pensemble
des élaves de la classe et Vensemble des matiéres ;
+ chaque professeur doit pouvoir entrer les notes de
cchacun des éleves dans sa matiere, et calculer la moyenne
de sa classe ;
+ le professeur principal doit pouvoir calculerla moyenne
de chaque éléve en vue du conseil de classe.
a. Spécifier interface du type abstrait Classe.
b. Quelle structure de données est adaptée 8 ce
probleme ? Discuter les avantages et inconvénients de
différentes possibiltés.
Choisir une implémentation et la coder.
Histogramme
Un histogramme de fréquence est une structure de
onnées qui compte le nombre de fois que chaque valeur
dun ensemble de données est ajoutée a I'histogramme,
Par exemple, Ihistograrime de fréquence de la série (1,0,
2,2,0, 1,1, 2,4, 2) vaut 2 pour la valeur 0 (car 0 apparait
2 fois), 3 pourla valeur 1,4 pour la valeur 2,0 pour la valeur
3 et 1 pourla valeur 4.
a. Définir interface d'un type abstrait décrivant un histo-
gramme de fréquence
b. Choisir une structure de données appropriée pour son
implémentation. Ce choix convient-i siles valeurs de len-
semble de données ne sont pas des nombres mais, par
exemple, des chaines de caractéres :(Alice, Bob’, Charlie’,
‘Alice’, Charlie’ ‘Alice
Coder implémentation choisie.
._ Ajouter interface une opération permettant dafficher
Ihistogramme 8 l'aide du code suivant
‘import [Link] as plt
# x= Le tableau Python des valeurs de 1'ensenble
[0, 1, 2, 3, 4] # pour L'exenple ci-dessus
# y= Le tableau des fréquences correspondantes
y= [2, 3, 4, 6, 1] # pour L'exemple ci-dessus
plt-bar(x, y)
[Link]()
Liste chainée dans un tableau
Lorsque on implémente lnterface étendue d'une liste par
Un tableau, les fonctions qui implémentent les opérations
‘inserer_iemeet supprimer_ieme doivent décaler
les éléments du tableau afin de faire de la place pour line
sertion ou pour « boucher le trou» créé par la suppression.
Cette opération est codteuse sila liste est trés longue.
Une autre approche consiste & stocker dans le tableau des
couples (valeur, suivant) 00 valeurestla valeur de élément
de liste et suivant est Vindice dans le tableau de élément
suivant, ou -1 si c'est le dernier élément de la liste. Le
début de la liste (sa tte] est repéré par indice de son
premier élément. Vimage suivante ilustre une représen-
tation possible de la liste (Alice, Bob, Charlie) avec cette
méthode. Les case vides peuvent étre utilisées pour rece-
voir de nouveaux éléments de la liste,
a
0 1 2 3 4 s
‘a._Implémenter linterface de base d'une liste avec cette
structure de données,
b. Implémenter les opérations suivantes de linterface
étendue: deme, insérer_iéme, supprimer.
_implémenter linversion d'une liste (voir exercice 21) de
telle sorte que chaque élément reste dans la méme case
du tableau,
GB dachage séquentiel
Il existe de nombreuses facons de gérer les collisions
dans une table de hachage. La méthode vue en cours,
Gection 5.2) utile une liste contenant es clés ayant méme
code de hachage. Une autre approche consiste 8 trouver
tne case libre dans la table de hachage en parcourant
celle-i a partir du code de hachage de la clé
‘Ainsisil'on veut ajouter le couple (té valeur), dont le code
de hachage est code, et si élément elcode) de la table
est occupé, on regarde tlcade+ ), icede+2), ete. jusqu’s
trouver une case libre, et on range le couple (le valeur)
dans cette case
a. Implémenter l'opération ajouter avec cette
méthode.
b. Comment doit fanctionner|'opération valeur_cle
qui recherche une clé ? Implémenter votre solution.
‘& Comparer cette implémentation & celle vue en cours
avec une liste de collisions. Quels sont les avantages et
inconvénients de chaque méthode ?
._ Esti possible d'implémenter le retrait dune clé avec
cette méthode?
CHAPITRE 1 | STRUCTURERLES Données 29inet
Le pitch
Les langages & objets ont uu le jour dans les années 60, en méme temps que les
autres grandes catégories de langages de haut niveau, mais n'ont commencé
a simposer dans l'industrie qu'a partir des années 90.
Le premier langage & objets s‘appelait SIMULA et son but était de simuler des
processus physiques. Il était donc nécessaire de représenter les objets de la
simulation, par exemple les éléments d'un systéme mécanique, leur état, par
exemple leur poids, leur position et leur vitesse, ainsi que leurs comportement,
par exemple pour calculer leur trajectoire.
Au lieu de définir séparément une structure de données et les fonctions permet-
tant de la manipuler, les objets permettent de définir ensemble leur structure
de données et leur comportement en une seule entité, appelée classe. Cette
approche facilite la lisibilité et la modularité des programmes.
Ce chapitre présente les principes de base de la programmation par objets et
leur mise en ceuure dans le langage Python.TEST
© Lees sont ies expressions valides en Python apres ces affectations ?
z
te
z
é 10, 'y': 20, z: 30}
a) di} b) di) =) dd) ee) tx) tz)
@ uae estla vateurattichée parce programme?
t = (10, 20, 30)
set
ti} =2
print(s[1])
a) 10
b) 20
ot
ad) 2
6 Quelles sont les valeurs affichées par ce programme ?
def mystere(p):
pl'x'] = 100
return p
p= {'x': 10, 'y': 20}
p2 = mystere(p)
print(p['x'], p2{'x"])
a) 10,20
b) 10,10
©) 10,100
d) 100,10
e) 100, 100
© Lu2KIes affimations sont conectes ?
1) Lexpression [Link]()
a) trie le contenu du tableau t par ordre croissant.
b)retourne un tableau avec les éléments de t triés par ordre croissant.
2) Lexpression t. append (10)
a) ajoute 'élément 10 alain du tableau t.
bb) retourne une copie du tableau avec élément 10 ajouté 8 la fin
Réponses page 330.
CCHAPITRE2 | PROGREMMATION PAR OBJETS
31Fal
f=]
=]
sy
o
=]
a
o
4
=
z
tal
A
Lu
=
=
=)
Ec
oO
<
32
La pluie de projectiles
OBJECTIF Simuler la trajectoire de projectiles soumis la gravité
Pour simuler la trajectoire d'un projectile que 'on lance en fair avec une certaine vitesse et
quiest soumis a la gravité, on a besoin de connaitre sa position x, y et sa vitesse vs, vy. Apres
un intervalle de temps dt, la position et la vitesse du projectile sont madifiges comme suit
+ xsutdixu j yaytatxy;
+ we=w-gxat ou g estlintensité de la pesanteur (9,81 m/s? sur Terre),
Pour représenter le projectile, nous allons utiliser un nouveau type de données : unobjet, Pour
créer un objet représentant un projectile i faut d‘abord définir uneclasse, que lon appelle ici
Projectile. La fonction ProjectiLe() retourne alors un nouvel objet, qui est comme une
coquille vide. On peut ensuite « remplir » cette coquille avec lesattributs qui représentent
état du projectile icix, y, vx et vy, que lon accéde par la notation pointée =
class Projectile: # declarer une classe
= i,
x=0
balle = Projectile() — # créer un objet =H
balle.x = 0 # affecter son attribut x,
balle.y = 0 # son attribut y, vx=10
[Link] = 10 # son attribut vx, vy=20
'
[Link] = 20
et son attribut vy
1. Ecrire la fonction pas (bal le, dt) qui prend une balle en paramétre et modifie son
état apras l'intervalle de temps dt.
2. Ecrire un programme qui crée une balle et appelle répétitivement la fonctionpas en
affichant la position de la bale.
Modifier la fonction pas pour qu’elle affiche la trajectoire dela balle en dessinant un
trait depuis sa derniére position. On utilisera la bibliotheque tur tLe et la fonction
goto(x,y) qui déplace la tortue a la position x, yen tracant un trait.
La fonction pas n’a de sens que sion lui passe un projectile comme premier paramétre. Pour
rendre cela explicite, on peut la définird Fintérieur de la classe Projectile. On dit que l'on
deéfinit la méthode pas dela classe Projectile. Aulieu d'appeler a fonction pas(balle,
dt), on utilise la notation pointée pour appeler cette méthode :balle. pas (dt)
class Projectile:
def pas(self, dt): # définir La méthode ‘pas‘ dans 1a classe ‘Projectile’
a # ‘self’ est Uobjet pour lequel on a appelé 1a méthode
[Link](dt) # appeler 1a méthode ‘pas* pour l'objet ‘bale’
4, Modifier le programme précédent pour définir la fonction pas sous forme d’une
méthode de la classe Projectile.
5. Modifier la méthode pas pour programmer le rebond sur le sol : sila coordonnéey
du projectile devient négative, on inverse la vitesse verticalevy.
6. Modifier le programme pour créer plusieurs balles avec des positions et des vitesses
initiales différentes et lancer la simulation en appelant répétitivement la méthode
pas de chaque balle a tour de réle.Le ballet des tortues
OBJECTIF Utiliser la classe d'objets Turtle de la bibliothéque Python turtle.
La bibliotheque Python turtle est le plus souvent utiisée avec les fonctions forward,
backward, Left, etc. qui permettent de dessiner avec une tortue, Cependant la biblioth&que
permet de manipuler plusieurs tortues simultanément grace a la classe Turtle
from turtle import Turtle
romeo = Turtle() # eréer 1a tortue
juliette = Turtle() # créer 1a tortue
"romeo"
juliette”
[Link]("blue’) i changer 1a couleur de roneo
[Link](*red’) # changer 1a couleur de juliette
romeo. right (98) ¥ tourner romeo de 98 degrés
[Link](1@0) — avancer romeo de 108 pas
[Link](188) # avancer juliette de 198 pas
1. En utilisant la fonction randint (min, max) dela biblioth&que random qui retourne
un nombre aléatoire entre min et max, écrire un programme qui fait déplacer les
deux tortues ci-dessus de maniére aléatoire.
2, Modifier le programme pour que les deux tortues suivent une trajectoire aléatoire
miroir 'une de l'autre : lorsque l'une tourne a droite, l'autre tourne a gauche, et
inversement.
On veut maintenant réaliser un ballet de tortues. On définit la classe suivante
class Ballet:
def init(self, n):
""" Initialise un ballet den tortues et les orienter radialement "*"
[Link] = [Turtle() for i in range(n)] # un tableau de n tortues
for i in range(n):
[Link][i].left(i * 360/n) # orienter chaque tortue
ballet = Ballet() # créer un ballet
[Link](8) # L'initialiser avec 8 tortues
3. Définir les méthodes avance, droite et
gauche dans la classe Ballet qui font N
avancer ou tourner toutes les tortues du '
ballet.
Définir la méthode danse dans la classe
Ballet qui appelle ces méthodes pour :
exécuter un pas de danse aléatoire et
identique pour tout le corps de ballet.
5. Ecrire un programme qui fait danser le
ballet de8 tortues, puis ajouter un pas de
deux (un ballet de deux danseurs) pour
créer un ballet numérique complet.
CHAPITRE2 | PROGREMMATION PaROSETS — BBDy) yea cat Lay
Imaginons une application numérique demandant [utilisation de points repérés
par des coordannées dans un repére. Pour définir un point, nous avons besoin
d’au moins 2 informations :les coordonnées. ety de ce point. Par ailleurs, un point
pourra également subir des transformations géométriques, comme par exemple
des translations ou des symétries
Nous avons wu en premiere des types structurés qui permettent de stocker plusieurs
informations relatives & un méme « objet » numérique. Ainsi, on pourrait représenter
un point par un tuple (x, y), un tableau [x, y], ou un dictionnaire {"x": x 5
Dans ce chapitre, nous allons voir qui est également possible de stocker ces infor-
mations dans une nouvelle structure de données appelée objet.
Un objet contient un ensemble dttributs qui ont chacun une valeur, un peu
comme dans un dictionnaire. On accéde aux attributs d'un objet par lanotation
pointée: obj. attr est la valeur de lattribut attr de objet obj,
Par exemple, un point de espace & deux dimensions peut étre représenté par un
objet avec deux attributs x et [Link] p est un tel objet, on peut accéder & ses attributs
[Link] psy.
Pour créer des objets, on a besoin de définir une classe. La définition la plus simple
est la suivante :
class Point:
pass
Une fois la classe définie, on peut créer desinstances de la classe en utilisant le nom
de la classe comme une fonction :
oint() —# créer un nouvel objet, dénoté par pl
pl.x = 10 # affecter son attribut x
5 # et son attribut y
On dit que p2 est une instance de la classe Point, ou que la classe de pest Point,
ou plus simplement que p1 est un objet Point.
Un objet connait sa classe :lattribut spécial _cLass__ d'un objet est sa classe.
pl._class__is Point # True
Dans la figure ci-contre, appelée diagramme d’objets, p1 désigne objet qui a
&té créé, représenté par ses attributs x et y et leurs valeurs. La classe Point est
représentée par un rectangle arrondi, La classe de Vobjet ('attribut__class__) est,
représentée parla flache mauve :
Les objets sont manipulés dans un programme Python comme les autres valeurs du
langage :on peut les passer en paramétres, accéder et affecter leurs attributs et les
retourner comme valeur d’une fonction. Par exemple, la fonction suivante prend en
paramétres deux instances pi et p2 de la classe Point, crée une nowvelle instance
mde la class Point, affecte ses attributs et retoumne cette nouvelle instance
def milieu(p1, p2):
""" Retourne un nouveau point, milieu du segment (pl, p2) """
mm = Point()
mx = (pl.x + p2.x
my = (pl.y + p2.y’
return n
12.0
12.0
34Comme les tableaux et les dictionnaires, les objets sontmuables puisque lon peut
changer les valeurs de leurs attributs, Cela peut donc causer des surprises en cas
Gialiassage, lorsque deux variables référencent le méme objet (figure ci-contre)
p2=p1 # p2 et p1 désignent le mine point
def zero(p)
p.x=0
py=0
zero(p1) pl et p2 ont maintenant pour attributs x=0 et y=0
Contrairement aux tableaux et aux dictionnaires, deux objets sont égaux uniquement
sils sont le méme objet, et pas sils ont le méme contenu figure ci-contre)
pl = Point(); pl.x = 10; p2.x = 15
p2 = Point(); p2.x = pl.x; p2.
pl==p2 —‘# False
ply
PARR}
Le but d'une classe est de pouvoir eréer et manipuler des objets qui ont des carac-
1éristiques communes :les instances de la classe Point, par exemple, représentent
es points du plan et on siattend a pouvoir faire des opérations géométriques telles
que translater un point ou calculer sa distance a un autre point
La classe permet de regrouper ces opérations en definissant desméthodes, c'est-
a-dire des fonctions propres a cette classe, définies a I'intérieur de celle-ci. Par
exemple, la classe Point pourrait avoir trois méthodes
+ imit(p, x, y) pour initialiser le point p aux coordonnées (x,y);
+ translater (p, v) pour translater une point d'un vecteurv;
+ distance(p, q) pour calculer la distance entre deux points et g.
Ces fonctions ont toutes la particularité que leur premier paramétre est un Point.
Conventionnellement, on appelle ce paramétre se lorsque l'on définit une
méthode. Ainsi la méthode 4 nit est définie comme sult
class Poin’
def init(self, coord_x, coord_y):
self.x = coord x
self.y = coord_y
Pour appeler cette méthode, on utilise la notation pointée, comme pour les attributs
p = Point()
[Link](1@, 15)
IMPORTANT:
+ init n’est pas un attribut de p, mais une méthode définie dans la classe de p
(Point). Le langage reconnait que p est un objet et que init n’est pas un de ses
attributs, il regarde alors si cest une méthode déclarée dans sa classe.
+ Bien que lon ait déclaré la méthode init comme prenant trois paramétres (self,
xety),on/appelle avec deux paramétres (19 et 15). Le parametre seLf correspond
a fobjet p de la notation pointée p. init (..). En dautres termes, psinit(x, y)
appelle la méthode init (p, x, y) de la classe de p, cest-a-dire la classe Point.
CHAPITRE2 | PROGREMMATION PaROSETS BBIlrésulte des deux remarques ci-dessus que :
+ toutes les instances d'une classe ant accés a ses méthodes : celles
donc interface de la classe ;
+ deux classes peuvent avoir une méthode de méme nom. Par exemple la
classe Point et la classe Segment peuvent toutes les deux avoir une méthode
translater.
(éfinissent
2.41, Définir une classe
Pour définir complétement la classe Point, on doit définir l'ensemble de ses
méthodes & I'intérieur de la classe :
class Point:
def init(self, coord x, coord_y:
self.x = coord_x
self.y = coord
return self
def translater(self, v):
self.x #2 v.x
self.y #= vy
def distance(self, p2)
return [Link]((p2.x - self.x)**2 + (p2.y - self.y)**2)
On peut alors utiliser les méthodes comme suit
pl = Point().init(5, 2) # créer un point et L'initialiser
p2 = Point().init(3, 4) —# créer un second point et 1*initialiser
[Link](p1) # p2 est en 8, 6
print(p!.distance(p2)) _# distance = 5
La figure ci-contre illustre la situation aprés la deuxiéme ligne du programme.
Le rectangle arrondi, qui représente la classe Point, contient ses méthodes.
2.2. Garantir l'initialisation avec un constructeur
ilest important de créer des objets dont l'état initial est connu. Dans les exemples
précédent, la création d’une instance en appelant la fonction Point () crée un objet
qui n’a aucun attribut. Si on crée deux points sans les initialiser, on a de grandes
chances de provoquer des erreurs :
>>> pl = Point()
>>> p2 = Point()
>>> pl .distance(p2)
Traceback (most recent call last):
File "", Line 1, in
File “", line 12, in distance
AttributeError: "Point’ object has no attribute ‘x’
Silfon définit dans la classe une méthode au nom spécial __init__, cette méthode,
appelée constructeur, est automatiquement appelée lorsque lon crée un objet
class Point:
def _init_(self):
self.x = 0
self.y = 0
p=Point() — # p a deux attributs x=0 et y=0
36Cette méthode peut avoir des parametres supplémentaires, avec éventuellement
des valeurs par défaut
class Point:
def __init_(self, coord.
self.x = coord_x
self.y = coord y
origine = Point() # origine.x = @ et origine.y = @
p= Point(5, 10) #p.x = Set py = 10
RPL Tee hea ede) (ey
Dans de nombreux cas, utilisation d'objets permet d'écrire des programmes plus
lisibles et de maniére plus intuitive que lorsque l'on utilise seulement des tuples ou
es tableaux. En effet:
+ les noms des classes et des attributs permettent de mieux décrire la nature des
objets : p = Point () est plus explicite que p = [0,0] oup = (0,0), et p.y est
plus clair que p21 ;
+ les attributs des objets peuvent étre diautres objets, ce qui permet de créer des
structures complexes ;
+ des opérations similaires peuvent étre implémentées par des méthodes de meme
nom. Par exemple, les classes Point et Segment (voir ci-dessous) implémentent
toutes les deux la méthode trans ater, mais de maniére différente ;
+ les méthodes étant liées & la classe de l'objet lui-méme (contrairement a une
fonction), cela limite les erreurs de programmation et facilte la maintenance d'un
programme, c’est-a-dire son évolution au cours du temps.
Illustrons ces trois derniers points avec I'exemple suivant. Un segment de droite
tant constitué de deux points, il est naturel de définir la classe Segment comme
ayant deux attributs qui sont des objets Point
class Segnent:
def __init__(self, point_1, point_2):
self.p1 = point_1
self.p2 = point 2
def translater(self, p):
[Link](p)
[Link](p)
def milieu(self)
return Point(([Link].x + self.p2.x)/2, (self.p1.y + self.p2.y)/2)
p= Point(18, 20) # p.x poy = 20
Q=Point(5, 15) q.x qy = 15
S = Segnent(p, q) # [Link].x = 10, [Link].y = 20, s.p2.x = 5, s.p2.y = 15
m=[Link]() — #m.x = 7.5, my = 17.5
[Link]() erreur : ‘p’ object has no attribute ‘milieu’
La classe Segment définit la méthode translater, similaire a celle de la classe
Point. Si fon utlisait des fonctions au lieu de méthodes, i faudrait définir deux fonc-
tions, transLater_point et translater_segment, alors qu'ici on peut utiliser le
méme nom de méthode :0. translater (p) appelera la méthode translater
de la classe Point si o est un point, celle de la classe Segment io est un segment
et provoquera une erreur sinon,
CCHAPITRE2 | PROGREMMATION PAR OBJETS
37x=10 x=5 x=75
y=20 y=i5 y=005
tzle
s p 4 m
Diagramme d'objets d lissue du programme
La classe Segment définit également la méthode mi 14 eu qui retourne le point
milieu du segment. Comme cette méthode est définie seulernent dans cette classe,
sion applique & un objet qui n‘est pas un segment, on obtient un message d'erreur
facile & interpréter (derniae ligne du programme ci-dessus).
Si ‘on nvutilisait pas d'objets et que Ion représentait les points et les segments par
des tuples, Ia fonction mi ew s‘écrrait comme ci-dessous. L'appel de cette fonction
avec un point au lieu diun segment en paramétre provoque une erreur, mais celle-ci
est difficile a interpréter
4 sans L'utilisation d'objets
def milieu(s):
pl, p2=s # un segment est un tuple (p1, p2)
x1, yl = pl # un point est un tuple (x, y)
x2, y2 = p2
return ((x1+x2)/2, (yl4y2)/2)
mitieu(((16,20), (5,15))) # (7.5, 17.5)
milieu((10,20)) # erreur “cannot unpack non-iterable int object"
* Objets et aliassage
Ilfaut cependant étre prudent avec laliassage lorsque l'on utilise des objets. Aprés
instruction suivante, les coordonnées du point p ont changé, mais cela affecte aussi
la premidre extrémité du segment s
[Link](q) # p.x
G45 = 15, p.y = 2615 = 35
0 = 3 x=5
y=m0 z =I5
pL i
2
‘ » « . . 4
Etat des objets avant Etat des objets apres
p. translater (q) p. translater (q)
38De la méme facon, apres instruction suivante, les coordonnées des deux points du
segment s ont changé, et donc celles de p et q aussi figure ci-clessous & gauche)
[Link](q) # [Link].x = 1545, [Link].y = 35415, 5.p2.x = 5#5, s.p2.y = 15415
En revanche, si fon affecte un nouveau point a lattribut pa du segment s, p nvest
pas affecté (figure ci-dessous a droite)
s.p2 = Point(5, 10)
x= 20 x= 10 ae x22
yam 30 y=10
f
pl pl
po po
. p 4 . p 4
Etat des objets apres la ligne Etat des objets apres affectation
[Link](q) dun nouveau point as .p2
yee ee (Melty
Dans le chapitre précédent, nous avons vu des types abstraits implémentées par
des structures de données de facan fonctionnelle, cest-a-dire par des fonctions et
des types de données structurées ou d'autres types abstraits
Les types abstraits peuvent également étre inmplémentés par des classes d objets
+ Le constructeur de la structure de données est implémenté par le constructeur
de la classe.
+ Les opérateurs sont des méthodes quiimodifient 'état de l'objet. Au contraire de
approche fonctionnelle, ol es structures sont en général immuables et les apéra
teurs retournent une nouvelle structure, les objets sont muables et les opérateurs
modifient directement l'objet.
+ Lesaccesseurs sont des méthodes qui retournent une information sur a structure,
+ Les itérateurs sont des méthodes qui permettent d’énumérer les éléments de
la structure,
Ainsi, les méthodes de la classe correspondent a Interface du type abstrait. Deux
classes qui implémentent le type abstait de facon différente ont alors des méthodes
de méme nom, ce qui permet de facilement remplacer une implémentation par
une autre,
+ Objets et types structurés Python
Les tableaux et les dictionnaires Python sont des classes prédéfinies de Python, C'est
la raison pour laquelle nous avons déj2 utilisé la notation pointée pour manipuler
tableaux et dictionnaires
+ teappend(v), t-pop(), [Link]() sont trois méthodes qui modifient le
tableau t;
+ [Link](),[Link](),[Link]() sont trois méthodes qui retournent des
listes de clés, de valeurs ou de couples (clé, valeur) du dictionnaire d.
CHAPITRE2 | PROGREWMATION PaROSETS 3Beae
Instantation
obj = Maclasse(.)
Classes Constructeur
Cie def init__(self.)
Méthode
det meth (sel, .):
i
i
‘[Link](..)
z
£
[Link]
Classe —>} MaClasse
Constructeur —| wit _(e0lf, param... )+
Acces attribut Lf attr = paren
Méthode —|—>laer metha(self, param...)
Accas attribut > nee self attr
seit mech2(
Appels de méthode
SSA objaemeth(.+.) cad
Méthode —|—olace meth2(self, ...)2 = =
Instancations ck bil = Haciasse5
anciatons <¥ 093) = eevee} cy ote
Acces attribut —» [Link] = 3
‘Appel de méthode —> obji-meen(2)
@ Parcours d'exercices
Ecrire la définition dune classe
Accéder aux attributs et méthodes dune classe
40Choisir la (ou les) bonnets) réponse(s)
Un objet
a} contient des attriburs
dafinit des méthodes
b
€ | estlinstance d'une classe
Une classe:
[a] sera créer des objets
b
ce]
estfinstance d'un objet
definit des méthodes
Une méthode est
| un attriburt dun objet
‘b|
ic
une fonction définie dans une classe
tune fonction définie dans un objet
La notation pointée
permet dlaccéder aux attributs dun objet
a
b| permet dappeler des méthodes
| n’existe pas en Python
Une instance est
[a] unobjet
b
c
une classe
une méthode
selfest
un attribut spécial
un objet spécial
objet pour lequel on appelle la méthode
allele
le premier paramétre d'une méthode
On accéde & lattribut x de l'objet par'expression
a] o(x) [b| ofx] (¢| of'x'] [d
o.x
‘On appelle la méthode mde objet o par expression
a] o.m() [b] m(o) |) o(m) [d| m.o()
Réponses page 330.
© awstes afimations sont conectes?
Le constructeur dune classe
fa]
b)
ig
estobligatoire
sert a initialiser les attributs
est appelé automatiquement
© ovatfche e prosrarnme suivant ?
(a)
b
c
a
b
Le]
id)
class
def init(self, x):
self.x = 10
print(C(6).x)
°
10
Une erreur
Quelles affirmations sont correctes ?
Le premier parametie d'une méthode m
dott s'appeler seLf
est optionnel
estl'objet 0 dans expression o«m(.)
este parametre x dans Fexpression 0.m(x, =)
Quel constructeur est correct ?
a) Sf fete: fp) et inte:
E] fF minitoet: fg) det inte (cet
© oxalic méthode m met la valeur de Fateribut xa 0?
a] fa: B] ®t meth: |
[e] stn: a] #0:
CHAPITRE2 | PROGRAMATION PaROSETS
Vous aimerez peut-être aussi