1680 lines
44 KiB
Markdown
1680 lines
44 KiB
Markdown
# Chapitre 02 — Les conditions : faire des choix
|
||
|
||
> **⏱️ Durée estimée :** 4 heures
|
||
>
|
||
> **📋 Prérequis :** [Chapitre 01 — Variables, types et opérateurs](01-variables-types-operateurs.md) : 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` |
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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.
|
||
|
||
```python
|
||
print("chat" == "chat")
|
||
print("chat" == "Chat")
|
||
print("chat" == "chat ")
|
||
print("été" == "ete")
|
||
```
|
||
|
||
Sortie :
|
||
|
||
```text
|
||
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** :
|
||
|
||
```python
|
||
print("abricot" < "banane")
|
||
print("Zoo" < "abc")
|
||
print("10" < "9")
|
||
```
|
||
|
||
Sortie :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```python
|
||
print(0.1 + 0.2 == 0.3)
|
||
print(abs((0.1 + 0.2) - 0.3) < 0.000001)
|
||
```
|
||
|
||
Sortie :
|
||
|
||
```text
|
||
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](09-modules-bibliotheque-standard.md).)
|
||
|
||
#### 2.3. Comparaisons enchaînées
|
||
|
||
Python permet d'écrire des encadrements comme en maths :
|
||
|
||
```python
|
||
note = 14
|
||
print(10 <= note <= 20) # note est-elle entre 10 et 20 ?
|
||
print(0 < note < 10)
|
||
```
|
||
|
||
Sortie :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```python
|
||
temperature = 31
|
||
|
||
if temperature > 30:
|
||
print("Il fait très chaud !")
|
||
print("Pense à boire de l'eau.")
|
||
|
||
print("Bonne journée.")
|
||
```
|
||
|
||
Sortie :
|
||
|
||
```text
|
||
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é.
|
||
|
||
```python
|
||
temperature = 20
|
||
|
||
if temperature > 30:
|
||
print("Il fait très chaud !")
|
||
print("Pense à boire de l'eau.")
|
||
|
||
print("Bonne journée.")
|
||
```
|
||
|
||
Sortie :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```python
|
||
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.
|
||
|
||
```python
|
||
solde = 50
|
||
if solde < 0:
|
||
print("Attention : compte à découvert !")
|
||
print("Contacte ta banque.")
|
||
```
|
||
|
||
Sortie :
|
||
|
||
```text
|
||
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 ») :
|
||
|
||
```python
|
||
niveau = 3
|
||
if niveau > 10:
|
||
pass # TODO : gérer les niveaux bonus plus tard
|
||
print("Partie lancée")
|
||
```
|
||
|
||
Sortie :
|
||
|
||
```text
|
||
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.
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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.
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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 »).
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```python
|
||
note = 18
|
||
|
||
if note >= 10:
|
||
mention = "Passable"
|
||
elif note >= 16:
|
||
mention = "Très bien"
|
||
else:
|
||
mention = "Non admis"
|
||
|
||
print(mention)
|
||
```
|
||
|
||
Sortie :
|
||
|
||
```text
|
||
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 :**
|
||
|
||
```text
|
||
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.
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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.
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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
|
||
|
||
```python
|
||
age = 25
|
||
a_le_permis = True
|
||
|
||
if age >= 18 and a_le_permis:
|
||
print("Tu peux louer une voiture.")
|
||
```
|
||
|
||
Sortie :
|
||
|
||
```text
|
||
Tu peux louer une voiture.
|
||
```
|
||
|
||
#### 7.2. `or` : au moins une doit être vraie
|
||
|
||
```python
|
||
jour = "dimanche"
|
||
|
||
if jour == "samedi" or jour == "dimanche":
|
||
print("C'est le week-end !")
|
||
```
|
||
|
||
Sortie :
|
||
|
||
```text
|
||
C'est le week-end !
|
||
```
|
||
|
||
#### 7.3. `not` : inverse une condition
|
||
|
||
```python
|
||
est_connecte = False
|
||
|
||
if not est_connecte:
|
||
print("Merci de te connecter.")
|
||
```
|
||
|
||
Sortie :
|
||
|
||
```text
|
||
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** :
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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.
|
||
|
||
```python
|
||
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) :
|
||
|
||
```text
|
||
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` :
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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](04-structures-de-donnees.md).
|
||
|
||
### 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](06-chaines-et-comprehensions.md)) 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 :
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```text
|
||
valeur_si_vrai if condition else valeur_si_faux
|
||
```
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
mineur
|
||
Tu as 1 message.
|
||
Tu as 3 messages.
|
||
```
|
||
|
||
C'est l'équivalent de :
|
||
|
||
```python
|
||
age = 16
|
||
if age >= 18:
|
||
statut = "majeur"
|
||
else:
|
||
statut = "mineur"
|
||
print(statut)
|
||
```
|
||
|
||
Sortie :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
Voici l'aide.
|
||
```
|
||
|
||
Depuis Python 3.10, l'instruction **`match`** permet d'écrire cela plus clairement :
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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` :
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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** :
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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.
|
||
|
||
```python
|
||
# 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 :
|
||
|
||
```text
|
||
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
|
||
|
||
```python
|
||
age = 20
|
||
if age >= 18
|
||
print("Majeur")
|
||
```
|
||
|
||
```text
|
||
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
|
||
|
||
```python
|
||
age = 20
|
||
if age >= 18:
|
||
print("Majeur")
|
||
```
|
||
|
||
```text
|
||
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
|
||
|
||
```python
|
||
age = 20
|
||
if age >= 18:
|
||
print("Majeur")
|
||
print("fin")
|
||
```
|
||
|
||
```text
|
||
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 `==`
|
||
|
||
```python
|
||
age = 20
|
||
if age = 18:
|
||
print("Pile 18 ans")
|
||
```
|
||
|
||
```text
|
||
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
|
||
|
||
```python
|
||
age = input("Âge : ")
|
||
if age >= 18:
|
||
print("Majeur")
|
||
```
|
||
|
||
```text
|
||
Â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`
|
||
|
||
```python
|
||
couleur = "vert"
|
||
if couleur == "rouge" or "bleu":
|
||
print(f"{couleur} est une couleur primaire")
|
||
```
|
||
|
||
Sortie :
|
||
|
||
```text
|
||
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` :
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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
|
||
|
||
```python
|
||
x = 3
|
||
if x > 0:
|
||
print("positif")
|
||
print("test terminé")
|
||
else:
|
||
print("négatif ou nul")
|
||
```
|
||
|
||
```text
|
||
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 :
|
||
|
||
```python
|
||
vitesse = 150
|
||
if vitesse > 90:
|
||
print("Amende légère")
|
||
elif vitesse > 130:
|
||
print("Retrait de permis")
|
||
```
|
||
|
||
Sortie :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```text
|
||
Â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 :
|
||
|
||
```text
|
||
Année : 2024
|
||
2024 est bissextile.
|
||
```
|
||
|
||
```text
|
||
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 :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```text
|
||
Numéro du jour (1-7) : 6
|
||
samedi (week-end)
|
||
```
|
||
|
||
```text
|
||
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 :
|
||
|
||
```text
|
||
Côté a : 3
|
||
Côté b : 4
|
||
Côté c : 5
|
||
Triangle quelconque. Il est rectangle.
|
||
```
|
||
|
||
```text
|
||
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 :
|
||
- si le montant est insuffisant, indique combien il manque ;
|
||
- 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 :
|
||
|
||
```text
|
||
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 :
|
||
- 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 ») ;
|
||
- au moins une question à réponse **numérique** entière ;
|
||
- 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) ;
|
||
- 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 ;
|
||
- au moins une question **vrai/faux**.
|
||
3. Après chaque réponse, le programme affiche « Bonne réponse ! » ou la bonne réponse.
|
||
4. 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 ».
|
||
5. 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 :**
|
||
|
||
```text
|
||
===== 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
|
||
|
||
<details>
|
||
<summary>Corrigé de l'exercice 1</summary>
|
||
|
||
```python
|
||
# 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 :
|
||
|
||
```text
|
||
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.
|
||
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Corrigé de l'exercice 2</summary>
|
||
|
||
```python
|
||
# 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 :
|
||
|
||
```text
|
||
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.
|
||
|
||
```python
|
||
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 :
|
||
|
||
```text
|
||
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.
|
||
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Corrigé de l'exercice 3</summary>
|
||
|
||
```python
|
||
# 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 :
|
||
|
||
```text
|
||
Â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`.
|
||
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Corrigé de l'exercice 4</summary>
|
||
|
||
```python
|
||
# 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 :
|
||
|
||
```text
|
||
Année : 2024
|
||
2024 est bissextile.
|
||
```
|
||
|
||
```text
|
||
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.
|
||
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Corrigé de l'exercice 5</summary>
|
||
|
||
```python
|
||
# 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 :
|
||
|
||
```text
|
||
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.
|
||
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Corrigé de l'exercice 6</summary>
|
||
|
||
```python
|
||
# 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 :
|
||
|
||
```text
|
||
Numéro du jour (1-7) : 6
|
||
samedi (week-end)
|
||
```
|
||
|
||
```text
|
||
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.
|
||
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Corrigé de l'exercice 7</summary>
|
||
|
||
```python
|
||
# 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 :
|
||
|
||
```text
|
||
Côté a : 3
|
||
Côté b : 4
|
||
Côté c : 5
|
||
Triangle quelconque. Il est rectangle.
|
||
```
|
||
|
||
```text
|
||
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).
|
||
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Corrigé de l'exercice 8</summary>
|
||
|
||
```python
|
||
# 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 :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```text
|
||
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`.
|
||
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Corrigé du mini-projet</summary>
|
||
|
||
```python
|
||
# 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é) :
|
||
|
||
```text
|
||
===== 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.
|
||
|
||
</details>
|
||
|
||
---
|
||
|
||
## 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](01-variables-types-operateurs.md) | [Sommaire](README.md) | [Chapitre suivant →](03-boucles.md)
|