Lire une erreur, et la corriger
Ce que ce chapitre apporte5 points
- Lire un message d'erreur et en tirer trois informations : où, quoi, et ce qui était attendu.
- Reconnaître les six familles d'erreurs qui arrêtent un organigramme.
- Corriger une variable non déclarée, un type qui ne convient pas, un indice hors tableau.
- Distinguer une erreur qui arrête le programme d'un résultat faux qui ne dit rien.
- Employer le pas à pas pour voir l'état juste avant l'arrêt.
Un programme peut échouer de deux façons, et elles ne se traitent pas de la même manière. Ou bien il s'arrête en le disant : une fenêtre annonce ce qui l'a bloqué, et le travail consiste à lire ce message. Ou bien il va jusqu'au bout et se trompe : rien ne s'affiche en rouge, le résultat est simplement faux, et c'est le sujet du chapitre suivant.
Ce chapitre traite la première famille, celle que tout débutant rencontre dès son deuxième organigramme. Un message d'erreur n'est pas une punition : c'est le seul moment où la machine explique ce qu'elle attendait. Encore faut-il savoir le lire, et surtout savoir où regarder ensuite.
Ce qu'un message contient
Les organigrammes de ces pages s'arrêtent comme le logiciel, et leurs messages disent la même chose. Chacun porte trois informations, et c'est toujours les mêmes.
Où. La forme en cours au moment de l'arrêt se surligne. C'est là qu'il faut regarder, et nulle part ailleurs.
Quoi. La nature du blocage : une variable inconnue, une valeur du mauvais type, un indice qui sort d'un tableau.
Ce qui était attendu. La partie la plus utile, et la plus souvent ignorée. « La forme attendue est noms en Type » dit exactement quoi écrire.
Lire le message, trouver la forme qu'il désigne, corriger, relancer. Quatre gestes, dans cet ordre.
La variable qui n'existe pas
Exécuter : le programme s'arrête sur la première forme. Rien n'a créé « total », et une valeur ne peut pas se ranger dans une case qui n'existe pas.
Flowgorithm exige qu'une variable soit créée avant d'être employée, par une forme Declare qui lui donne un nom et un type. C'est la contrainte que Python n'a pas, et c'est une des raisons d'apprendre ici : elle oblige à décider, avant de calculer, ce que chaque valeur représente et dans quel type elle tient.
La même chose, corrigée par une seule forme. Exécuter, puis supprimer la déclaration pour retrouver le message précédent.
Deux cousines de cette erreur méritent d'être connues. « La variable est déjà déclarée » arrive quand un nom est créé deux fois, souvent parce qu'une forme Declare a été recopiée. Et « déclarée mais n'a encore reçu aucune valeur » arrive quand on affiche une variable avant de l'avoir remplie : la case existe, elle est vide, et Flowgorithm refuse de deviner ce qu'on voulait y mettre.
Exécuter : la case existe mais elle est vide. Ajouter « affecter: mesure ← 12.5 » avant l'affichage pour que le programme aboutisse.
Le type qui ne convient pas
Un type est une promesse : un Integer ne contient que des entiers, un Real des nombres à virgule, un String du texte, un Boolean vrai ou faux. Une saisie qui trahit cette promesse arrête le programme.
Exécuter avec la saisie proposée, 3.5, dans une variable déclarée Integer : le message dit le type attendu et la valeur reçue. Corriger en saisissant 3, ou en déclarant la variable Real.
La même exigence vaut dans les comparaisons et dans les calculs. Comparer un texte à un nombre n'a pas de sens, et le programme le dit plutôt que d'inventer une réponse.
Exécuter : comparer un texte et un nombre est refusé. La correction consiste à comparer ce qui est comparable, par exemple Len(nom) au seuil.
"Total : " + total échoue parce que + est réservé aux nombres. La concaténation s'écrit avec &, qui accepte les deux.C'est l'erreur la plus commune du parcours, et son message le dit sans détour : l'opérateur attend un nombre et reçoit du texte.
L'indice qui sort du tableau
Exécuter : la boucle va jusqu'à 4, alors que les cases s'arrêtent à l'indice 3. Remplacer la borne par « Size(debits) - 1 » et relancer.
Un tableau de quatre cases porte les indices 0, 1, 2 et 3. L'indice 4 n'existe pas, et le message le dit en donnant les bornes réelles. C'est l'erreur d'un cran, celle qui se produit à chaque fois qu'on écrit la taille là où il fallait la taille moins un.
La division par zéro
Exécuter avec 240 pièces et 0 heure : la division s'arrête net. Relancer avec 8 heures, puis réfléchir à ce que le programme devrait faire d'une durée nulle.
Ce cas mérite mieux qu'une correction de syntaxe. Une durée nulle est une donnée possible, pas une faute de frappe : le programme doit décider quoi en faire, et le seul moyen est de tester avant de diviser.
La version qui tient debout : le cas impossible est traité avant le calcul. Exécuter avec 0 heure, puis avec 8, et vérifier que les deux chemins répondent.
La boucle qui ne s'arrête jamais
Exécuter : rien dans le corps ne fait grandir le volume, donc la condition reste vraie pour toujours. Ajouter « affecter: volume ← volume + debit » dans la boucle et relancer.
Une boucle While s'arrête quand sa condition devient fausse. Pour qu'elle le devienne, une
variable de la condition doit changer dans le corps. Ici rien ne touche au volume : la condition
reste vraie, et l'exécution tourne jusqu'à ce que la page l'interrompe.
Le vrai logiciel, lui, ne s'interrompt pas tout seul : il faut arrêter l'exécution à la main. C'est la seule erreur de ce chapitre qui ne produit pas de message clair, et c'est pourquoi elle se reconnaît à son symptôme, une console qui se remplit sans fin ou une fenêtre qui ne répond plus.
Les erreurs de fonction
Exécuter : la fonction se termine sans avoir rangé de valeur dans « resultat », et l'appel n'a donc rien à rendre. Ajouter l'affectation manquante pour que le programme aboutisse.
Une fonction qui annonce une valeur de retour doit la ranger dans la variable nommée par son en-tête, avant de se terminer. Deux autres messages de la même famille se rencontrent : une fonction appelée avec le mauvais nombre d'arguments, et une fonction sans retour appelée dans une expression alors qu'elle demande une forme Call.
À calculer soi-même
Les erreurs d'un cran se comptent, et c'est le meilleur moyen de ne plus les commettre.
Bornes, indices et cas impossibles
- 1.
Un tableau déclaré avec 4 cases porte des indices de 0 à combien ?
- 2.
Une boucle « pour i de 0 à 4 » sur ce tableau fait combien de tours ?
- 3.
Combien de tours de trop cette boucle fait-elle ?
- 4.
Avec Size(debits) valant 4, quelle borne de fin faut-il écrire ?
- 5.
Un programme lit une durée en heures et divise par elle. Combien de valeurs de durée doivent être écartées avant le calcul ?
- 6.
Une variable déclarée Integer reçoit la saisie 3.5. Combien de corrections différentes règlent le problème, selon ce que le programme veut représenter ?
Vérification
1.Que faire en premier devant un message d'erreur ?
2.Que signifie « la variable n'est pas déclarée » ?
3.Un tableau de 6 cases : quel est le plus grand indice valide ?
4.Une division par zéro : que faut-il faire du cas ?
5.Une boucle While qui ne s'arrête jamais : où est la faute ?
Exercices type
Le message dit « attend un nombre, et reçoit du texte ». Où chercher ?
Dans la forme surlignée, et précisément dans l'opérateur qu'elle contient. Le cas le plus fréquent
est un + employé pour coller un libellé à une valeur : "Total : " + total. La concaténation
s'écrit &, qui accepte à la fois du texte et des nombres.
Le second cas est une variable déclarée String employée dans un calcul. La fonction ToNumber
convertit alors le texte en nombre, si tant est que ce texte en contienne un.
Un programme s'arrête au dernier tour d'une boucle seulement. Pourquoi ?
Parce que l'erreur est d'un cran : la boucle va une case trop loin, et les premiers tours se passent bien.
C'est la signature de l'indice hors tableau. La borne de fin doit valoir la taille moins un, ou
Size(tableau) - 1, ce qui reste juste même si la taille change plus tard.
Le pas à pas confirme en une exécution : la fenêtre des variables montre l'indice atteindre la valeur interdite, et la forme se surligne avant de s'arrêter.
Un organigramme s'exécute sans message, et affiche un résultat faux. Que faire ?
Rien de ce chapitre ne s'applique : il n'y a pas de message à lire, donc pas de forme désignée.
C'est l'autre famille d'erreurs, celle de la logique, et elle se traite par le jeu d'essai et le pas à pas : prévoir la valeur de chaque variable, exécuter forme par forme, et chercher la première divergence entre la prévision et l'observation. Le chapitre suivant lui est entièrement consacré.
La méthode
- Lire le message en entier, jusqu'à la fin : c'est souvent la dernière phrase qui dit quoi écrire.
- Regarder la forme surlignée, et elle seule, avant de relire tout le reste.
- Nommer la famille : déclaration, type, indice, division, boucle, fonction. Elle indique la correction.
- Corriger une seule chose, puis relancer. Deux corrections à la fois rendent impossible de savoir laquelle a servi.
- Se demander si le cas était possible : une durée nulle ou un tableau vide ne se corrigent pas, ils se traitent.
Synthèse
- Un programme échoue de deux façons : il s'arrête en le disant, ou il aboutit et ment. Ce chapitre traite la première, le suivant la seconde.
- Un message porte toujours trois informations : où, quoi, et ce qui était attendu.
- Les familles à reconnaître : variable non déclarée ou sans valeur, type qui ne convient pas, indice hors tableau, division par zéro, boucle sans fin, fonction sans valeur rendue.
- L'erreur d'un cran, celle de l'indice, se reconnaît à son symptôme : tout se passe bien jusqu'au dernier tour.
- Une donnée impossible, comme une durée nulle, ne se corrige pas : elle se teste avant le calcul.
Et ensuite
Reste l'autre famille, celle qui ne dit rien. Concevoir, tester, puis traduire en Python donne la méthode qui va du besoin à l'organigramme, le jeu d'essai qui révèle un résultat faux, et le pas à pas qui désigne la forme responsable.
Mettre en pratique
Les six familles de messages qui arrêtent un organigramme, l'erreur d'un cran, et la donnée impossible qui se teste au lieu de se corriger.
- L'erreur d'un cranNiveau 2
- Ce qu'un message d'erreur contientNiveau 1
- La donnée impossible ne se corrige pas, elle se testeNiveau 3