Explorer les Livres électroniques
Catégories
Explorer les Livres audio
Catégories
Explorer les Magazines
Catégories
Explorer les Documents
Catégories
janvier-avril 2018
Les erreurs (des élèves) en programmation sont récurrentes. Nous listons ici les situations pouvant amener
ces erreurs et les messages d’erreur correspondants.
Lors de l’exécution d’un script Python dans Thonny, un message d’erreur s’affiche dans la console.
Ce message précise le numéro de ligne à laquelle l’erreur a été identifiée.
— Il est possible de visualiser les numéro de ligne dans la fenêtre de l’éditeur en positionnant l’option
ad hoc accessible via le menu Tools > Options > Show line numbers.
— Il est possible de naviguer directement à la ligne concernée en cliquant sur le lien souligné présenté
dans la console.
1 Erreurs de syntaxe
Le message d’erreur SyntaxError: invalid syntax couvre une large palette d’erreurs courantes.
∗ Philippe Marquet et les collègues formateurs de l’Académie de Lille. Ce document est mis à disposition selon les termes
de la licence Creative Commons Attribution - Partage dans les mêmes conditions 4.0 international
1
1.1 Confusion = et ==
>>> if x = 1 :
File "<stdin>", line 1
if x = 1 :
^
SyntaxError: invalid syntax
L’erreur de syntaxe dans ce cas est l’utilisation du symbole = qui, en Python, ne désigne pas l’opérateur
de comparaison, mais l’instruction d’affectation.
Python mentionne que le délimiteur de début ou de fin de chaîne de caractères a été omis.
>>> prenom = "Ada'
File "<stdin>", line 1
prenom = "Ada'
^
SyntaxError: EOL while scanning string literal
Cette même erreur est reportée si les délimiteurs de début et de fin ne correspondent pas.
Les instructions de structure de contrôle if, for, etc. nécessitent un : pour ouvrir le bloc d’instructions
qui les composent. Payton rapporte un oubli de ce caractère :
2
>>> if x == 0
File "<stdin>", line 1
if x == 0
^
SyntaxError: invalid syntax
La variable variable n’a en effet pas été définie préalablement à son utilisation. Ici c’est une faute de
frappe qui en est la raison, les deux lettres l et b ont été inversées lors de la définition de la variable.
>>> n = 0
>>> if n > 0 :
... somme = n
...
>>> carre = somme ** 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'somme' is not defined
Ici la variable somme est bien définie. . . seulement si on entre dans l’alternative, c’est-à-dire si et seulement
si la valeur de n est positive.
On préfèrera écrire :
>>> n = 0
>>> somme = 0
>>> if n > 0 :
... somme = n
...
>>> carre = somme ** 2
3
Un opérateur peut aussi s’appliquer à des valeurs de types différents, sans pouvoir les mixer. Par exemple,
l’opérateur + peut additionner des nombres, concaténer des chaînes de caractères, mais pas combiner un
nombre et une chaîne de caractères :
>>> 7 + 1
8
>>> "huit" + "ième"
'huitième'
>>> 8 + "ième"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
De même que pour les opérateurs, certaines fonctions attendent des arguments d’un type donné. Par
exemple round() qui renvoie l’arrondi d’un nombre et n’accepte donc pas une chaîne de caractères, abs()
qui renvoie la valeur absolue d’un nombre, ou len() qui renvoie la longueur d’une liste.
Les messages produits sont variés :
>>> round(42.7)
43
>>> round("42.7")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: type str doesn't define __round__ method
>>> abs(42.7)
42.7
>>> abs("42.7")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: bad operand type for abs(): 'str'
>>> len([42.7])
1
>>> len(42.7)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'float' has no len()
4
À l’inverse on a aussi une erreur si une indentation attendue n’est pas présente dans une structure de
contrôle, if, for, etc. :
>>> if n == 0 :
... x = 12
File "<stdin>", line 2
x = 12
^
IndentationError: expected an indented block
Enfin, un retrait d’indentation marque la fin d’un bloc. On peut avoir une erreur si une indentation
négative ne revient pas à la hauteur d’un bloc précédent :
>>> if n == 0 :
... x = 12
... y = x**2
File "<stdin>", line 3
y = x**2
^
IndentationError: unindent does not match any outer indentation level
Si l’instruction y = x**2 est en dehors du bloc if, elle doit être placée exactement à la verticale du if :
>>> if n == 0 :
... x = 12
...
>>> y = x**2
ou d’autres erreurs :
5
>>> x = 12
>>> y = 2 (x**2 + x + 4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
ici Python reconnaît la forme d’un appel de fonction, f(x**2 + x + 4), mais 2 qui est un entier, int,
n’est pas une fonction et ne peut être appelé, il n’est pas « callable » !
ou trop petit :
>>> l = [0, 1, 2, 3]
>>> l[-5]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
Python rapporte aussi comme erreur de syntaxe l’oubli deux-points lors de la définition d’une fonction :
>>> def f ()
File "<stdin>", line 1
6
def f ()
^
SyntaxError: invalid syntax
Au final, les parenthèses et les deux-points sont nécessaires. Les instructions de la définition doivent être
indentées. On écrit donc :
>>> def f ():
... return 0
...
La fonction f1() attend exactement un argument (un paramètre). La fonction f0() n’attend aucun
argument. La fonction prédéfinie abs() calcule la valeur absolue d’un nombre. Elle attend donc un nombre
en argument.
Lors de l’appel d’une fonction, il faut fournir exactement le bon nombre d’arguments, sous peine d’erreur :
>>> f0(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f0() takes 0 positional arguments but 1 was given
>>> f1()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f1() missing 1 required positional argument: 'x'
>>> f1(2,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f1() takes 1 positional argument but 2 were given
>>> abs(2,3)
Traceback (most recent call last):
7
File "<stdin>", line 1, in <module>
TypeError: abs() takes exactly one argument (2 given)
f0() n’attend pas d’argument, mais un a été donné ; f1() attend un argument qui n’a pas été donné ;
deux arguments ont été fournis à f1() ou abs() qui n’en attendent qu’un.
Un appel de fonction se fait avec des parenthèses, même pour les fonctions qui ne prennent aucun argument
:
>>> 3 + f0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'function'
On a omis les parenthèses lors de l’appel à la fonction f0(). L’évaluation de f0 produit non pas la valeur
entière 0, mais une valeur qui est une fonction.
>>> type(f0)
<class 'function'>
>>> f00 = f0
>>> type(f00)
<class 'function'>
>>> f00()
0
9 Assertions
Il est possible de placer des instructions assert pour s’assurer qu’une expression booléenne est vraie.
L’exécution provoquera une erreur si l’expression booléenne est False :
>>> n = 0
>>> assert n != 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
8
10 Erreurs liées aux saisies claviers
>>> n = input("un nombre ? ")
un nombre ? 12
>>> carre = n**2
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
La saisie ne provoque pas d’erreur en soit, la variable n est associée à la valeur "12" qui est une chaîne
de caractères.
C’est l’utilisation de cette variable qui provoquera l’erreur.
>>> a = int(input("un nombre ? "))
un nombre ? 12
>>> a**2
144
Tout se passe bien la saisie correspond à un entier, la chaîne "12" est transformée en l’entier 12.
>>> a = int(input("un nombre ? "))
un nombre ? douze
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'douze'
La chaîne saisie, "douze" ne peut être transformée en un entier. L’exécution de la fonction int() provoque
une erreur.
>>> a = int(input("un nombre ? "))
un nombre ? 12.5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '12.5'
De même ici, la valeur saisie, "12.5" ne peut être transformée en un entier. L’exécution de la fonction
int() provoque une erreur.
now exiting Console...