Prendre une décision
Ce que ce chapitre apporte
- Écrire une comparaison et ranger son résultat dans une variable Boolean.
- Choisir entre deux chemins avec le bloc If, et prévoir ce qui s'exécute dans chaque cas.
- Organiser plusieurs cas avec des If imbriqués, dans un ordre qui ne laisse aucune valeur sans réponse.
- Combiner des conditions avec and, or et not, en maîtrisant les priorités.
- Construire un jeu de valeurs qui passe par chaque chemin et teste chaque seuil.
Un programme qui exécute toujours les mêmes formes dans le même ordre ne sait réagir à rien. Dès qu'une mesure dépasse un seuil, qu'une vanne est ouverte ou qu'une pièce sort de ses tolérances, il faut choisir un chemin. Ce chapitre apprend à écrire la question que pose le losange, à organiser plusieurs cas sans en oublier ni en compter deux fois, et à vérifier une décision là où elle se trompe le plus souvent : exactement au seuil.
Une question à réponse vraie ou fausse
Un capteur mesure la pression dans un réservoir d'air comprimé. La question « la pression dépasse-t-elle le seuil de sécurité ? » n'a que deux réponses possibles : oui ou non. Flowgorithm range ce genre de réponse dans une variable de type Boolean, qui ne peut valoir que true ou false.
Une comparaison confronte deux valeurs et produit un booléen : true si elle est vérifiée, false sinon. Le résultat peut être rangé dans une variable Boolean, ou utilisé directement comme condition d'un losange.
| Question | Écriture recommandée | Autre écriture acceptée |
|---|---|---|
| égal à | == | = |
| différent de | != | <> |
| strictement inférieur, inférieur ou égal | <, <= | |
| strictement supérieur, supérieur ou égal | >, >= |
La comparaison pression > seuil produit un booléen, rangé dans surpression, qui apparaît en bleu-vert dans la fenêtre des variables. Exécuter pas à pas, puis relancer avec une pression de 5 : la variable change de valeur.
Flowgorithm accepte = et == pour comparer : l'affectation a sa propre forme, le rectangle, et ne s'écrit pas dans un losange. Python, lui, réserve = au rangement et == à la comparaison, et la confusion y est une erreur classique. Ce cours écrit ==, !=, and, or et not, les écritures de Python.
Le bloc If : deux chemins qui se rejoignent
Le losange porte une condition. Si elle vaut true, le programme prend la branche True, à droite ; si elle vaut false, la branche False, à gauche. Les deux chemins se retrouvent ensuite en un point de jonction, et le programme continue.
False à gauche, True à droite. Relancer avec une pression de 5 pour passer par l'autre branche : la dernière sortie s'affiche dans les deux cas.
Avec la saisie 7.2, la console affiche « Ouvrir la soupape de sécurité » puis « Contrôle terminé » ; avec 5, « Pression normale » puis « Contrôle terminé ». Ce qui est placé après la jonction ne dépend pas de la condition : une forme qui ne concerne qu'un cas va dans sa branche, jamais après.
Une branche peut rester vide : le chemin existe, mais il ne fait rien. C'est le cas le plus fréquent en surveillance, où l'on n'agit qu'en cas d'anomalie.
La branche False est vide. Avec 5, le programme passe directement à la jonction ; avec 7.2, il affiche l'alerte et compte une alerte de plus.
Plusieurs cas : des If imbriqués
Le niveau de charge d'une batterie de secours se classe en trois cas : critique sous 10 %, faible sous 30 %, correct au-delà. Un losange n'a que deux sorties ; pour trois cas, on place un second losange dans une branche du premier.
Le second test n'est posé que si le premier est faux : arrivé là, la charge vaut déjà au moins 10. Essayer 5, 25 puis 80.
Le second losange n'a pas besoin de vérifier charge >= 10 : il ne s'exécute que dans la branche False du premier, donc quand la charge n'est pas sous 10. C'est tout l'intérêt de l'imbrication : chaque test hérite de ce que les précédents ont éliminé.
Inverser les deux tests (d'abord charge < 30, puis charge < 10) donne un programme qui s'exécute sans erreur et qui se trompe : avec une charge de 5, le premier test est déjà vrai, le programme affiche « Charge faible », et le cas critique n'est jamais atteint. Avec des seuils « inférieur à », tester du plus petit au plus grand.
Chaque valeur doit tomber dans un seul cas. Trois If indépendants, posés l'un après l'autre, ne le garantissent pas :
Trois décisions indépendantes, toutes évaluées. Avec 5, la console affiche « Charge critique » puis « Charge faible » : deux diagnostics contradictoires.
Python écrit une cascade sans l'imbriquer visuellement, avec elif (« sinon si ») ; l'indentation remplace les branches du losange.
Conditions composées
Un bain de traitement thermique est correct si sa température est comprise entre 60 et 80 °C. Cette phrase contient deux comparaisons : la température est au moins 60, et elle est au plus 80. and exige que les deux conditions soient vraies ; or se contente d'une seule ; not inverse.
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 |
Ranger la condition dans dansPlage lui donne un nom : le losange se lit comme une phrase, et la réponse peut resservir plus loin sans réécrire la comparaison. Essayer 59, 60, 80 et 81.
60 <= temperature <= 80 n'est pas une double comparaison : une comparaison confronte deux valeurs, pas trois. La première produirait un booléen, et c'est ce booléen, et non la température, qui serait comparé à 80. « Compris entre » s'écrit toujours avec deux comparaisons reliées par and.
L'erreur inverse est plus sournoise, parce qu'elle ne provoque aucune erreur :
Une condition toujours vraie. Avec 95, le bain est jugé correct : toute température est au-dessus de 60 ou au-dessous de 80, et aucune saisie ne mène à la branche False. Une plage se décrit avec and.
Les priorités
Une expression ne s'évalue pas de gauche à droite mais selon la priorité des opérateurs, de la plus forte à la plus faible : not, puis les calculs et &, puis les comparaisons, puis and, et enfin or. Conséquences :
capotOuvert or temperature > 90 and moteurActifse litcapotOuvert or (temperature > 90 and moteurActif). AveccapotOuvertàtrue,temperatureà 95 etmoteurActifàfalse, elle vauttrue; la version(capotOuvert or temperature > 90) and moteurActifvautfalse. Dès queandetorse mêlent, écrire les parenthèses qui disent l'intention.notest plus fort qu'une comparaison :not charge < 10s'évalue(not charge) < 10, etnotreçoit un nombre au lieu d'une condition. Écrirenot (charge < 10), ou plus simplementcharge >= 10.- Nier une comparaison stricte fait apparaître l'égalité :
not (a > 10)équivaut àa <= 10, et non àa < 10. De même,not (a == b)équivaut àa != b.
Un not sans parenthèses. Exécuter : le programme s'arrête sur le losange, car not s'applique au nombre charge. Ajouter les parenthèses autour de charge < 10 corrige l'erreur.
Les valeurs limites
Les règles métier s'écrivent en français, et c'est à la traduction que l'erreur se glisse. « Une pièce est refusée si sa masse dépasse 250 g » donne masse > 250 ; « refusée dès qu'elle atteint 250 g » donne masse >= 250. Les deux programmes répondent pareil pour 200 ou 300 g. Ils ne diffèrent qu'en un point : 250 exactement.
« Refusée si la masse dépasse 250 g ». Exécuter avec 250 : la pièce est acceptée. Remplacer > par >= change ce seul cas.
Un test avec 200 et 300 ne dit rien de la frontière. Pour vérifier une décision, construire un jeu de valeurs qui :
- passe au moins une fois par chaque chemin de l'organigramme ;
- prend exactement chaque seuil, puis une valeur juste en dessous et une juste au-dessus.
Pour la batterie (seuils 10 et 30), un jeu suffisant, où chaque valeur vérifie quelque chose que les autres ne vérifient pas :
| Charge saisie | Chemin attendu | Ce que la valeur vérifie |
|---|---|---|
| 5 | Charge critique | premier chemin |
| 9 | Charge critique | juste sous le premier seuil |
| 10 | Charge faible | le premier seuil exactement |
| 29 | Charge faible | juste sous le second seuil |
| 30 | Charge correcte | le second seuil exactement |
| 80 | Charge correcte | dernier chemin |
Chaque ligne s'obtient en relançant l'organigramme de la batterie avec la saisie correspondante. Si l'énoncé disait « critique jusqu'à 10 % inclus », la ligne 10 devrait donner « Charge critique », et c'est elle seule qui révélerait l'erreur.
Fil rouge : la cuve de traitement
Étape 3 : la cuve calcule son taux de remplissage (étape 2). Elle doit maintenant en tirer deux décisions.
- Le diagnostic, trois cas donc deux
Ifimbriqués : « Débordement imminent » au-dessus du seuil haut (90 %), « Niveau bas » en dessous du seuil bas (10 %), « Niveau normal » sinon. - La pompe de remplissage, une condition composée rangée dans une variable : autorisée seulement si le taux est sous le seuil haut et que la vanne de sortie est fermée. L'opérateur saisit l'état de la vanne (
truesi elle est fermée).
Étape 3 du fil rouge. Saisies proposées : rayon 1.5, hauteur 4, 26000 litres, vanne fermée. Relancer avec 12000 litres, puis avec la vanne ouverte (false).
Avec les saisies proposées, le programme affiche « Taux de remplissage : 92.0 % », « Débordement imminent » et « Pompe de remplissage bloquée » : la vanne est fermée, mais la cuve est trop pleine. Avec 12000 litres et la vanne fermée, il affiche « Taux de remplissage : 42.4 % », « Niveau normal » et « Pompe de remplissage autorisée ». Avec 12000 litres et la vanne ouverte, la pompe est bloquée.
Au seuil haut exactement, pour un taux de 90 % tout juste, le diagnostic dit « Niveau normal » (taux > 90 est faux) mais la pompe est bloquée (taux < 90 est faux aussi). Les deux décisions respectent leurs règles : « au-dessus du seuil » et « sous le seuil » excluent tous deux l'égalité. Ce cas limite sera testé à l'étape 6.
Exercices type
Un arbre usiné est conforme si son diamètre est compris entre 19,95 et 20,05 mm, bornes incluses. Un technicien écrit le test ci-dessous. Qu'affiche-t-il pour 19.95, 20 et 20.05, et comment le corriger ?
Le test du technicien.
Les deux comparaisons sont reliées par and, ce qui est juste pour une plage. Mais elles sont strictes : pour 19.95, diametre > 19.95 est faux, donc toute la condition est fausse. Le programme affiche Rebut pour 19.95, Conforme pour 20, Rebut pour 20.05.
Deux pièces conformes sont mises au rebut, et un essai avec 20 seulement ne l'aurait jamais montré. « Bornes incluses » se traduit par diametre >= 19.95 and diametre <= 20.05 : avec cette condition, les trois saisies donnent « Conforme ». Seuls les deux seuils pris exactement révèlent la différence.
Au péage d'un pont, un véhicule léger (catégorie 1) paie 4 € le jour et 3 € la nuit ; un poids lourd (catégorie 2) paie 10 € le jour et 7 € la nuit. La nuit commence à 22 h et finit avant 6 h. Construire l'organigramme qui lit la catégorie et l'heure (entier de 0 à 23), puis donner le tarif affiché pour un poids lourd à 22 h et un véhicule léger à 5 h.
La nuit se décrit par une condition composée : l'heure est avant 6 ou à partir de 22. C'est bien or : aucune heure ne peut être à la fois inférieure à 6 et supérieure ou égale à 22. Ranger cette condition dans nuit évite de la réécrire dans chaque branche.
La catégorie choisit la grille, la variable nuit choisit le tarif dans la grille.
Pour un poids lourd à 22 h, l'organigramme affiche Tarif : 7 euros ; pour un véhicule léger à 5 h, Tarif : 3 euros. 22 est un seuil : avec heure > 22, le poids lourd de 22 h paierait le tarif de jour. Autre limite du programme : toute catégorie autre que 1 passe par la branche False et paie comme un poids lourd, ce qu'une saisie de contrôle hors des valeurs prévues (3, par exemple) montre immédiatement.
Vérification
1.Pour charge = 30, laquelle de ces conditions est vraie ?
2.La branche False d'un If est vide. Que fait le programme quand la condition est fausse ?
3.Comment écrire « la cote est comprise entre 19,95 et 20,05, bornes incluses » ?
4.Quelle condition équivaut à not (a > 10) ?
5.Dans la cascade de la batterie (d'abord charge < 10, puis charge < 30), qu'affiche le programme pour une charge de 10 ?
6.Que vaut true and (false or true) ?
7.Pour quelles températures la condition temperature > 60 or temperature < 80 est-elle vraie ?
La méthode
- Traduire la règle mot à mot : « dépasse » et « au-dessus de » donnent
>, « atteint » et « au moins » donnent>=, « compris entre » donne deux comparaisons reliées parand. - Compter les cas : deux cas, un
If; trois cas, deuxIfimbriqués ; vérifier que chaque valeur possible tombe dans un seul cas. - Ordonner les tests pour que chacun hérite de ce que les précédents ont éliminé.
- Nommer les conditions composées en les rangeant dans une variable
Boolean, et parenthéser dès queandetorse mêlent ou qu'unnotporte sur une comparaison. - Placer chaque forme dans une branche si elle ne concerne qu'un cas, après la jonction si elle les concerne tous.
- Tester avec une valeur par chemin, puis chaque seuil exactement, et dérouler pas à pas quand un résultat surprend.
Synthèse
- Une comparaison produit un
Boolean,trueoufalse;==compare, et reste l'écriture à préférer. - Le bloc If : branche False à gauche, True à droite ; une branche peut être vide ; ce qui suit la jonction s'exécute toujours.
- Pour plusieurs cas, des If imbriqués : l'ordre des tests compte, et chaque valeur doit tomber dans un seul cas.
andexige les deux conditions,orune seule,notinverse ; priorités :not, calculs, comparaisons,and, puisor.- « Compris entre » s'écrit
x >= a and x <= b;x > a or x < best vrai pour toutes les valeurs. - Les erreurs se cachent aux valeurs limites : tester chaque seuil exactement, et chaque chemin au moins une fois.
Mettre en pratique
Évaluer une condition, suivre le bon chemin, tester les valeurs limites.
- Suivre une cascade de décisionsNiveau 1
- Évaluer une condition composéeNiveau 2
- Compter les lignes affichéesNiveau 2
- Une erreur au seuilNiveau 2
- Construire une régulation de chauffageNiveau 3