Leçon 02-1 — if, elif, else : décider
1. Objectif
À la fin de cette leçon tu sauras : écrire un programme qui exécute des lignes différentes selon une condition, avec if, elif et else ; comparer des valeurs avec ==, !=, <, <=, >, >= ; expliquer pourquoi = et == sont deux choses totalement différentes ; et indenter correctement des blocs, y compris imbriqués.
2. Pourquoi c'est important
Jusqu'ici, tes programmes exécutaient toutes leurs lignes, de haut en bas, à chaque fois. Un vrai programme décide : afficher « Majeur » ou « Mineur », accepter ou refuser un mot de passe, appliquer tel tarif ou tel autre. Le if est la première structure de contrôle — TOUT le reste du niveau 2 (et les boucles, et les fonctions du niveau 4) repose sur des conditions. C'est aussi ici qu'on rencontre l'indentation comme syntaxe : en Python, les espaces en début de ligne changent le sens du programme.
3. Explication simple
Un if se lit comme une phrase : « SI la condition est vraie, fais ceci ; SINON, fais cela ».
age = 17
if age >= 18:
print("Majeur")
else:
print("Mineur")
print("Fin du programme")
Sortie :
Mineur
Fin du programme
Quatre choses à voir sur ce squelette :
- La condition (
age >= 18) est une expression qui vautTrueouFalse(unbool, vu en 01-2). - Les deux-points
:en fin de ligne annoncent un bloc. Obligatoires. - Le bloc indenté (décalé de 4 espaces) : c'est ce qui est exécuté si la condition est vraie. L'indentation N'EST PAS décorative : elle dit à Python « ces lignes appartiennent au
if». - La dernière ligne, non indentée, est hors du
if: elle s'exécute toujours, quelle que soit la condition.
Pour comparer, tu disposes de six opérateurs :
| Opérateur | Sens | Exemple vrai |
|---|---|---|
== | égal à | 5 == 5 |
!= | différent de | 5 != 3 |
< / <= | strictement inférieur / inférieur ou égal | 3 < 5, 5 <= 5 |
> / >= | strictement supérieur / supérieur ou égal | 5 > 3, 5 >= 5 |
Le point crucial de toute la leçon : = assigne (colle une étiquette, leçon 01-1), == compare (pose une question, réponse True/False). age = 18 donne la valeur 18 à age ; age == 18 demande « est-ce que age vaut 18 ? » sans rien modifier.
4. Explication approfondie
a) elif : la chaîne de décisions. Quand il y a plus de deux cas, on enchaîne : if … elif … elif … else. Python descend la chaîne et exécute le premier bloc dont la condition est vraie — puis saute tout le reste, même si une condition plus bas aurait aussi été vraie. Le else final (sans condition) attrape tous les cas restants ; il est facultatif.
Conséquence directe : l'ordre des elif est une décision de conception. Si tu testes score >= 50 avant score >= 90, un score de 95 s'arrête à la première condition vraie et affiche « Passable ». Pas d'erreur, juste un programme faux — on le verra en section 6.
b) L'indentation, précisément. La convention Python (universelle) : 4 espaces par niveau. VS Code les insère quand tu appuies sur Tab. Règles :
- Toutes les lignes d'un même bloc ont exactement la même indentation.
- Un bloc ne peut pas être vide : il faut au moins une ligne indentée après
:. - Revenir à l'indentation précédente ferme le bloc — il n'y a pas de
endni d'accolade fermante en Python : c'est la dé-indentation qui ferme.
c) Conditions imbriquées. Un if peut contenir un autre if : le bloc intérieur est indenté de 8 espaces. C'est légal et parfois le plus lisible (« d'abord vérifier l'âge, PUIS le billet »). Mais au-delà de deux niveaux, le code devient pénible à lire — la leçon 02-2 (and, or) te donnera l'outil pour aplatir la plupart des imbrications.
d) Comparer des types différents — deux comportements à connaître.
print(3 == 3.0) # True : int et float comparent leurs VALEURS
print("3" == 3) # False : str et int ne sont JAMAIS égaux — sans erreur !
== entre types incompatibles ne plante pas : il répond tranquillement False. C'est le bug silencieux emblématique du niveau : input() renvoie "5", et "5" == 5 vaut False pour toujours. En revanche <, >, <=, >= entre une str et un int plantent (TypeError) — Python ne sait pas ordonner un texte et un nombre. Retiens : égalité = False silencieux ; ordre = TypeError bruyant.
e) Le chaînage, spécialité Python. 2 < 3 <= 3 est légal et vaut True : Python le lit comme « 2 < 3 ET 3 <= 3 ». Très pratique pour les intervalles (0 <= note <= 20). ⏩ Le and sous-jacent est le sujet de la leçon 02-2.
Difficulté honnête : la syntaxe de cette leçon s'apprend en une session. Ce qui prend du temps, c'est (1) le réflexe == vs =, (2) l'indentation qui change le sens sans message d'erreur, (3) l'ordre des elif. Les trois reviennent en force dans la leçon 02-5 (erreurs de logique) — considère cette leçon-ci comme la pose des fondations.
5. Exemples commentés
Exemple 1 — if/else minimal (celui de la section 3 — tape-le vraiment).
Exemple 2 — une chaîne elif bien ordonnée
score = 72
if score >= 90:
print("Excellent")
elif score >= 70: # testé seulement si score < 90
print("Bien")
elif score >= 50: # testé seulement si score < 70
print("Passable")
else: # tous les cas restants : score < 50
print("Echoue")
Sortie : Bien. Les seuils sont testés du plus haut au plus bas : chaque elif sait que les conditions précédentes étaient fausses, donc pas besoin d'écrire 70 <= score < 90 — le < 90 est garanti par la position.
Exemple 3 — une comparaison est une valeur comme une autre
age = 20
is_adult = age >= 18 # la droite est évaluée d'abord (True), puis assignée
print(is_adult) # True
print(type(is_adult)) # <class 'bool'>
On peut stocker le résultat d'une comparaison dans une variable, l'afficher, la réutiliser dans un if (if is_adult:). Une condition n'a rien de magique : c'est une expression qui produit un bool.
Exemple 4 — condition sur une saisie utilisateur
answer = int(input("Combien font 2 + 2 ? ")) # int() : réflexe de la 01-2 !
if answer == 4:
print("Correct !")
else:
print(f"Non : tu as répondu {answer}")
Session (l'utilisateur tape 5) :
Combien font 2 + 2 ? 5
Non : tu as répondu 5
Sans le int(), la comparaison "4" == 4 serait toujours fausse — voir section 6.
Exemple 5 — conditions imbriquées
age = 25
has_ticket = True
if age >= 18:
if has_ticket: # testé SEULEMENT si age >= 18
print("Entree autorisee")
else: # cet else appartient au if INTÉRIEUR
print("Va acheter un billet")
else: # celui-ci au if EXTÉRIEUR (même indentation)
print("Interdit aux mineurs")
Sortie : Entree autorisee. Un else s'accroche au if qui a la même indentation que lui. Décale-le, et le programme change de sens (⏩ démonté en détail en 02-5).
6. Erreurs fréquentes
1) = au lieu de == dans la condition
age = 18
if age = 18:
print("majeur")
# SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
Python te sauve : assigner dans un if est interdit, et le message suggère même la correction. Grave le réflexe : = assigne, == compare. (L'inverse — age == 18 seul sur une ligne à la place d'une assignation — est légal et ne fait RIEN : la comparaison est calculée puis jetée. Bug silencieux.)
2) Oublier les deux-points
x = 5
if x == 5
print("ok")
# SyntaxError: expected ':'
Le message dit exactement quoi, et le ^ pointe la fin de la ligne fautive. if, elif, else : deux-points obligatoires, toujours.
3) Oublier d'indenter le bloc
x = 5
if x == 5:
print("ok")
# IndentationError: expected an indented block after 'if' statement on line 2
Après un :, Python exige au moins une ligne indentée. Le message te donne la ligne du if orphelin.
4) Indenter au hasard
x = 5
if x == 5:
print("a")
print("b")
# IndentationError: unexpected indent
Toutes les lignes d'un même bloc doivent avoir la même indentation. Deux espaces de trop suffisent à tout casser.
5) Comparer la saisie utilisateur sans la convertir
age = input("Ton age ? ") # l'utilisateur tape 18 → age vaut "18"
if age == 18:
print("Pile 18 ans")
else:
print("Pas 18")
Affiche Pas 18, toujours, sans erreur : "18" == 18 vaut False. C'est le pire des trois mondes — pas de traceback, une sortie plausible, un programme faux. Correction : age = int(input("Ton age ? ")). Avec < ou > au lieu de ==, tu aurais au moins eu un TypeError pour te prévenir.
6) Des elif dans le mauvais ordre
score = 95
if score >= 50:
print("Passable") # ← 95 >= 50 est vrai : on s'arrête ICI
elif score >= 90:
print("Excellent") # jamais atteint pour aucun score !
Sortie : Passable. Aucune erreur : Python exécute le premier bloc vrai et ignore le reste. Avec des seuils, teste toujours du plus exigeant au moins exigeant (90 avant 70 avant 50). Vérifie ta chaîne avec une valeur par branche, plus les valeurs pile sur les seuils (90, 70, 50).
7. Lire les messages d'erreur
SyntaxError avec suggestion — le = de trop
File "c:\Users\jtron\Claude\learnpython\note.py", line 2
if age = 18:
^^^^^^^^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
- Pas de
Traceback (most recent call last): c'est une erreur de syntaxe, le programme n'a exécuté aucune ligne (rappel de 01-1). - Les
^^^soulignent toute la condition ; la dernière ligne suggère la correction. (Le:=proposé est un opérateur avancé, ignore-le pour l'instant.)
IndentationError — le bloc manquant
File "c:\Users\jtron\Claude\learnpython\grade.py", line 3
print("admis")
^^^^^
IndentationError: expected an indented block after 'if' statement on line 2
Le message donne DEUX numéros de ligne : la ligne 3 qui aurait dû être indentée, et la ligne 2 du if qui attend son bloc. IndentationError est une sous-espèce de SyntaxError : là aussi, rien n'a été exécuté.
TypeError — ordonner un texte et un nombre
Nombre ? Traceback (most recent call last):
File "c:\Users\jtron\Claude\learnpython\check.py", line 3, in <module>
if guess < secret:
^^^^^^^^^^^^^^
TypeError: '<' not supported between instances of 'str' and 'int'
- Dernière ligne :
'<' not supported between instances of 'str' and 'int'— le message nomme l'opérateur ET les deux types coupables. Unestrface à unint: c'est uninput()non converti, à tous les coups. - Remonte : ligne 3 de
check.py, la comparaison est soulignée. Leifest la ligne du symptôme ; la cause est plus haut, à la création deguess(rappel de 01-2 : on corrige souvent au-dessus de la ligne du traceback). - Note le
Nombre ?avant le traceback : l'input()a fonctionné, le programme a planté juste après.
8. Exercices — faciles
Règles : nouveau fichier par exercice dans
lessons/level-02-conditions-boucles/exercices/mes-reponses/, nomméex-02-1-a.py, etc. Tape tout à la main. Prédis la sortie AVANT d'exécuter.
a) Demande un nombre entier à l'utilisateur et affiche positif, négatif ou nul. Trois branches, une seule s'exécute. Teste avec 7, -3 et 0.
b) Sans exécuter, écris sur papier la sortie de chaque ligne, puis vérifie :
print(3 == 3.0)
print("3" == 3)
print(10 != 10)
print("a" == "A")
print(5 >= 5)
c) Tarif de cinéma : demande l'âge et affiche le prix — gratuit avant 4 ans, 5.50 € de 4 à 17 ans, 9.20 € à partir de 18 ans. Contraintes : une chaîne if/elif/else (pas trois if séparés) ; teste les âges charnières 3, 4, 17, 18.
9. Exercices — moyens
a) Ce programme contient DEUX bugs — un bruyant, un silencieux. Trouve-les sans exécuter, dis quel message (ou quelle absence de message !) chacun produit, puis corrige :
age = input("Ton age ? ")
if age = 18:
print("Pile la majorite !")
elif age > 18:
print("Majeur")
else:
print("Mineur")
b) Ce programme affiche Passable pour TOUTES les notes au-dessus de 50, même 95. Explique pourquoi (sans exécuter), puis répare en changeant seulement l'ordre des branches :
score = 95
if score >= 50:
print("Passable")
elif score >= 70:
print("Bien")
elif score >= 90:
print("Excellent")
else:
print("Echoue")
Vérifie ta version avec 95, 72, 50 et 30.
c) Demande un nombre entier et affiche s'il est pair positif, pair négatif, impair positif ou impair négatif (traite 0 comme pair positif). Contraintes : utilise % (vu en 01-2) pour la parité, et des conditions imbriquées (un if parité qui contient un if signe) — tu n'as pas encore and, c'est le but de l'exercice.
10. Exercices — difficiles
a) Demande trois nombres entiers et affiche le plus grand, SANS utiliser la fonction max() ni and/or (⏩ leçon 02-2). Puis améliore : si le plus grand apparaît plusieurs fois (ex. 7 7 2), affiche ex aequo : 7.
- Indice 1 : compare d'abord
aetb: que sais-tu après ce seul test ? - Indice 2 : dans chaque branche du premier
if, il reste UNE comparaison à faire (le gagnant provisoire contrec). C'est de l'imbrication. - Indice 3 :
if a >= b:puis, à l'intérieur,if a >= c:→ le plus grand esta, sinonc. La brancheelseextérieure est symétrique avecb. Pour les ex aequo, compare le plus grand trouvé aux deux autres avec==.
11. Mini-projet lié — le convertisseur passe au menu
Reprends le convertisseur de la fiche projects/mini-projects/02-convertisseur-unites.md : tu as maintenant TOUT ce qu'il faut pour le faire en entier (étapes 1 à 6). Le menu à trois choix (1 : °C → °F, 2 : km → miles, 3 : kg → livres) est une chaîne if/elif/elif/else ; le else attrape les choix invalides avec un message propre, sans traceback.
Piège central de la fiche, désormais dans tes cordes : le choix arrive comme chaîne ("1", pas 1) — compare avec choice == "1", ou convertis. Durée cible : 30–45 min.
12. Correction / méthode de correction
Les solutions détaillées sont dans solutions/serie-02-1-solutions.md.
Méthode : (1) finis TOUS les exercices avant d'ouvrir les solutions ; (2) compare le raisonnement, pas seulement le code — une solution différente qui marche est souvent valable ; (3) pour chaque écart, écris une ligne dans ton journal : « je pensais X, en fait Y » ; (4) refais de tête l'exercice raté, le lendemain.
13. À retenir
if condition:+ bloc indenté (4 espaces) ;elifenchaîne,elseattrape le reste. Deux-points obligatoires.=assigne,==compare.if x = 5:→SyntaxErroravec suggestion.- Python exécute le premier bloc vrai de la chaîne et ignore tout le reste : l'ordre des
elifest une décision (seuils : du plus exigeant au moins exigeant). - L'indentation est de la syntaxe : la dé-indentation ferme le bloc.
"5" == 5vautFalsesans erreur ;"5" < 5lève unTypeError. Convertis tesinput()AVANT de comparer.- Un
elses'accroche auifde même indentation. - Une comparaison est une expression qui vaut
True/False— stockable dans une variable. 0 <= note <= 20: le chaînage de comparaisons est légal et lisible.
14. Questions de révision
- Quelle est la différence entre
age = 18etage == 18? Que se passe-t-il si on met le premier dans unif, et le second seul sur une ligne ? - Dans une chaîne
if/elif/elif, combien de blocs peuvent s'exécuter au maximum ? Et si deux conditions sont vraies ? - Pourquoi
"18" == 18ne produit-il aucune erreur, et que vaut-il ? Pourquoi est-ce plus dangereux qu'unTypeError? - Qu'est-ce qui « ferme » un bloc en Python, puisqu'il n'y a ni accolade ni mot-clé de fin ?
- À quel
ifunelses'accroche-t-il quand il y a des conditions imbriquées ? - Pourquoi faut-il tester
score >= 90AVANTscore >= 50dans un barème ? - Cite deux erreurs de cette leçon détectées avant l'exécution (aucune ligne ne tourne) et une détectée pendant. Comment les distingues-tu au traceback ?
- Que vaut
2 < 3 <= 3et comment Python le lit-il ?
15. Checklist de compréhension
- J'écris un
if/elif/elseà trois branches sans modèle sous les yeux. - Je peux expliquer à voix haute la différence entre
=et==et je repère l'erreur dans du code en quelques secondes. - Je sais pourquoi l'exercice 9-b affichait
Passablepour 95, sans exécuter. - Je convertis mes
input()avant toute comparaison, par réflexe. - Je peux provoquer volontairement les deux
IndentationErrorde la section 6 et les lire. - Je sais dire quel
elseappartient à quelifdans du code imbriqué. - Le mini-projet convertisseur tourne : trois conversions justes + choix invalide géré proprement.
Si une case reste vide : refais les exercices de la section correspondante demain, AVANT d'ouvrir la leçon suivante.
16. Commit conseillé
git add lessons/level-02-conditions-boucles/exercices/mes-reponses/
git commit -m "exercises: complete lesson 02-1 if elif else"
Puis, si c'est ta fin de session : entrée de journal + git push.