Concevoir, tester, puis traduire en Python
Ce que ce chapitre apporte 5 points
- Passer d'un besoin écrit en français à un organigramme, en six temps, dans l'ordre.
- Construire un jeu d'essai (cas nominal, cas limites, cas d'erreur) et le calculer avant d'exécuter.
- Distinguer une erreur qui arrête l'exécution d'une erreur de logique.
- Localiser une erreur en pas à pas : prédire, observer, repérer la première divergence.
- Relire en Python, forme par forme, un programme construit dans Flowgorithm.
Connaître les formes ne suffit pas : devant un besoin écrit en français, la difficulté est de savoir par où commencer, puis de savoir si le programme obtenu est juste. Ce chapitre donne une méthode fixe, du besoin jusqu'à l'organigramme. Il y ajoute un moyen de le vérifier, le jeu d'essai, et un moyen d'y trouver une erreur, le pas à pas. Il se termine par la lecture du même programme en Python : Flowgorithm traduit tout organigramme en Python, en Java ou en C++, et le parcours Python prend le relais à partir de là. Le tableau de la section consacrée à Python donne la correspondance, forme par forme.
Du besoin à l'organigramme
Un magasin de maintenance suit le stock d'une pièce de rechange. Le magasinier saisit le stock du matin, le seuil de réapprovisionnement, puis le nombre de sorties de la journée et la quantité prélevée à chaque sortie. Après chaque sortie, le programme affiche le stock restant ; une sortie qui dépasse le stock est refusée. En fin de journée, il indique s'il faut commander : c'est le cas quand le stock est inférieur ou égal au seuil.
Premier temps : identifier les entrées et les sorties. Ce que le magasinier tape est une entrée et deviendra une forme Input ; ce que le programme affiche est une sortie et deviendra une forme Output. Chaque entrée demande une variable déclarée, avec son type.
Entrées (toutes Integer) | Sorties |
|---|---|
stock : stock du matin | le stock restant après chaque sortie |
seuil : seuil de réapprovisionnement | « Sortie refusée » si la quantité dépasse le stock |
nbSorties : nombre de sorties | « Commander » ou « Stock suffisant » en fin de journée |
quantite : quantité d'une sortie |
Deuxième temps : calculer deux cas à la main. Avant de placer une seule forme, résoudre le problème sur papier. Ces résultats servent de référence : sans eux, rien ne permet de dire si le programme affiche la bonne chose.
- Cas A : stock 40, seuil 15, trois sorties de 12, 8 et 6. Le stock passe à 28, puis 20, puis 14. Comme 14 est inférieur ou égal à 15 : « Commander ».
- Cas B : stock 40, seuil 15, deux sorties de 10 et 5. Le stock passe à 30, puis 25. Comme 25 dépasse 15 : « Stock suffisant ».
Troisième temps : écrire les grandes étapes en français, puis un squelette qui tourne. Lire le stock, le seuil et le nombre de sorties. Pour chaque sortie, lire la quantité ; si elle dépasse le stock, afficher un refus ; sinon, la retirer du stock et afficher le stock. Enfin, comparer le stock final au seuil et afficher la décision.
À ce stade, les trois lectures du début suffisent à faire un programme qui tourne. Le construire tout de suite, avant même de savoir quelles structures viendront ensuite, évite de tout écrire d'un bloc et de chercher la faute dans vingt formes à la fois.
Le squelette du programme, exécutable dès maintenant : les trois lectures, et un affichage qui vérifie qu'elles sont arrivées au bon endroit. Exécuter avec 40, 15 et 3.
Ce squelette a l'air inutile, et il fait gagner du temps : si les trois valeurs s'affichent dans le désordre, la faute est dans l'ordre des lectures, et elle se voit sur un programme de quatre formes plutôt que de vingt.
Quatrième temps : repérer les structures. Les mots du besoin désignent les structures. Les cinq structures du parcours sont passées en revue, et celles qui ne servent pas sont écartées explicitement.
| Structure | Indice dans le besoin | Ici |
|---|---|---|
| Séquence | « d'abord…, puis… » | les trois lectures du début |
| Décision | « si… », « est refusée », « s'il faut » | deux losanges : refus d'une sortie, commande |
| Répétition | « à chaque sortie » | un For, car le nombre de sorties est saisi avant la boucle |
| Tableau | « garder la liste des… » | inutile : aucune quantité n'est réutilisée |
| Fonction | un calcul qui revient à plusieurs endroits | inutile : chaque calcul n'apparaît qu'une fois |
Cinquième temps : traduire en formes. Chaque phrase du plan devient une ou plusieurs formes, dans le même ordre.
Première version du suivi de stock. La lecture de la quantité est dans la boucle, la décision de commande après. Exécuter avec les saisies proposées, puis relancer avec 40, 15, 2, 10 et 5 : c'est le cas B calculé au deuxième temps.
Sixième temps : exécuter sur les cas calculés à la main. Les saisies proposées sont celles du cas A. Exécuter : la console affiche Stock : 28, Stock : 20, Stock : 14, puis Commander, le résultat calculé à la main. Relancer avec 40, 15, 2, 10 et 5 (cas B) : Stock : 30, Stock : 25, puis Stock suffisant.
Devant un besoin écrit en français, que faire avant de placer la première forme ?
Le jeu d'essai
Un jeu d'essai est une liste de saisies, chacune accompagnée de la sortie attendue, calculée à la main avant d'exécuter. Chaque ligne est ensuite exécutée et la sortie obtenue notée à côté : tout écart signale une erreur.
Calculé avant, sinon ce n'est plus un essai. La sortie attendue se calcule avant d'exécuter. Écrite après coup, elle recopie ce que le programme a affiché, et l'essai confirme alors tout, y compris une erreur.
C'est la seule discipline du chapitre qui demande un effort réel, et c'est celle qui distingue un programme vérifié d'un programme qui a l'air de marcher.
Deux cas qui passent ne prouvent pas grand-chose : ils ont été choisis parmi les situations auxquelles on pensait en dessinant. Un jeu d'essai contient donc trois familles de cas. Le cas nominal est une situation ordinaire, comme le cas A. Les cas limites se placent exactement sur une frontière du besoin, ici une sortie égale au stock ou un stock final égal au seuil, et juste à côté. Les cas d'erreur sont des saisies hors du domaine prévu : une sortie plus grande que le stock, une quantité négative. Voici celui de la première version, avec un stock de 40, un seuil de 15 et une seule sortie par cas :
| Cas | Quantité | Sortie attendue | Sortie obtenue |
|---|---|---|---|
| Nominal | 12 | Stock : 28, Stock suffisant | Stock : 28, Stock suffisant |
| Limite : sortie égale au stock | 40 | Stock : 0, Commander | Stock : 0, Commander |
| Limite : stock final égal au seuil | 25 | Stock : 15, Commander | Stock : 15, Commander |
| Juste au-dessus du seuil | 24 | Stock : 16, Stock suffisant | Stock : 16, Stock suffisant |
| Erreur : sortie supérieure au stock | 50 | Sortie refusée, Stock suffisant | Sortie refusée, Stock suffisant |
| Erreur : quantité négative | -5 | Sortie refusée, Stock suffisant | Stock : 45, Stock suffisant |
La ligne de 40 vise la frontière du premier losange : une sortie égale au stock est légitime, et un >= écrit par erreur à la place de > la refuserait. La dernière ligne diverge, mais d'une façon particulière : le besoin ne disait rien des quantités négatives, et c'est en écrivant la sortie attendue qu'il a fallu trancher. Refuser est la seule réponse raisonnable, car une quantité de -5 « retirée » fait monter le stock à 45 : une faute de frappe du magasinier fausserait l'inventaire. Exécuter l'organigramme de la première version avec 40, 15, 1 et -5 pour le constater. Le jeu d'essai a fait apparaître une question que le besoin avait oubliée, et la correction porte sur un seul losange, qui devient quantite <= 0 or quantite > stock.
Le seul losange qui change, et les saisies de la ligne qui divergeait. Exécuter : la sortie obtenue rejoint enfin la sortie attendue.
La console affiche Sortie refusée, puis Stock suffisant. Exécuter à nouveau avec 40, 15, 1 et 25, la ligne limite du jeu d'essai : Stock : 15, puis Commander. Les autres lignes donnent toujours la sortie attendue, et le losange plus sévère n'a rien cassé.
Une erreur qui arrête l'exécution se voit tout de suite : variable non déclarée, variable lue avant d'avoir reçu une valeur, + appliqué à du texte, indice hors du tableau. L'exécution s'interrompt. Une erreur de logique, elle, ne produit aucun message : le programme va jusqu'au bout et affiche un résultat faux, comme le stock de 45. Seul un jeu d'essai calculé d'avance la révèle.
Une erreur qui arrête l'exécution : + n'accepte que des nombres, et "Stock : " est du texte. Exécuter : l'exécution s'interrompt à la forme Output, avant tout affichage. Avec & à la place de +, la forme afficherait Stock : 28.
1.Une alarme doit se déclencher quand la température est strictement au-dessus de 100 °C. Quel cas limite tester en priorité ?
2.Un programme calcule la surface d'une parcelle et affiche une valeur négative, sans aucun message. De quel type d'erreur s'agit-il ?
Mettre au point : l'exécution pas à pas
Quand une ligne du jeu d'essai diverge, relire l'organigramme du regard mène rarement à l'erreur : on relit ce qu'on croit avoir dessiné. Il faut regarder le programme s'exécuter.
- L'exécution pas à pas avance d'une forme à la fois et surligne la forme en cours ; sur cette page, le bouton « Pas à pas » de chaque organigramme reproduit ce déroulé.
- La fenêtre des variables (Variable Watch) affiche la valeur de chaque variable à cet instant, avec les couleurs de type vues au deuxième chapitre.
- La forme Breakpoint, du même chapitre, suspend l'exécution là où elle est placée dans le logiciel : le programme avance normalement jusqu'à la zone suspecte, puis la fenêtre des variables s'observe à loisir.
La démarche tient en trois temps :
- Prédire : avant chaque forme, noter la valeur que la variable devrait prendre, d'après le calcul à la main.
- Observer : exécuter la forme et lire la fenêtre des variables.
- Repérer la première divergence : la première forme où l'observation diffère de la prédiction. L'erreur est dans cette forme, ou dans une valeur qu'elle utilise et qui a été préparée plus haut.
Exemple : une pression minimale qui vaut 0
Un technicien relève cinq pressions dans un réseau d'air comprimé : 6,2, 5,8, 6,5, 5,4 et 6,0 bars. À la main, la plus faible est 5,4. Le programme suivant affiche pourtant Pression minimale : 0.0 bar.
Une recherche du minimum qui donne un résultat faux. Dérouler en pas à pas en surveillant mini.
| Tour | pression lue | mini prédit après le losange | mini observé |
|---|---|---|---|
| 1 | 6,2 | 6,2 | 0 |
| 2 | 5,8 | 5,8 | 0 |
La divergence apparaît dès le premier tour, au losange : 6.2 < 0 est faux, la branche True n'est pas prise et mini garde sa valeur de départ. Le losange compare pourtant correctement : c'est la valeur qu'il utilise qui est fausse, et elle vient de l'affectation mini = 0, placée plus haut. Aucune pression n'étant inférieure à 0, le minimum n'est jamais remplacé. La correction consiste à partir d'une valeur réellement mesurée : remplacer mini = 0 par une lecture de la première pression suivie de mini = pression, et faire tourner la boucle de 2 à 5.
La même recherche, partie d'une valeur mesurée. Dérouler en surveillant mini, et le comparer au premier tour de la version fautive.
Avec les cinq mêmes pressions, le programme affiche Pression minimale : 5.4 bar, la valeur trouvée à la main. En pas à pas, mini vaut 6.2 avant même d'entrer dans la boucle, descend à 5.8 au tour i = 2, puis à 5.4 au tour i = 4, et ne bouge plus.
Dans l'exemple de la pression, pourquoi la forme fautive n'est-elle pas le losange où la divergence apparaît ?
De l'organigramme au code Python
Flowgorithm convertit un organigramme en code de plusieurs langages réels, dont Python, par le Source Code Viewer, présenté au premier chapitre : menu Tools, ou touche F12. En choisissant Python, le même programme apparaît en texte. Savoir y reconnaître chaque forme prépare directement la suite du parcours.
| Forme Flowgorithm | Python | Ce qui change |
|---|---|---|
| Declare d'une variable simple | rien | la variable naît à sa première affectation |
| Declare d'un tableau | volumes = [0] * 24 | la liste doit exister avant qu'on range une valeur dans une case ; le Source Code Viewer la crée ainsi |
| Input | stock = int(input()) | input() rend du texte : int(...) le convertit en entier, float(...) en réel |
| Output | print("Stock : " + str(stock)) | & devient +, à condition de convertir d'abord le nombre en texte par str(), comme l'écrit le Source Code Viewer ; une f-string, print(f"Stock : {stock}"), l'évite |
| Assign | stock = stock - quantite | rien : le signe = de la forme est aussi celui de Python |
| If | if condition: puis else: | chaque branche devient un bloc indenté |
| While | while condition: | le corps est le bloc indenté |
For i = a to b | for i in range(a, b + 1): | la borne de fin de range est exclue |
| Do | while True:, le corps, puis if not (condition): break | Python n'a pas de boucle testée en bas : le Source Code Viewer la simule ainsi |
| Fonction avec variable de retour | def Nom(parametres): et return resultat | le retour est une instruction explicite |
Deux lignes de ce tableau évitent les deux erreurs les plus fréquentes d'une traduction à la main. print("Stock : " + stock) s'arrête sur une TypeError, car Python n'additionne pas un texte et un nombre : c'est pourquoi le Source Code Viewer écrit str(stock). Et une case de liste ne se remplit pas avant que la liste existe : volumes[0] = 14200, sans la ligne volumes = [0] * 24 au-dessus, s'arrête sur une NameError.
Voici, écrit à la main, un code Python équivalent au suivi de stock corrigé. Le code du Source Code Viewer peut différer dans sa présentation ; la correspondance forme par forme reste la même.
L'indentation remplace les flèches. Le if stock <= seuil: final est aligné sur le for : il est après la boucle. Décalé de quatre espaces, il serait exécuté à chaque sortie.
1.Comment s'écrit For i = 1 to 10 en Python ?
2.En Python, qu'est-ce qui remplace les deux flèches d'une forme If ?
3.Comment déclare-t-on une variable simple en Python ?
4.Pourquoi le Source Code Viewer traduit-il "Stock : " & stock par "Stock : " + str(stock) ?
Fil rouge : la cuve de traitement
La cuve cylindrique de la station (rayon 1,5 m, hauteur 4 m) a été construite par morceaux au fil des chapitres. Il reste à la reprendre avec la méthode, à la tester et à la relire en Python. Entrées et sorties. Le technicien saisit le volume actuel en litres (Real) et l'état de la vanne de sortie (Boolean, true si elle est fermée). Le programme affiche le taux de remplissage, puis l'état du niveau : « Débordement imminent » au-dessus de 90 %, « Niveau bas » en dessous de 10 %, « Niveau normal » sinon. Il affiche enfin l'autorisation de la pompe, accordée quand le taux est sous 90 % et que la vanne est fermée. Un volume négatif ou supérieur à la capacité est refusé.
Cas à la main. La capacité vaut π × 1,5² × 4, soit environ 28,27 m³, ou 28 274 litres. Pour 21 000 litres et une vanne fermée, le taux est d'environ 74,3 % : « Niveau normal », « Pompe autorisée ». Étapes et structures. Calculer la capacité, puis lire les saisies. Refuser un volume hors limites, par une décision. Calculer ensuite le taux avec la fonction CalculerTaux, afficher l'état avec AfficherEtat, une procédure, c'est-à-dire une fonction qui ne retourne rien et s'appelle par une forme Call, et décider de la pompe par une condition composée.
Étape 7 du fil rouge : la cuve entière, avec la fonction CalculerTaux et la procédure AfficherEtat. Exécuter avec 21000 et true, puis à nouveau avec 27000 et true pour voir la pompe passer en interdite.
Le jeu d'essai. Chaque ligne a été calculée avant d'exécuter, puis vérifiée.
| Cas | Saisies | Sorties attendues |
|---|---|---|
| Nominal | 21000, true | Taux : 74.3 %, Niveau normal, Pompe autorisée |
| Niveau haut | 27000, true | Taux : 95.5 %, Débordement imminent, Pompe interdite |
| Niveau bas | 2000, true | Taux : 7.1 %, Niveau bas, Pompe autorisée |
| Erreur : volume négatif | -5, true | Volume hors limites |
| Erreur : au-delà de la capacité | 30000, true | Volume hors limites |
Les cas limites posent une difficulté : à cause de π, un taux d'exactement 10 % ou 90 % ne correspond à aucun nombre rond de litres. Pour tester les frontières, la procédure AfficherEtat s'essaie seule, dans un petit programme qui lit directement le taux.
Programme de test de la procédure AfficherEtat. Exécuter quatre fois, en saisissant 90, puis 90.1, 10 et 9.9.
Attendu et obtenu : 90 donne Niveau normal, 90,1 donne Débordement imminent, 10 donne Niveau normal, 9,9 donne Niveau bas. Un losange écrit taux >= 90 donnerait toujours Niveau normal sur le cas nominal, mais Débordement imminent pour la saisie 90 : seul le cas limite détecte l'erreur.
Une erreur à localiser. Dans une version où la forme de capacité s'écrit capacite = pi * 1.5 ^ 2 * 4, le programme affiche Volume hors limites pour 21 000 litres. En pas à pas, la prédiction après cette forme est d'environ 28 274 ; la fenêtre des variables montre environ 28,27. C'est la première divergence : la capacité est restée en m³ alors que le volume est en litres. Le losange qui refuse le volume ne fait que révéler l'écart.
En Python. Les deux fonctions s'écrivent ainsi (code équivalent, écrit à la main) : la variable de retour devient une instruction return, les losanges imbriqués deviennent des blocs indentés.
Mettre en pratique
Un pont provisoire supporte une charge maximale saisie en tonnes. Les véhicules s'y engagent un par un et y restent pendant le relevé ; un capteur transmet la masse de chacun, et une masse de 0 signale la fin du relevé. Concevoir le programme qui déclenche une alarme dès que la masse totale dépasse la charge maximale, puis affiche le nombre de véhicules et la masse totale.
Entrées : chargeMax, puis une suite de masses (Real) terminée par 0. Sorties : « Alarme : surcharge » pour chaque véhicule engagé alors que la charge maximale est dépassée, puis une ligne de bilan. Structures : le nombre de véhicules n'est pas connu d'avance, d'où un While, avec une lecture avant la boucle et une lecture à la fin du corps ; un losange sans branche False contrôle la charge.
Jeu d'essai, calculé avant de dessiner, pour une charge maximale de 40 t :
| Cas | Masses saisies | Sorties attendues |
|---|---|---|
| Nominal | 12, 15, 0 | 2 véhicules, 27.0 t |
| Limite : total égal à la charge | 25, 15, 0 | 2 véhicules, 40.0 t, sans alarme |
| Dépassement | 25, 16, 0 | Alarme : surcharge, 2 véhicules, 41.0 t |
| Erreur : masse négative | -3 | 0 véhicules, 0.0 t |
Les saisies proposées sont celles du dépassement. Relancer avec les autres lignes du jeu d'essai.
La condition est total > chargeMax et non >= : le besoin dit « dépasse », et le cas limite à 40 t le vérifie. Le cas d'erreur a forcé une décision que le besoin ne prenait pas : avec masse > 0, une masse négative termine le relevé comme un 0. Écrire le jeu d'essai avant l'organigramme fait surgir ces questions au moment où elles se tranchent le plus facilement.
Recherche de la cellule la plus faible d'une batterie de cinq cellules.
Le programme ci-dessus doit afficher la cellule la plus faible d'une batterie et sa tension. Pour les tensions 3,71, 3,64, 3,69, 3,58 et 3,66 V, il annonce la cellule 5. Localiser l'erreur.
À la main, la tension la plus faible est 3,58 V, celle de la cellule 4. La tension affichée est juste, le numéro faux : l'erreur porte sur cellule. Prédiction et observation de cellule à la fin de chaque tour :
i | tension lue | cellule prédit | cellule observé |
|---|---|---|---|
| 2 | 3,64 | 2 | 2 |
| 3 | 3,69 | 2 | 3 |
La première divergence est au tour i = 3 : la tension 3,69 ne bat pas le minimum, et pourtant cellule change. La forme fautive est cellule = i, placée après le losange au lieu d'être dans sa branche True : elle s'exécute à chaque tour, et cellule finit égale au dernier indice. Une fois la forme déplacée sous mini = tension, dans la même branche, les deux affectations vont ensemble : le numéro ne change que lorsque le minimum change.
La version corrigée : cellule = i est passée dans la branche True. Exécuter pour voir s'afficher la cellule 4, puis à nouveau en saisissant les tensions dans un autre ordre.
Le programme affiche Cellule 4 : 3.58 V, et la forme cellule = i ne s'exécute plus que deux fois, aux tours où le minimum descend. Si la cellule la plus faible avait été la dernière, le programme fautif aurait affiché le bon résultat. Un jeu d'essai doit donc placer la valeur cherchée ailleurs qu'en dernière position.
Chapitre révisé en octobre 2026 · Une erreur dans ce chapitre ?
Dans la bibliothèque d'exercices
Du besoin à l'organigramme, jeux d'essai, localiser une erreur, lire le code exporté.
- Compléter un jeu d'essaiNiveau 1
- Localiser l'erreur d'une peséeNiveau 2
- La première divergenceNiveau 2
- Lire un programme PythonNiveau 2
- Trier les colis d'un tapis roulantNiveau 3
- Construire le contrôle d'une ensacheuseNiveau 3