Éducation Nationale Française · Seconde
Python : choix et boucles
I
Choisir
Un programme sans condition exécute toutes ses lignes, une fois chacune, de haut en bas. Un programme qui réagit à une valeur a besoin de plus : afficher
minor pour un âge et adult pour un autre, répondre too big ou too small dans un jeu. La machine doit choisir entre plusieurs groupes de lignes selon une condition, une question dont la réponse est oui ou non. Choisir, c'est écrire cette question et les lignes qui en dépendent.
Définition — Booléens et comparaisons
Une comparaison entre deux valeurs est une expression dont la valeur est soit True soit False. Ces deux valeurs forment le type bool. Les opérateurs de comparaison sont == (égal à), != (différent de), <, <=, > et >=. L'égalité s'écrit avec deux signes égal : un seul = est une affectation, pas une question. Exemple
Qu'affiche le programme suivant ? print(3 < 5)
print(3 == 5)
print(2 + 2 == 4)
print("abc" == "ABC")
print(type(3 < 5)) True
False
True
False
<class 'bool'> Chaque comparaison se calcule comme n'importe quelle expression : 2 + 2 est calculé d'abord, puis comparé à 4. Deux chaînes ne sont égales que si elles ont exactement les mêmes caractères : une majuscule diffère d'une minuscule. La valeur d'une comparaison a le type bool. Définition — L'instruction if
L'instruction if est suivie d'une condition et d'un deux-points. Les lignes écrites en dessous et indentées de quatre espaces forment son bloc : elles ne sont exécutées que si la condition vaut True. Si la condition vaut False, le bloc est sauté. Un else facultatif suivi d'un deux-points, aligné avec le if, introduit un second bloc, exécuté seulement si la condition vaut False. Les lignes qui suivent, revenues à la marge, sont exécutées dans les deux cas. Exemple
Qu'affiche le programme suivant ? age = 15
if age >= 18:
print("adult")
else:
print("minor")
print("Checked.") minor
Checked. La condition age >= 18 vaut False, donc le bloc du if est sauté et le bloc du else s'exécute. La dernière ligne n'est pas indentée : elle n'appartient à aucun des deux blocs et s'exécute quel que soit l'âge. Avec age = 20, le programme afficherait adult puis Checked. Définition — La cascade elif
Quand il y a plus de deux cas, les blocs s'enchaînent avec elif (abréviation de else if) : if une première condition, elif une deuxième, elif une troisième, et éventuellement else à la fin. Les conditions sont testées dans l'ordre ; le bloc de la première condition qui vaut True est exécuté et tous les autres sont sautés, même si leur condition vaut aussi True. Le bloc else ne s'exécute que si aucune condition ne vaut True. Exemple
Qu'affiche le programme suivant ? score = 12
if score >= 16:
print("very good")
elif score >= 12:
print("good")
elif score >= 10:
print("pass")
else:
print("fail") good La première condition, score >= 16, vaut False. La deuxième, score >= 12, vaut True : son bloc s'exécute et la cascade s'arrête là. La troisième condition, score >= 10, vaut aussi True mais elle n'est jamais testée. Les cas sont rangés du seuil le plus haut au plus bas pour que chaque note tombe dans exactement un bloc. Définition — Combiner des conditions
Deux conditions se combinent avec and et or : a and b vaut True seulement si les deux valent True ; a or b vaut True dès que l'une au moins vaut True. Le mot not devant une condition l'inverse : not a vaut True exactement quand a vaut False. Chaque côté de and et de or s'écrit comme une comparaison complète. Exemple
Qu'affiche le programme suivant ? n = 15
print(n > 10 and n < 20)
print(n < 10 or n > 100)
print(not n > 100)
if n >= 10 and n <= 20:
print("between 10 and 20") True
False
True
between 10 and 20 Ligne 2 : les deux comparaisons valent True, donc le and vaut True. Ligne 3 : les deux valent False, donc le or vaut False. Ligne 4 : n > 100 vaut False, et not l'inverse. Le if teste une condition faite de deux comparaisons ; elle vaut True, donc son bloc s'exécute. Méthode — Lister les cas avant d'écrire
- Lister les cas : quelles sont les situations différentes que le programme doit distinguer ? Les écrire en mots, avec une valeur d'exemple pour chacune.
- Écrire l'affichage attendu à côté de chaque cas.
- Ordonner les cas pour que chaque valeur tombe dans exactement un seul : avec des conditions comme
score >= 16, du seuil le plus haut au plus bas ; avec des conditions commeage < 12, du seuil le plus bas au plus haut. - Écrire un bloc par cas :
ifpour le premier,elifpour les suivants,elsepour ce qui reste. - Exécuter le programme une fois par cas, avec la valeur d'exemple de ce cas.
Exemple
Écrire un programme qui affiche le plus grand de trois nombres a, b et c.
Trois cas :
a est le plus grand, ou b l'est, ou c l'est. Le premier cas signifie que a est au moins aussi grand que les deux autres ; sinon, le deuxième cas n'a plus qu'à comparer b et c ; ce qui reste est le troisième cas. a = 4
b = 9
c = 2
if a >= b and a >= c:
biggest = a
elif b >= c:
biggest = b
else:
biggest = c
print("Largest:", biggest) Le programme affiche Largest: 9. Chaque bloc range sa réponse dans la même variable, biggest, affichée une seule fois après la cascade : un print au lieu de trois. Exemple
Qu'affiche le programme suivant ? light = "orange"
if light == "green":
print("go")
elif light == "orange":
print("slow down")
elif light == "red":
print("stop")
else:
print("unknown light") slow down Une chaîne se compare avec == comme un nombre. Le bloc else recueille toute valeur qui n'est aucune des trois couleurs, par exemple une faute de frappe comme "Orange" : c'est une bonne pratique de dire ce qui se passe dans le cas restant.
Un signe égal ou deux
Une condition écrite avec un seul signe égal n'est pas une comparaison, et la machine la refuse avant d'exécuter quoi que ce soit.
x = 5
if x = 5:
print("five") File "main.py", line 2
if x = 5:
^^^^^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='? L'autre faute classique est acceptée par la machine mais fausse : if x == 5 or 6: ne signifie pas x vaut 5 ou 6. Le côté droit du or est le nombre 6 tout seul, que Python considère comme vrai, donc le bloc s'exécute toujours. Chaque côté doit être une comparaison complète : if x == 5 or x == 6:.
L'indentation
Le bloc d'un
if se reconnaît à sa seule indentation. Une indentation oubliée arrête le programme avant son exécution. age = 20
if age >= 18:
print("adult") File "main.py", line 3
print("adult")
^
IndentationError: expected an indented block after 'if' statement on line 2 Le else doit être aligné avec son if, et toutes les lignes d'un bloc doivent avoir la même indentation, quatre espaces par convention. Une ligne revenue à la marge termine le bloc : une ligne destinée au bloc mais écrite à la marge ne donne aucune erreur et s'exécute dans tous les cas, ce qui est plus difficile à remarquer.
Une cascade ou des tests séparés
Remplacer
elif par if change le sens : les conditions deviennent indépendantes, et plusieurs blocs peuvent s'exécuter pour la même valeur. score = 12
if score >= 12:
print("good")
if score >= 10:
print("pass") good
pass Avec elif sur le second test, seul good serait affiché. Écrire elif quand les cas s'excluent, if quand ce sont des questions indépendantes.
Comparer une valeur saisie
La valeur renvoyée par
input() est une chaîne, même quand l'utilisateur tape des chiffres. La comparer à un nombre avec <, <=, > ou >= arrête le programme. age = input("Age? ")
if age >= 18:
print("adult") Age? 20
Traceback (most recent call last):
File "main.py", line 2, in <module>
if age >= 18:
^^^^^^^^^
TypeError: '>=' not supported between instances of 'str' and 'int' Avec == il n'y a pas d'erreur, mais la chaîne "20" n'est jamais égale au nombre 20, donc la comparaison vaut toujours False. Convertir d'abord : age = int(input("Age? ")).
Compétences à pratiquer
- Prédire une branche
- Deux branches
- Plusieurs cas
II
Répéter un nombre de fois
Afficher les nombres de 1 à 10 avec dix lignes
print fonctionne ; de 1 à 1000, non. Un programme a besoin d'un moyen de dire répéter ces lignes, et de savoir à quel tour il en est. C'est le rôle de la boucle : un bloc de lignes exécuté plusieurs fois, avec une variable qui compte les tours.
Définition — La boucle for et range
L'instruction for i in range(n): exécute son bloc indenté n fois. À chaque tour, la variable de boucle i prend la valeur suivante de la suite 0, 1, …, n - 1 : elle commence à 0 et s'arrête avant n ; quand n vaut 0 ou est négatif, le bloc n'est pas exécuté du tout. Avec deux arguments, range(a, b) va de a à b - 1 ; avec trois, range(a, b, step) avance de step (le pas), qui peut être négatif pour compter à rebours. La variable de boucle peut porter n'importe quel nom. Exemple
Qu'affiche le programme suivant ? for i in range(3):
print("Hello")
for i in range(3):
print(i)
for k in range(2, 5):
print(k) Hello
Hello
Hello
0
1
2
2
3
4 La première boucle exécute son bloc trois fois sans utiliser i. La deuxième affiche les valeurs successives de i : trois valeurs, de 0 à 2. La troisième commence à 2 et s'arrête avant 5. Exemple
Qu'affiche le programme suivant ? for k in range(5, 0, -1):
print(k)
print("Go!") 5
4
3
2
1
Go! Le pas -1 compte à rebours depuis 5 ; la boucle s'arrête avant 0, donc 0 n'est pas affiché. La dernière ligne n'est pas indentée : elle s'exécute une fois, après la boucle. Définition — Compteur et accumulateur
Un compteur est une variable qui compte quelque chose pendant une boucle : elle est créée avant la boucle avec la valeur 0, augmentée de un dans le bloc chaque fois que la chose se produit, et lue après la boucle. Un accumulateur fonctionne de même mais combine les valeurs vues jusque-là en un seul résultat, une somme, un produit ou une plus grande valeur : créé avant la boucle avec la valeur de départ de ce résultat, 0 pour une somme, 1 pour un produit, la première valeur pour une plus grande valeur, mis à jour dans le bloc, lu après. Méthode — Le schéma de l'accumulateur
- Avant la boucle, créer la variable avec sa valeur de départ :
total = 0pour une somme,product = 1pour un produit,count = 0pour un compteur, la première valeur pour une plus grande valeur. - Dans le bloc, la mettre à jour à partir de la valeur courante :
total = total + i,count = count + 1. - Après la boucle, l'afficher ou l'utiliser. Rien dans le bloc ne doit la remettre à zéro.
Méthode — Tracer une boucle avec un tableau
Pour prédire ce qu'une boucle affiche, ou trouver pourquoi elle ne l'affiche pas, remplir un tableau à la main : une colonne par variable, une ligne par tour. - Écrire les colonnes : le numéro du tour, la variable de boucle, chaque variable modifiée dans le bloc.
- Écrire la ligne d'avant la boucle : les valeurs de départ.
- Remplir une ligne par tour, en exécutant le bloc avec les valeurs de la ligne précédente.
- S'arrêter quand la boucle s'arrête : la dernière ligne donne les valeurs après la boucle.
Exemple
Qu'affiche le programme suivant ? total = 0
for i in range(1, 5):
total = total + i
print("Sum:", total) Sum: 10 Le tableau de la trace, une ligne par tour : | tour | i | total |
| avant | 0 | |
| 1 | 1 | 1 |
| 2 | 2 | 3 |
| 3 | 3 | 6 |
| 4 | 4 | 10 |
i de 1 à 4 ; à chaque tour total augmente de i. Après la boucle, total vaut 10 et le print l'affiche une fois. Exemple
Qu'affiche le programme suivant ? for i in range(1, 6):
print(7, "x", i, "=", 7 * i) 7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35 Une ligne par tour : la variable de boucle apparaît deux fois dans le print, une fois comme nombre et une fois dans un produit. Remplacer 6 par 11 donne la table entière. Exemple
L'utilisateur tape 3, 9, 4, 9 et 1. Qu'affiche le programme suivant ? biggest = int(input("Number? "))
for i in range(4):
n = int(input("Number? "))
if n > biggest:
biggest = n
print("Biggest:", biggest) Number? 3
Number? 9
Number? 4
Number? 9
Number? 1
Biggest: 9 La variable biggest garde la plus grande valeur vue jusque-là : elle commence avec le premier nombre plutôt qu'avec 0, pour fonctionner quels que soient les nombres, puis chacun des quatre autres la remplace seulement s'il est plus grand. C'est le maximum courant, un accumulateur avec un if dans la boucle. Définition — Boucles imbriquées
Une boucle écrite dans le bloc d'une autre boucle est imbriquée : pour chaque tour de la boucle extérieure, la boucle intérieure fait tous ses tours. L'instruction print(x, end="") affiche x sans terminer la ligne, si bien que le print suivant continue sur la même ligne ; print() seul termine la ligne. Exemple
Qu'affiche le programme suivant ? for row in range(1, 4):
for col in range(row):
print("*", end="")
print() *
**
*** Trois tours de la boucle extérieure, un par ligne. À la ligne 1 la boucle intérieure fait un tour et affiche une étoile ; à la ligne 2, deux ; à la ligne 3, trois. Le print() du bloc extérieur, indenté une fois, termine chaque ligne.
Le décalage d'une unité
range(10) produit dix nombres, de 0 à 9 : 10 n'en fait pas partie. Pour afficher de 1 à 10, écrire range(1, 11). La faute de boucle la plus fréquente est un résultat auquel il manque un tour, ou qui en a un de trop : quand une boucle donne un résultat inattendu, vérifier d'abord les bornes de son range. for i in range(1, 4):
print(i) 1
2
3
Un accumulateur remis à zéro dans la boucle
Un accumulateur créé dans le bloc est remis à zéro à chaque tour, et ne garde que la dernière valeur.
for i in range(1, 5):
total = 0
total = total + i
print(total) 4 La ligne total = 0 doit être écrite une fois, avant la boucle. Le tableau de la trace montre la faute aussitôt : la colonne total ne grandit jamais.
Compétences à pratiquer
- Prédire une boucle
- Compter
- Accumuler
- Boucles imbriquées
III
Répéter tant que
Une boucle
for sait d'avance combien de tours elle fera. Beaucoup de programmes ne le savent pas : redemander jusqu'à ce que la réponse soit valable, lancer un dé jusqu'à obtenir un six, lire des nombres jusqu'à ce que l'utilisateur tape 0. Le nombre de tours dépend de ce qui se passe pendant la boucle. La boucle qui répète tant que une condition tient, et les nombres aléatoires, rendent possible un premier vrai jeu.
Définition — La boucle while
L'instruction while est suivie d'une condition et d'un deux-points. Avant chaque tour, la condition est calculée : si elle vaut True, le bloc indenté est exécuté et la condition est calculée de nouveau ; si elle vaut False, la boucle s'arrête et le programme continue après le bloc. Le bloc doit modifier quelque chose dont la condition dépend, sinon la boucle ne s'arrête jamais ; l'instruction break, définie plus bas, est l'autre issue. Exemple
Qu'affiche le programme suivant ? n = 1
while n <= 100:
n = n * 2
print(n) 128 La trace : n prend les valeurs 1, 2, 4, 8, 16, 32, 64, 128. Tant que n vaut au plus 100 il est doublé ; quand n atteint 128 la condition vaut False et la boucle s'arrête. Le programme trouve la première puissance de deux au-dessus de 100 sans savoir d'avance combien de doublements il faut. Définition — Sentinelle et break
Une sentinelle est une valeur spéciale que l'utilisateur tape pour terminer la boucle, comme 0 ou stop : la valeur est lue une fois avant la boucle et de nouveau à la fin de chaque tour, et la condition du while la compare à la sentinelle. L'instruction break, écrite dans le bloc, quitte la boucle immédiatement quelle que soit la condition. Exemple
L'utilisateur tape 5, 8 et 0. Qu'affiche le programme suivant ? total = 0
n = int(input("Number? "))
while n != 0:
total = total + n
n = int(input("Number? "))
print("Total:", total) Number? 5
Number? 8
Number? 0
Total: 13 La sentinelle est 0. Le premier nombre est lu avant la boucle ; chaque tour additionne le nombre courant et lit le suivant. Quand 0 est tapé, la condition n != 0 vaut False : la boucle s'arrête sans l'additionner. Deux nombres ont été additionnés, mais le programme fonctionnerait de même avec cent. Exemple
L'utilisateur tape 15, 0 et 7. Qu'affiche le programme suivant ? n = int(input("Between 1 and 10? "))
while n < 1 or n > 10:
print("Try again")
n = int(input("Between 1 and 10? "))
print("OK:", n) Between 1 and 10? 15
Try again
Between 1 and 10? 0
Try again
Between 1 and 10? 7
OK: 7 C'est le schéma de la validation de saisie : la condition du while décrit une valeur incorrecte, donc le bloc s'exécute tant que la réponse est incorrecte. Avec 7, la condition vaut False aussitôt et la boucle se termine. Exemple
L'utilisateur tape 4, 7, 0 et 9. Qu'affiche le programme suivant ? total = 0
while True:
n = int(input("Number? "))
if n == 0:
break
total = total + n
print("Total:", total) Number? 4
Number? 7
Number? 0
Total: 11 La condition True ne devient jamais False : la seule issue est le break, pris dès que 0 est tapé. Le 9 n'est jamais lu. Par rapport à la version précédente, le nombre est lu une fois, en tête du bloc, au lieu de deux ; les deux programmes sont corrects, et la version avec une vraie condition dit au premier coup d'œil quand la boucle s'arrête. Définition — Les nombres aléatoires
La ligne import random, écrite en tête du programme, donne accès à random.randint(a, b), qui renvoie un entier choisi au hasard entre a et b, tous deux compris. Deux exécutions du même programme peuvent afficher des valeurs différentes. Exemple
Les tirages du dé sont 3, 5 et 6. Qu'affiche le programme suivant ? import random
count = 0
die = 0
while die != 6:
die = random.randint(1, 6)
count = count + 1
print("Throw", count, ":", die)
print("Six after", count, "throws") Throw 1 : 3
Throw 2 : 5
Throw 3 : 6
Six after 3 throws La variable die commence à 0, une valeur qui n'est pas 6, donc la boucle fait au moins un tour. Chaque tour lance le dé et compte le lancer. Avec d'autres tirages le nombre de tours change : la boucle doit être un while, puisque personne ne sait d'avance quand le six arrive. Méthode — for ou while ?
- Se demander : le nombre de tours est-il connu avant que la boucle commence ?
- Connu (un compte, un
range, un nombre d'éléments) : écrire unfor. La variable de boucle tient le compte. - Inconnu (il dépend d'une valeur tapée, d'un tirage, d'une valeur calculée) : écrire un
whileavec la condition qui fait continuer la boucle. - Vérifier qu'un
whilelit ou modifie, dans son bloc, ce dont sa condition dépend.
Méthode — S'assurer que la boucle s'arrête
- Nommer les variables de la condition : dans
while n != 0, la variable estn. - Trouver la ligne du bloc qui modifie chacune d'elles. S'il n'y en a pas et pas de
break, la boucle ne peut pas s'arrêter. - Tracer deux ou trois tours avec un tableau, une ligne par tour, jusqu'à ce que la condition devienne
False. - Si le programme semble bloqué, l'arrêter, puis relire la condition : est-ce bien la condition pour continuer, et non celle pour s'arrêter ?
Exemple
Qu'affiche le programme suivant ? n = 6
while n != 1:
if n % 2 == 0:
n = n // 2
else:
n = 3 * n + 1
print(n, end=" ") 3 10 5 16 8 4 2 1 Un if dans un while : à chaque tour, un n pair (son reste par 2 vaut 0) est divisé par deux avec le quotient entier //, et un n impair est triplé plus un. Les valeurs s'affichent sur une ligne grâce à end=" ". La condition n != 1 devient False après huit tours. Que cette suite atteigne 1 pour tout entier de départ strictement positif est une question ouverte célèbre des mathématiques ; pour les nombres essayés jusqu'ici, c'est le cas.
La boucle infinie
Un
while dont le bloc ne modifie jamais la condition ne s'arrête jamais. n = 3
while n > 0:
print(n) Le programme affiche 3 sans fin : le bloc ne modifie jamais n. Dans l'éditeur en ligne, un programme qui ne s'arrête pas après cinq secondes est arrêté avec un message ; sur un ordinateur, il faut interrompre le programme à la main. La correction est une ligne qui fait avancer n vers la fin de la boucle, ici n = n - 1 dans le bloc.
La condition inversée
La condition d'un
while est la condition pour continuer, pas la condition pour s'arrêter. Écrire la condition d'arrêt à la place donne une boucle qui ne démarre jamais, sauf si 0 est tapé d'emblée. n = int(input("Number? "))
while n == 0:
n = int(input("Number? "))
print("Done") Number? 5
Done L'intention était lire jusqu'à ce que 0 soit tapé ; la condition pour continuer est n != 0. Lire la condition à voix haute avec tant que : tant que n vaut 0, redemander n'est pas ce qui était voulu.
Un while qui compte
Un
while peut faire le travail d'un for, au prix d'écrire le compteur à la main : le créer avant, le tester dans la condition, l'augmenter dans le bloc. Les deux programmes ci-dessous affichent la même chose ; le for est plus court et ne peut pas oublier d'augmenter i. i = 0
while i < 3:
print(i)
i = i + 1
for i in range(3):
print(i)
Compétences à pratiquer
- Prédire un while
- Sentinelles
- Le hasard
IV
Projet : deviner le nombre
Les conditions et les deux boucles suffisent à écrire un jeu. La machine tire un nombre secret ; le joueur propose des nombres ; après chaque proposition la machine dit
too big ou too small, jusqu'à ce que le joueur le trouve. Un jeu est une boucle : elle tourne tant que la partie n'est pas finie, et chaque tour lit le coup du joueur, met à jour l'état de la partie et répond.
Méthode — Construire la boucle d'un jeu
- Écrire l'état : les variables qui décrivent la partie à tout moment. Ici : le nombre secret, la dernière proposition, le nombre de tentatives.
- Écrire la condition pour continuer : la partie continue tant que la proposition diffère du secret.
- Écrire un tour : lire le coup, mettre à jour l'état, répondre au joueur. L'exécuter : la boucle doit se terminer quand le bon nombre est tapé.
- Écrire la fin : ce qui s'affiche après la boucle, à partir de l'état.
- Seulement ensuite ajouter les extras : une limite de tentatives, un message au début, une seconde partie.
Exemple
Le nombre secret tiré est 42 et le joueur tape 50, 25 et 42. Qu'affiche le programme suivant ? import random
secret = random.randint(1, 100)
attempts = 0
guess = 0
while guess != secret:
guess = int(input("Your guess? "))
attempts = attempts + 1
if guess > secret:
print("too big")
elif guess < secret:
print("too small")
print("Found in", attempts, "attempts") Your guess? 50
too big
Your guess? 25
too small
Your guess? 42
Found in 3 attempts L'état tient en trois variables : secret, tiré une fois avant la boucle ; guess, qui commence à 0, une valeur que le secret ne peut pas prendre, pour que la boucle fasse au moins un tour ; attempts, un compteur. La cascade répond aux deux cas faux ; quand la proposition est juste, aucune branche ne s'exécute, la condition devient False et la fin affiche le compteur. Chaque pièce de ce programme est déjà connue : un tirage, un while avec une condition sur une valeur tapée, un compteur, un if / elif. Compétences à pratiquer
- Construire le jeu et ses variantes
V
Pour aller plus loin
Compétences à pratiquer
- Aller plus loin avec les choix et les boucles
- Quiz
Aller à la section