Aller au contenu

Chapitre 02 — Les conditions : faire des choix

⏱️ Durée estimée : 4 heures

📋 Prérequis : Chapitre 01 — Variables, types et opérateurs : variables, types int/float/str/bool, input() avec conversion, f-strings.

🎯 Objectifs — À la fin de ce chapitre, tu sauras : - comparer des valeurs avec ==, !=, <, >, <=, >= et obtenir un booléen ; - faire exécuter du code seulement si une condition est vraie, avec if, elif et else ; - indenter correctement ton code pour délimiter des blocs ; - combiner plusieurs conditions avec and, or et not ; - utiliser l'expression conditionnelle sur une ligne (a if condition else b) ; - choisir parmi plusieurs cas de façon élégante avec match / case.


Cours

1. Pourquoi des conditions ?

Jusqu'ici, tes programmes exécutaient toutes leurs lignes, de haut en bas, quoi qu'il arrive. Mais la vie est faite de choix : s'il pleut, je prends un parapluie, sinon je prends mes lunettes de soleil. Un distributeur de billets vérifie si ton code est correct. Un jeu vérifie si tu as perdu toutes tes vies.

Les conditions permettent à un programme de prendre des décisions : exécuter certaines lignes seulement dans certaines situations. Pour cela, il faut d'abord savoir poser des questions dont la réponse est oui ou non, c'est-à-dire True ou False.

2. Les opérateurs de comparaison

Un opérateur de comparaison compare deux valeurs et renvoie un booléen (True ou False).

Opérateur Signification Exemple Résultat
== est égal à 5 == 5 True
!= est différent de 5 != 3 True
< est strictement inférieur à 3 < 5 True
> est strictement supérieur à 3 > 5 False
<= est inférieur ou égal à 5 <= 5 True
>= est supérieur ou égal à 4 >= 5 False
age = 17
print(age >= 18)
print(age == 17)
print(age != 17)

majeur = age >= 18      # on peut stocker le résultat dans une variable
print(majeur, type(majeur))

Sortie :

False
True
False
False <class 'bool'>

⚠️ = n'est pas == ! Un seul = affecte une valeur (« colle l'étiquette »). Deux == comparent (« est-ce que c'est égal ? »). C'est l'erreur la plus fréquente de ce chapitre.

2.1. Comparer des chaînes

On peut comparer des chaînes. L'égalité est stricte : majuscules, espaces et accents comptent.

print("chat" == "chat")
print("chat" == "Chat")
print("chat" == "chat ")
print("été" == "ete")

Sortie :

True
False
False
False

On peut aussi comparer des chaînes avec < et > : c'est l'ordre « alphabétique », mais attention, il suit en réalité les codes des caractères. Toutes les majuscules passent avant toutes les minuscules, et les chiffres sont comparés caractère par caractère :

print("abricot" < "banane")
print("Zoo" < "abc")
print("10" < "9")

Sortie :

True
True
True

"10" < "9" est vrai, car on compare d'abord "1" et "9", et "1" vient avant. Encore une bonne raison de convertir les saisies en nombres avec int() !

2.2. Comparer des nombres à virgule

À cause de l'imprécision des floats vue au chapitre 01, l'égalité exacte entre floats est piégeuse :

print(0.1 + 0.2 == 0.3)
print(abs((0.1 + 0.2) - 0.3) < 0.000001)

Sortie :

False
True

Pour comparer deux floats, on vérifie plutôt que leur écart est minuscule. (Le module math propose math.isclose() pour ça, voir le chapitre 09.)

2.3. Comparaisons enchaînées

Python permet d'écrire des encadrements comme en maths :

note = 14
print(10 <= note <= 20)    # note est-elle entre 10 et 20 ?
print(0 < note < 10)

Sortie :

True
False

10 <= note <= 20 signifie « 10 <= note et note <= 20 ». C'est très lisible, profites-en.

3. L'instruction if

Voici la structure de base :

temperature = 31

if temperature > 30:
    print("Il fait très chaud !")
    print("Pense à boire de l'eau.")

print("Bonne journée.")

Sortie :

Il fait très chaud !
Pense à boire de l'eau.
Bonne journée.

Décortiquons :

  1. Le mot-clé if (« si »), suivi d'une condition (temperature > 30), suivie de deux-points :.
  2. En dessous, un bloc de lignes indentées (décalées vers la droite de 4 espaces). Ces lignes ne s'exécutent que si la condition vaut True.
  3. La première ligne qui n'est plus indentée (print("Bonne journée.")) marque la fin du bloc : elle s'exécute dans tous les cas.

Avec temperature = 20, la condition est fausse : le bloc est sauté.

temperature = 20

if temperature > 30:
    print("Il fait très chaud !")
    print("Pense à boire de l'eau.")

print("Bonne journée.")

Sortie :

Bonne journée.

3.1. L'indentation : la grammaire de Python

Dans beaucoup de langages, on délimite les blocs avec des accolades { }. Python, lui, utilise l'indentation : le décalage en début de ligne. Ce n'est pas une simple question d'esthétique : c'est obligatoire, et c'est ce qui dit à Python quelles lignes font partie du bloc.

Pense à une recette : « Si tu as des invités : mets la table, sors les verres. » Les actions « mets la table » et « sors les verres » sont en retrait, car elles dépendent du « si ».

Règles d'or :

  • la convention est d'indenter avec 4 espaces (VS Code le fait automatiquement quand tu appuies sur Tab ou après les :) ;
  • toutes les lignes d'un même bloc ont exactement la même indentation ;
  • ne mélange jamais espaces et tabulations.

Compare ces deux programmes, qui ne diffèrent que par l'indentation de la dernière ligne :

solde = 50
if solde < 0:
    print("Attention : compte à découvert !")
    print("Contacte ta banque.")

Ce premier programme n'affiche rien : la condition est fausse, donc les deux print sont sautés.

solde = 50
if solde < 0:
    print("Attention : compte à découvert !")
print("Contacte ta banque.")

Sortie :

Contacte ta banque.

Dans le second programme, le dernier print ne fait plus partie du bloc : il s'exécute toujours.

3.2. Un bloc vide : pass

Un bloc ne peut pas être vide. Si tu veux prévoir un if sans encore savoir quoi mettre dedans, écris pass (« ne rien faire ») :

niveau = 3
if niveau > 10:
    pass  # TODO : gérer les niveaux bonus plus tard
print("Partie lancée")

Sortie :

Partie lancée

4. else : sinon…

else (« sinon ») introduit le bloc à exécuter quand la condition est fausse. Exactement l'un des deux blocs est exécuté, jamais les deux, jamais aucun.

age = int(input("Quel âge as-tu ? "))

if age >= 18:
    print("Tu es majeur.")
else:
    print("Tu es mineur.")
    print(f"Encore {18 - age} an(s) à attendre.")

Exemple d'exécution :

Quel âge as-tu ? 15
Tu es mineur.
Encore 3 an(s) à attendre.

Le else est aligné avec le if, se termine par :, et n'a pas de condition.

Un grand classique : tester si un nombre est pair, avec le modulo vu au chapitre 01.

nombre = int(input("Un nombre entier : "))

if nombre % 2 == 0:
    print(f"{nombre} est pair.")
else:
    print(f"{nombre} est impair.")

Exemple d'exécution :

Un nombre entier : 7
7 est impair.

5. elif : sinon, si…

Quand il y a plus de deux possibilités, on enchaîne des elif (contraction de else if, « sinon, si »).

note = float(input("Ta note sur 20 : "))

if note >= 16:
    mention = "Très bien"
elif note >= 14:
    mention = "Bien"
elif note >= 12:
    mention = "Assez bien"
elif note >= 10:
    mention = "Passable"
else:
    mention = "Non admis"

print(f"Mention : {mention}")

Exemple d'exécution :

Ta note sur 20 : 14.5
Mention : Bien

Comment Python lit ce code : il teste les conditions dans l'ordre, de haut en bas, et exécute uniquement le premier bloc dont la condition est vraie. Ensuite, il saute directement après toute la structure, sans regarder les autres.

Avec 14.5 : 14.5 >= 16 est faux → on passe ; 14.5 >= 14 est vrai → mention « Bien », et c'est fini. Peu importe que 14.5 >= 12 soit aussi vrai : on ne le teste même pas.

C'est pour cela que l'ordre des conditions est crucial. Regarde ce qui se passe si on les inverse :

note = 18

if note >= 10:
    mention = "Passable"
elif note >= 16:
    mention = "Très bien"
else:
    mention = "Non admis"

print(mention)

Sortie :

Passable

Un 18 qui obtient « Passable » ! La première condition vraie gagne, et 18 >= 10 est vrai. Quand les conditions se chevauchent, va du plus restrictif au moins restrictif.

Résumé de la structure complète :

if condition_1:        ← obligatoire, toujours en premier
    ...
elif condition_2:      ← facultatif, autant qu'on veut
    ...
elif condition_3:
    ...
else:                  ← facultatif, toujours en dernier, sans condition
    ...

💡 if successifs ou elif ? Plusieurs if à la suite sont indépendants : chacun est testé. Une chaîne if/elif est exclusive : un seul bloc s'exécute.

nombre = 15

print("Avec des if séparés :")
if nombre % 3 == 0:
    print("  divisible par 3")
if nombre % 5 == 0:
    print("  divisible par 5")

print("Avec elif :")
if nombre % 3 == 0:
    print("  divisible par 3")
elif nombre % 5 == 0:
    print("  divisible par 5")

Sortie :

Avec des if séparés :
  divisible par 3
  divisible par 5
Avec elif :
  divisible par 3

6. Les conditions imbriquées

Un bloc peut contenir lui-même un if. On parle de conditions imbriquées. Chaque niveau ajoute 4 espaces d'indentation.

a_un_billet = True
age = 10

if a_un_billet:
    print("Bienvenue au parc !")
    if age < 12:
        print("Voici ton bracelet enfant.")
    else:
        print("Voici ton bracelet adulte.")
else:
    print("Merci de passer par la billetterie.")

Sortie :

Bienvenue au parc !
Voici ton bracelet enfant.

Remarque if a_un_billet: : comme a_un_billet est déjà un booléen, inutile d'écrire if a_un_billet == True:. C'est plus court et plus naturel (« si on a un billet »).

💡 Au-delà de deux ou trois niveaux d'imbrication, le code devient difficile à lire. Les opérateurs logiques de la section suivante permettent souvent d'« aplatir » les conditions.

7. Les opérateurs logiques and, or, not

Ils permettent de combiner plusieurs conditions.

7.1. and : les deux doivent être vraies

age = 25
a_le_permis = True

if age >= 18 and a_le_permis:
    print("Tu peux louer une voiture.")

Sortie :

Tu peux louer une voiture.

7.2. or : au moins une doit être vraie

jour = "dimanche"

if jour == "samedi" or jour == "dimanche":
    print("C'est le week-end !")

Sortie :

C'est le week-end !

7.3. not : inverse une condition

est_connecte = False

if not est_connecte:
    print("Merci de te connecter.")

Sortie :

Merci de te connecter.

7.4. Tables de vérité

a b a and b a or b not a
True True True True False
True False False True False
False True False True True
False False False False True

Moyen mnémotechnique : and est exigeant (tout doit être vrai), or est arrangeant (une seule suffit).

7.5. Priorités et parenthèses

L'ordre de priorité est : d'abord les comparaisons, puis not, puis and, puis or. Comme pour * et +, and passe avant or. Dans le doute, mets des parenthèses :

age = 15
accompagne = False
est_vip = True

# Entrée autorisée si : (majeur OU accompagné) ET VIP
if (age >= 18 or accompagne) and est_vip:
    print("Entrée autorisée (version avec parenthèses)")
else:
    print("Entrée refusée (version avec parenthèses)")

# Sans parenthèses, Python lit : age >= 18 or (accompagne and est_vip)
if age >= 18 or accompagne and est_vip:
    print("Entrée autorisée (version sans parenthèses)")
else:
    print("Entrée refusée (version sans parenthèses)")

Sortie :

Entrée refusée (version avec parenthèses)
Entrée refusée (version sans parenthèses)

Ici les deux résultats coïncident par hasard, mais changeons une valeur :

age = 20
accompagne = False
est_vip = False

if (age >= 18 or accompagne) and est_vip:
    print("Avec parenthèses : autorisé")
else:
    print("Avec parenthèses : refusé")

if age >= 18 or accompagne and est_vip:
    print("Sans parenthèses : autorisé")
else:
    print("Sans parenthèses : refusé")

Sortie :

Avec parenthèses : refusé
Sans parenthèses : autorisé

Les parenthèses changent le sens. Écris toujours ce que tu veux dire explicitement.

7.6. L'évaluation paresseuse

Python est « paresseux » : avec and, si la première condition est fausse, il ne regarde même pas la seconde (le résultat sera faux de toute façon). Avec or, si la première est vraie, il s'arrête aussi. C'est utile pour se protéger d'une erreur :

nb_personnes = 0
total = 120

if nb_personnes != 0 and total / nb_personnes > 50:
    print("Repas cher !")
else:
    print("Pas de calcul possible ou repas raisonnable.")

Sortie :

Pas de calcul possible ou repas raisonnable.

Comme nb_personnes != 0 est faux, la division par zéro n'est jamais tentée.

8. La « vérité » des valeurs

Une condition n'a pas forcément besoin d'être un booléen. Python sait évaluer n'importe quelle valeur comme vraie ou fausse, selon les règles de bool() vues au chapitre 01 :

  • considérés comme faux : False, 0, 0.0, la chaîne vide "" (et None, ainsi que les collections vides, que tu verras plus tard) ;
  • considéré comme vrai : tout le reste.
pseudo = input("Ton pseudo (laisse vide pour rester anonyme) : ")

if pseudo:
    print(f"Bienvenue, {pseudo} !")
else:
    print("Bienvenue, visiteur anonyme !")

Exemple d'exécution (l'utilisateur appuie directement sur Entrée) :

Ton pseudo (laisse vide pour rester anonyme) : 
Bienvenue, visiteur anonyme !

if pseudo: se lit « si le pseudo n'est pas vide ». C'est une écriture très courante en Python.

9. L'opérateur in avec les chaînes

in teste si un morceau de texte est contenu dans une chaîne. C'est une façon très pratique d'éviter les longues séries de or :

email = "camille@exemple.fr"

if "@" in email:
    print("L'adresse contient bien un @.")

lettre = "e"
if lettre in "aeiouy":
    print(f"'{lettre}' est une voyelle.")

if "z" not in email:
    print("Pas de z dans l'adresse.")

Sortie :

L'adresse contient bien un @.
'e' est une voyelle.
Pas de z dans l'adresse.

in fonctionne aussi avec les listes, les tuples et les dictionnaires, que tu découvriras au chapitre 04.

10. Rendre les saisies plus tolérantes

Si tu demandes « oui ou non ? », l'utilisateur peut taper oui, Oui, OUI ou oui… et "Oui" == "oui" est faux. Deux outils des chaînes (détaillés au chapitre 06) règlent le problème :

  • texte.lower() renvoie le texte en minuscules ;
  • texte.strip() renvoie le texte sans les espaces au début et à la fin.

On peut les enchaîner :

reponse = input("Veux-tu continuer (oui/non) ? ").strip().lower()

if reponse == "oui":
    print("C'est parti !")
elif reponse == "non":
    print("À bientôt.")
else:
    print("Je n'ai pas compris.")

Exemple d'exécution :

Veux-tu continuer (oui/non) ?   OUI
C'est parti !

11. L'expression conditionnelle (le « if sur une ligne »)

Quand on veut simplement choisir entre deux valeurs, il existe une forme compacte :

valeur_si_vrai if condition else valeur_si_faux
age = 16
statut = "majeur" if age >= 18 else "mineur"
print(statut)

nb_messages = 1
print(f"Tu as {nb_messages} message{'s' if nb_messages > 1 else ''}.")
nb_messages = 3
print(f"Tu as {nb_messages} message{'s' if nb_messages > 1 else ''}.")

Sortie :

mineur
Tu as 1 message.
Tu as 3 messages.

C'est l'équivalent de :

age = 16
if age >= 18:
    statut = "majeur"
else:
    statut = "mineur"
print(statut)

Sortie :

mineur

💡 Réserve cette forme aux cas simples. Dès qu'il y a plus de deux possibilités ou plusieurs instructions, un if/else classique est plus lisible.

12. match / case : choisir parmi plusieurs cas

Quand tu compares une même valeur à une série de possibilités, une longue chaîne de elif devient vite lourde :

commande = "aide"

if commande == "jouer":
    print("Lancement du jeu...")
elif commande == "aide":
    print("Voici l'aide.")
elif commande == "quitter":
    print("Au revoir !")
else:
    print("Commande inconnue.")

Sortie :

Voici l'aide.

Depuis Python 3.10, l'instruction match permet d'écrire cela plus clairement :

commande = "aide"

match commande:
    case "jouer":
        print("Lancement du jeu...")
    case "aide":
        print("Voici l'aide.")
    case "quitter":
        print("Au revoir !")
    case _:
        print("Commande inconnue.")

Sortie :

Voici l'aide.

Comment ça marche :

  • match valeur: indique la valeur à examiner ;
  • chaque case motif: propose une possibilité. Python les teste dans l'ordre et exécute le premier qui correspond ;
  • case _: (le tiret bas) est le cas « joker » : il correspond à tout. C'est l'équivalent du else. Mets-le toujours en dernier.

Pense à un aiguilleur de gare : le train (la valeur) arrive, et l'aiguilleur l'envoie sur la première voie (le case) qui lui correspond.

12.1. Plusieurs valeurs pour un même cas : |

Le symbole | signifie « ou » dans un case :

jour = "samedi"

match jour:
    case "samedi" | "dimanche":
        print("Week-end : grasse matinée !")
    case "lundi" | "mardi" | "mercredi" | "jeudi" | "vendredi":
        print("Semaine : debout !")
    case _:
        print("Ce n'est pas un jour valide.")

Sortie :

Week-end : grasse matinée !

12.2. Ajouter une condition : la garde if

On peut capturer la valeur dans un nom, puis ajouter une condition avec if après le motif. On appelle ça une garde :

temperature = 23

match temperature:
    case 0:
        print("Pile le point de congélation.")
    case t if t < 0:
        print(f"{t} °C : il gèle !")
    case t if t < 25:
        print(f"{t} °C : température agréable.")
    case t:
        print(f"{t} °C : il fait chaud !")

Sortie :

23 °C : température agréable.

Ici, case t if t < 0: signifie : « appelle la valeur t, et ce cas s'applique si t < 0 ». Le dernier case t: sans garde attrape tout ce qui reste.

💡 match ou if/elif ? Utilise match quand tu compares une seule valeur à des valeurs précises (commandes, choix de menu, codes). Pour des intervalles et des conditions complexes, if/elif reste souvent plus naturel. match est en réalité bien plus puissant (il sait décomposer des structures de données), tu en verras d'autres usages plus tard.

13. Exemple complet : la calculatrice

Récapitulons avec une petite calculatrice qui utilise match, des conditions imbriquées et une vérification de la division par zéro.

# Calculatrice à 4 opérations
a = float(input("Premier nombre : "))
operateur = input("Opérateur (+, -, *, /) : ").strip()
b = float(input("Second nombre : "))

match operateur:
    case "+":
        print(f"{a} + {b} = {a + b}")
    case "-":
        print(f"{a} - {b} = {a - b}")
    case "*" | "x":
        print(f"{a} × {b} = {a * b}")
    case "/":
        if b == 0:
            print("Erreur : division par zéro impossible.")
        else:
            print(f"{a} / {b} = {a / b:.4g}")
    case _:
        print(f"Opérateur « {operateur} » inconnu.")

Exemple d'exécution :

Premier nombre : 10
Opérateur (+, -, *, /) : /
Second nombre : 3
10.0 / 3.0 = 3.333

Le format :.4g affiche au plus 4 chiffres significatifs, en supprimant les zéros inutiles.


Pièges fréquents

Piège 1 — Oublier les deux-points

age = 20
if age >= 18
    print("Majeur")
  File "conditions.py", line 2
    if age >= 18
                ^
SyntaxError: expected ':'

Correction : chaque ligne if, elif, else, match et case se termine par :.

Piège 2 — Oublier d'indenter

age = 20
if age >= 18:
print("Majeur")
  File "conditions.py", line 3
    print("Majeur")
    ^^^^^
IndentationError: expected an indented block after 'if' statement on line 2

Correction : décale la ligne de 4 espaces : print("Majeur").

Piège 3 — Une indentation incohérente

age = 20
if age >= 18:
    print("Majeur")
  print("fin")
  File "conditions.py", line 4
    print("fin")
                ^
IndentationError: unindent does not match any outer indentation level

La dernière ligne a 2 espaces : elle n'est alignée ni avec le bloc (4 espaces) ni avec le if (0 espace).

Correction : chaque ligne doit être alignée exactement sur un niveau existant. Dans VS Code, le nombre d'espaces de la ligne courante est indiqué en bas à droite, et le menu Affichage → Afficher les espaces (Render Whitespace) les rend visibles.

Piège 4 — = au lieu de ==

age = 20
if age = 18:
    print("Pile 18 ans")
  File "conditions.py", line 2
    if age = 18:
       ^^^^^^^^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?

Correction : if age == 18:. Python te le suggère d'ailleurs dans le message.

Piège 5 — Comparer une saisie non convertie

age = input("Âge : ")
if age >= 18:
    print("Majeur")
Âge : 20
Traceback (most recent call last):
  File "conditions.py", line 2, in <module>
    if age >= 18:
       ^^^^^^^^^
TypeError: '>=' not supported between instances of 'str' and 'int'

Python refuse de comparer le texte "20" au nombre 18. Et avec ==, c'est encore plus sournois : "18" == 18 ne provoque pas d'erreur, mais vaut toujours False !

Correction : age = int(input("Âge : ")).

Piège 6 — Le faux ami or

couleur = "vert"
if couleur == "rouge" or "bleu":
    print(f"{couleur} est une couleur primaire")

Sortie :

vert est une couleur primaire

Aucune erreur… mais un résultat faux ! Python lit (couleur == "rouge") or ("bleu"). Or "bleu" est une chaîne non vide, donc considérée comme vraie : la condition est toujours vraie.

Correction : répète la comparaison, ou utilise in :

couleur = "vert"
if couleur == "rouge" or couleur == "bleu" or couleur == "jaune":
    print(f"{couleur} est une couleur primaire")
else:
    print(f"{couleur} n'est pas une couleur primaire")

Sortie :

vert n'est pas une couleur primaire

(Au chapitre 04, tu pourras écrire encore plus simplement if couleur in ("rouge", "bleu", "jaune"):.)

Piège 7 — Un else orphelin

x = 3
if x > 0:
    print("positif")
print("test terminé")
else:
    print("négatif ou nul")
  File "conditions.py", line 5
    else:
    ^^^^
SyntaxError: invalid syntax

Le print non indenté a « fermé » le if : le else n'a plus de if auquel se rattacher. Même erreur si un elif apparaît sans if avant lui.

Correction : le else doit suivre immédiatement le bloc du if (ou du dernier elif), au même niveau d'indentation que le if.

Piège 8 — Des conditions dans le mauvais ordre

Comme vu à la section 5, avec elif, la première condition vraie gagne :

vitesse = 150
if vitesse > 90:
    print("Amende légère")
elif vitesse > 130:
    print("Retrait de permis")

Sortie :

Amende légère

Correction : teste d'abord le cas le plus restrictif (vitesse > 130), puis vitesse > 90.


Exercices

Exercice 1 ⭐ — Positif, négatif ou nul

Écris un programme qui demande un nombre (à virgule possible) et indique s'il est positif, négatif ou nul.

Exemple d'exécution :

Un nombre : -4.5
-4.5 est négatif.

Exercice 2 ⭐ — Le plus grand de trois

Écris un programme qui demande trois nombres entiers et affiche le plus grand, sans utiliser la fonction max().

Exemple d'exécution :

Premier nombre : 12
Deuxième nombre : 45
Troisième nombre : 7
Le plus grand est 45.

Exercice 3 ⭐ — Tarif du cinéma

Un cinéma pratique les tarifs suivants : moins de 14 ans : 5 € ; de 14 à 25 ans inclus : 7.5 € ; de 26 à 64 ans : 11 € ; 65 ans et plus : 8 €. Écris un programme qui demande l'âge et affiche le tarif avec 2 décimales.

Exemple d'exécution :

Âge : 25
Tarif : 7.50 €

Exercice 4 ⭐⭐ — Année bissextile

Une année est bissextile si elle est divisible par 4 mais pas par 100, ou si elle est divisible par 400. Écris un programme qui demande une année et indique si elle est bissextile, en une seule condition combinant and, or et %.

Exemples d'exécution :

Année : 2024
2024 est bissextile.
Année : 1900
1900 n'est pas bissextile.

(2000 est bissextile, 2023 ne l'est pas.)

Exercice 5 ⭐⭐ — Calcul de l'IMC

L'indice de masse corporelle (IMC) se calcule ainsi : IMC = poids / taille², avec le poids en kg et la taille en mètres. Écris un programme qui demande le poids et la taille, affiche l'IMC avec une décimale, puis l'interprétation :

IMC Interprétation
moins de 18.5 insuffisance pondérale
de 18.5 à moins de 25 corpulence normale
de 25 à moins de 30 surpoids
30 et plus obésité

Le programme doit refuser une taille négative ou nulle avec un message d'erreur.

Exemple d'exécution :

Poids (kg) : 70
Taille (m) : 1.75
IMC : 22.9 (corpulence normale)

Exercice 6 ⭐⭐ — Le jour de la semaine

Écris un programme qui demande un numéro de jour entre 1 et 7 et affiche le nom du jour correspondant (1 = lundi) ainsi que « (week-end) » pour le samedi et le dimanche. Utilise match/case. Un numéro invalide affiche un message d'erreur.

Exemples d'exécution :

Numéro du jour (1-7) : 6
samedi (week-end)
Numéro du jour (1-7) : 9
Numéro invalide : 9

Exercice 7 ⭐⭐⭐ — Le type de triangle

Écris un programme qui demande les longueurs des trois côtés d'un triangle (des entiers) et affiche :

  • Ce n'est pas un triangle. si une longueur est inférieure ou égale à 0, ou si un côté est plus grand ou égal à la somme des deux autres ;
  • sinon, Triangle équilatéral., Triangle isocèle. ou Triangle quelconque. ;
  • et, en plus, Il est rectangle. sur la même ligne si le triangle est rectangle (théorème de Pythagore : le carré du plus grand côté est égal à la somme des carrés des deux autres).

Exemples d'exécution :

Côté a : 3
Côté b : 4
Côté c : 5
Triangle quelconque. Il est rectangle.
Côté a : 2
Côté b : 2
Côté c : 9
Ce n'est pas un triangle.

Exercice 8 ⭐⭐⭐ — Le distributeur de boissons

Un distributeur propose : 1 café (1.20 €), 2 thé (1.00 €), 3 chocolat (1.50 €). Écris un programme qui :

  1. affiche le menu et demande le numéro de la boisson ;
  2. si le choix est invalide, affiche « Choix invalide. » et s'arrête là ;
  3. sinon, demande le montant inséré et :
  4. si le montant est insuffisant, indique combien il manque ;
  5. sinon, sert la boisson et indique la monnaie rendue (ou « Compte juste, merci ! » si elle vaut 0).

Pour éviter les soucis d'imprécision des floats, fais tous les calculs en centimes (entiers) : round(montant * 100).

Exemple d'exécution :

1. Café (1.20 €)
2. Thé (1.00 €)
3. Chocolat (1.50 €)
Ton choix : 3
Montant inséré (€) : 2
Voici ton chocolat. Monnaie rendue : 0.50 €

Mini-projet

Le quiz de culture générale

Objectif : écrire un programme quiz.py qui pose 5 questions à l'utilisateur, compte les points et affiche une appréciation finale.

Cahier des charges :

  1. Le programme affiche un titre et demande le prénom du joueur. Si le prénom est vide, il utilise « Joueur mystère ».
  2. Il pose 5 questions de types variés :
  3. au moins une question à réponse texte, tolérante aux majuscules et aux espaces (strip().lower()), et qui accepte plusieurs variantes de réponse (par exemple « paris » ou « la ville de paris ») ;
  4. au moins une question à réponse numérique entière ;
  5. au moins une question à réponse numérique où une réponse approchée rapporte la moitié des points (par exemple, à 5 ans près pour une date) ;
  6. au moins une question à choix multiples (a, b, c, d) traitée avec match/case, qui affiche un message spécifique pour chaque mauvaise réponse ;
  7. au moins une question vrai/faux.
  8. Après chaque réponse, le programme affiche « Bonne réponse ! » ou la bonne réponse.
  9. Le score (qui peut contenir des demi-points) est affiché à la fin sur 5, avec une appréciation selon le score : 5 → « Parfait ! », 4 ou plus → « Excellent », 2.5 ou plus → « Pas mal », moins → « Révise un peu ».
  10. Le score est affiché sans décimale inutile : 4 plutôt que 4.0, mais 3.5 reste 3.5 (indice : le format :g).

Exemple d'exécution :

===== QUIZ DE CULTURE GÉNÉRALE =====
Ton prénom : Léa

Question 1 : Quelle est la capitale de la France ?
> Paris 
Bonne réponse !

Question 2 : Combien de pattes a une araignée ?
> 8
Bonne réponse !

Question 3 : En quelle année l'homme a-t-il marché sur la Lune ?
> 1970
Presque ! C'était en 1969. (+0.5)

Question 4 : Quel est le plus grand océan ?
  a) Atlantique   b) Indien   c) Pacifique   d) Arctique
> a
Non, l'Atlantique est le deuxième. C'était le Pacifique.

Question 5 : Vrai ou faux : la tomate est un fruit ?
> vrai
Bonne réponse !

Léa, ton score : 3.5 / 5 — Pas mal

Étapes suggérées :

  1. Écris l'en-tête, la saisie du prénom (avec la valeur par défaut) et initialise score = 0.
  2. Écris la question 1 et teste-la avec plusieurs variantes de réponse (PARIS, paris, Lyon).
  3. Ajoute les questions une par une, en testant à chaque fois les bonnes et les mauvaises réponses.
  4. Termine par l'appréciation finale avec une chaîne if/elif/else.

Pistes d'amélioration :

  • Ajoute un « mode difficile » choisi au début, qui change les questions posées.
  • Pour la question numérique, vérifie que la saisie contient bien des chiffres avec reponse.isdigit() avant de convertir, pour éviter le plantage (une approche plus robuste avec try/except sera vue au chapitre 08).
  • Au chapitre 03, tu pourras proposer de rejouer, ou donner plusieurs essais par question ; au chapitre 04, stocker les questions dans une liste.

Corrigés

Corrigé de l'exercice 1
# Positif, négatif ou nul
nombre = float(input("Un nombre : "))

if nombre > 0:
    print(f"{nombre} est positif.")
elif nombre < 0:
    print(f"{nombre} est négatif.")
else:
    print(f"{nombre} est nul.")
Exemple d'exécution :
Un nombre : -4.5
-4.5 est négatif.
Le `else` n'a pas besoin de condition : si le nombre n'est ni positif ni négatif, il est forcément nul.
Corrigé de l'exercice 2
# Le plus grand de trois nombres, sans max()
a = int(input("Premier nombre : "))
b = int(input("Deuxième nombre : "))
c = int(input("Troisième nombre : "))

if a >= b and a >= c:
    plus_grand = a
elif b >= c:          # ici, on sait déjà que a n'est pas le plus grand
    plus_grand = b
else:
    plus_grand = c

print(f"Le plus grand est {plus_grand}.")
Exemple d'exécution :
Premier nombre : 12
Deuxième nombre : 45
Troisième nombre : 7
Le plus grand est 45.
Autre approche, très utile pour la suite : supposer que le premier est le plus grand, puis corriger si besoin.
a, b, c = 12, 45, 7
plus_grand = a
if b > plus_grand:
    plus_grand = b
if c > plus_grand:
    plus_grand = c
print(f"Le plus grand est {plus_grand}.")
Sortie :
Le plus grand est 45.
Ici, on utilise des `if` **indépendants** (pas de `elif`) : chaque nombre doit être comparé. Cette technique se généralisera très bien avec les boucles au chapitre 03.
Corrigé de l'exercice 3
# Tarif du cinéma selon l'âge
age = int(input("Âge : "))

if age < 14:
    tarif = 5
elif age <= 25:
    tarif = 7.5
elif age < 65:
    tarif = 11
else:
    tarif = 8

print(f"Tarif : {tarif:.2f} €")
Exemple d'exécution :
Âge : 25
Tarif : 7.50 €
Grâce à `elif`, inutile d'écrire `14 <= age <= 25` : si on arrive au deuxième test, on sait déjà que `age >= 14`. Attention aux bornes : « de 14 à 25 ans inclus » se traduit par `<= 25`.
Corrigé de l'exercice 4
# Année bissextile
annee = int(input("Année : "))

if (annee % 4 == 0 and annee % 100 != 0) or annee % 400 == 0:
    print(f"{annee} est bissextile.")
else:
    print(f"{annee} n'est pas bissextile.")
Exemples d'exécution :
Année : 2024
2024 est bissextile.
Année : 1900
1900 n'est pas bissextile.
Les parenthèses ne sont pas strictement nécessaires ici (`and` est prioritaire sur `or`), mais elles rendent la règle bien plus lisible. Vérifie aussi : 2000 → divisible par 400 → bissextile ; 2023 → pas divisible par 4 → non.
Corrigé de l'exercice 5
# Calcul de l'IMC
poids = float(input("Poids (kg) : "))
taille = float(input("Taille (m) : "))

if taille <= 0:
    print("Erreur : la taille doit être strictement positive.")
else:
    imc = poids / taille ** 2

    if imc < 18.5:
        interpretation = "insuffisance pondérale"
    elif imc < 25:
        interpretation = "corpulence normale"
    elif imc < 30:
        interpretation = "surpoids"
    else:
        interpretation = "obésité"

    print(f"IMC : {imc:.1f} ({interpretation})")
Exemple d'exécution :
Poids (kg) : 70
Taille (m) : 1.75
IMC : 22.9 (corpulence normale)
On vérifie la taille **avant** de calculer, sinon une taille de 0 provoquerait une `ZeroDivisionError`. Tout le calcul est dans le bloc `else`, d'où le deuxième niveau d'indentation. `taille ** 2` est calculé avant la division, car `**` est prioritaire.
Corrigé de l'exercice 6
# Nom du jour avec match/case
numero = int(input("Numéro du jour (1-7) : "))

match numero:
    case 1:
        print("lundi")
    case 2:
        print("mardi")
    case 3:
        print("mercredi")
    case 4:
        print("jeudi")
    case 5:
        print("vendredi")
    case 6:
        print("samedi (week-end)")
    case 7:
        print("dimanche (week-end)")
    case _:
        print(f"Numéro invalide : {numero}")
Exemples d'exécution :
Numéro du jour (1-7) : 6
samedi (week-end)
Numéro du jour (1-7) : 9
Numéro invalide : 9
On convertit avec `int()`, car `case 6:` compare à l'**entier** 6 : la chaîne `"6"` ne correspondrait à aucun cas. Au chapitre 04, une liste des noms de jours permettra d'écrire ce programme en trois lignes.
Corrigé de l'exercice 7
# Type de triangle
a = int(input("Côté a : "))
b = int(input("Côté b : "))
c = int(input("Côté c : "))

if a <= 0 or b <= 0 or c <= 0 or a >= b + c or b >= a + c or c >= a + b:
    print("Ce n'est pas un triangle.")
else:
    # Nature du triangle
    if a == b == c:
        message = "Triangle équilatéral."
    elif a == b or b == c or a == c:
        message = "Triangle isocèle."
    else:
        message = "Triangle quelconque."

    # Est-il rectangle ? On cherche le plus grand côté.
    if a >= b and a >= c:
        rectangle = a ** 2 == b ** 2 + c ** 2
    elif b >= c:
        rectangle = b ** 2 == a ** 2 + c ** 2
    else:
        rectangle = c ** 2 == a ** 2 + b ** 2

    if rectangle:
        message = message + " Il est rectangle."

    print(message)
Exemples d'exécution :
Côté a : 3
Côté b : 4
Côté c : 5
Triangle quelconque. Il est rectangle.
Côté a : 2
Côté b : 2
Côté c : 9
Ce n'est pas un triangle.
Points importants : - l'équilatéral est testé **avant** l'isocèle (un triangle équilatéral a aussi deux côtés égaux) ; - `a == b == c` est une comparaison enchaînée ; - `rectangle = a ** 2 == b ** 2 + c ** 2` stocke directement le **booléen** résultant de la comparaison, sans `if` ; - comme les côtés sont des entiers, la comparaison avec `==` est exacte (pas de souci de floats).
Corrigé de l'exercice 8
# Distributeur de boissons (calculs en centimes)
print("1. Café (1.20 €)")
print("2. Thé (1.00 €)")
print("3. Chocolat (1.50 €)")
choix = input("Ton choix : ").strip()

match choix:
    case "1":
        boisson, prix_centimes = "café", 120
    case "2":
        boisson, prix_centimes = "thé", 100
    case "3":
        boisson, prix_centimes = "chocolat", 150
    case _:
        boisson, prix_centimes = "", 0

if boisson == "":
    print("Choix invalide.")
else:
    montant = float(input("Montant inséré (€) : "))
    montant_centimes = round(montant * 100)

    if montant_centimes < prix_centimes:
        manque = prix_centimes - montant_centimes
        print(f"Montant insuffisant : il manque {manque / 100:.2f} €.")
    else:
        rendu = montant_centimes - prix_centimes
        if rendu == 0:
            print(f"Voici ton {boisson}. Compte juste, merci !")
        else:
            print(f"Voici ton {boisson}. Monnaie rendue : {rendu / 100:.2f} €")
Exemple d'exécution :
1. Café (1.20 €)
2. Thé (1.00 €)
3. Chocolat (1.50 €)
Ton choix : 3
Montant inséré (€) : 2
Voici ton chocolat. Monnaie rendue : 0.50 €
Autre exécution :
1. Café (1.20 €)
2. Thé (1.00 €)
3. Chocolat (1.50 €)
Ton choix : 1
Montant inséré (€) : 1
Montant insuffisant : il manque 0.20 €.
On garde le choix sous forme de **texte** : ainsi, une saisie comme `abc` tombe simplement dans le `case _` au lieu de faire planter `int()`. Travailler en centimes évite les surprises : `1.5 - 1.2` donne `0.30000000000000004`, alors que `150 - 120` donne exactement `30`.
Corrigé du mini-projet
# quiz.py — Quiz de culture générale en 5 questions
print("===== QUIZ DE CULTURE GÉNÉRALE =====")
prenom = input("Ton prénom : ").strip()
if not prenom:
    prenom = "Joueur mystère"

score = 0

# --- Question 1 : réponse texte, plusieurs variantes acceptées ---
print()
print("Question 1 : Quelle est la capitale de la France ?")
reponse = input("> ").strip().lower()
if reponse == "paris" or reponse == "la ville de paris":
    print("Bonne réponse !")
    score += 1
else:
    print("Raté, c'était Paris.")

# --- Question 2 : réponse numérique exacte ---
print()
print("Question 2 : Combien de pattes a une araignée ?")
reponse = int(input("> "))
if reponse == 8:
    print("Bonne réponse !")
    score += 1
else:
    print("Raté, une araignée a 8 pattes.")

# --- Question 3 : réponse numérique approchée ---
print()
print("Question 3 : En quelle année l'homme a-t-il marché sur la Lune ?")
reponse = int(input("> "))
if reponse == 1969:
    print("Bonne réponse !")
    score += 1
elif abs(reponse - 1969) <= 5:
    print("Presque ! C'était en 1969. (+0.5)")
    score += 0.5
else:
    print("Raté, c'était en 1969.")

# --- Question 4 : choix multiples avec match ---
print()
print("Question 4 : Quel est le plus grand océan ?")
print("  a) Atlantique   b) Indien   c) Pacifique   d) Arctique")
reponse = input("> ").strip().lower()
match reponse:
    case "c":
        print("Bonne réponse !")
        score += 1
    case "a":
        print("Non, l'Atlantique est le deuxième. C'était le Pacifique.")
    case "b":
        print("Non, l'océan Indien est le troisième. C'était le Pacifique.")
    case "d":
        print("Non, l'Arctique est le plus petit ! C'était le Pacifique.")
    case _:
        print("Réponse invalide. C'était le Pacifique.")

# --- Question 5 : vrai / faux ---
print()
print("Question 5 : Vrai ou faux : la tomate est un fruit ?")
reponse = input("> ").strip().lower()
if reponse == "vrai" or reponse == "v":
    print("Bonne réponse !")
    score += 1
else:
    print("Raté : botaniquement, la tomate est bien un fruit.")

# --- Résultat final ---
if score == 5:
    appreciation = "Parfait !"
elif score >= 4:
    appreciation = "Excellent"
elif score >= 2.5:
    appreciation = "Pas mal"
else:
    appreciation = "Révise un peu"

print()
print(f"{prenom}, ton score : {score:g} / 5 — {appreciation}")
Exemple d'exécution (mêmes réponses que dans l'énoncé) :
===== QUIZ DE CULTURE GÉNÉRALE =====
Ton prénom : Léa

Question 1 : Quelle est la capitale de la France ?
> Paris 
Bonne réponse !

Question 2 : Combien de pattes a une araignée ?
> 8
Bonne réponse !

Question 3 : En quelle année l'homme a-t-il marché sur la Lune ?
> 1970
Presque ! C'était en 1969. (+0.5)

Question 4 : Quel est le plus grand océan ?
  a) Atlantique   b) Indien   c) Pacifique   d) Arctique
> a
Non, l'Atlantique est le deuxième. C'était le Pacifique.

Question 5 : Vrai ou faux : la tomate est un fruit ?
> vrai
Bonne réponse !

Léa, ton score : 3.5 / 5 — Pas mal
Remarques : - `if not prenom:` détecte une chaîne vide (section 8 du cours). - `abs(reponse - 1969) <= 5` signifie « à 5 ans près » : `abs()` donne l'écart sans se soucier du signe (1964 et 1974 sont acceptés). - Le `elif` de la question 3 n'est testé que si la réponse n'est pas exacte : une réponse exacte ne rapporte donc pas 1.5 point. - `{score:g}` affiche `4` pour `4` ou `4.0`, et `3.5` pour `3.5`. - On remarque beaucoup de répétitions d'une question à l'autre : les boucles (chapitre 03), les listes (chapitre 04) et les fonctions (chapitre 05) permettront de les éliminer.

Récapitulatif

Points clés :

  • Les opérateurs de comparaison ==, !=, <, >, <=, >= renvoient un booléen. Ne confonds pas = (affectation) et == (comparaison).
  • Structure : if condition: puis un bloc indenté de 4 espaces. elif et else sont facultatifs ; else n'a jamais de condition.
  • Dans une chaîne if/elif/else, seul le premier bloc dont la condition est vraie s'exécute : l'ordre des conditions compte.
  • and (toutes vraies), or (au moins une vraie), not (inverse). Priorité : not > and > or ; mets des parenthèses pour être clair.
  • a <= x <= b permet d'écrire un encadrement.
  • 0, 0.0, "" sont considérés comme faux ; if texte: signifie « si le texte n'est pas vide ».
  • in teste si un morceau de texte est contenu dans une chaîne.
  • valeur1 if condition else valeur2 choisit entre deux valeurs sur une ligne.
  • match valeur: / case ...: / case _: compare une valeur à plusieurs cas ; | regroupe plusieurs valeurs, case x if ...: ajoute une garde.
  • Convertis toujours les saisies numériques avant de les comparer, et normalise les saisies texte avec .strip().lower().

Checklist de validation :

  • Je sais écrire une condition avec if, elif et else, avec les : et l'indentation correcte.
  • Je sais prédire quel bloc s'exécute dans une chaîne de elif, et j'ordonne mes conditions en conséquence.
  • Je sais combiner des conditions avec and, or, not et je connais le piège x == "a" or "b".
  • Je sais utiliser une comparaison enchaînée et l'expression a if condition else b.
  • Je sais écrire un match/case avec un cas par défaut _.
  • Mes programmes ne plantent plus sur une division par zéro grâce à une vérification préalable.
  • J'ai réalisé le quiz et testé chaque question avec une bonne et une mauvaise réponse.

← Chapitre précédent | Sommaire | Chapitre suivant →