S'entraîner...

Erreurs de syntaxe

Copiez les 2 codes suivants, collez-le dans un éditeur Python puis exécutez-les.

Répondez ensuite aux questions.

Question

1
def val_abs(a, b):
2
    if a-b > 0:
3
        return a-b
4
    else
5
        return b-a
6

Question 1 : Que signifie l'erreur signalée par la console ?

Question 2 : Corrigez ensuite cette erreur.

Solution

1
  File "val_abs.py", line 10
2
    else
3
       ^
4
SyntaxError: invalid syntax

Une erreur de syntaxe est signalée au niveau du else : il manque les deux-points « : ».

Question

1
def multi(a, b):
2
    while b > 0:
3
        resultat = resultat + a
4
        b = b-1
5
    return resultat
6

Question 1 : Effectuez un appel à la fonction multi(). Que signifie l'erreur signalée par la console ?

Question 2 : Corrigez ensuite cette erreur.

Indice

Effectuer un appel de la fonction signifie que, dans le programme principal (en dehors de la fonction donc, on appelle multi() avec 2 arguments à l'intérieur correspondant aux 2 paramètres de la fonction définie multi(a, b).

Solution

Explication de l'erreur
1
Traceback (most recent call last):
2
  File "multi.py", line 14, in <module>
3
    multi(3, 7)
4
  File "multi.py", line 9, in multi
5
    resultat = resultat + a
6
UnboundLocalError: local variable 'resultat' referenced before assignment

Une erreur de syntaxe est signalée en ligne 3 : la variable d'accumulation resultat est utilisée sans avoir été initialisée.

Solution

Correction du programme
1
def multi(a, b):
2
    resultat = 0
3
    while b > 0:
4
        resultat = resultat + a
5
        b = b-1
6
    return resultat
7

Plan de tests

Sur votre cahier, réaliser les 2 tableaux 'plan de tests' des 2 fonctions suivantes et renseignez-le. Vérifier ensuite avec la correction.

Question

La fonction meme_signe(a, b) doit renvoyer True lorsque a et b sont des entiers de même signe et False dans le cas contraire. On considère que 0 est positif et négatif.

Établir un plan de tests pour cette fonction.

Plan de test fonction meme_signe(a, b)

cas

a

b

valeur renvoyée attendue

_

_

_

_

_

_

_

_

_

_

_

_

_

_

_

_

_

_

_

_

Indice

a et b peuvent avoir 2 types de signes... 0 est aussi un cas particulier à prendre en compte lors du test.

Solution

Plan de test fonction meme_signe(a, b)

cas

a

b

valeur renvoyée attendue

a > 0 et b > 0

2

4

True

a < 0 et b > 0

-2

4

False

a > 0 et b < 0

6

-5

False

a < 0 et b < 0

-4

-2

True

L'un des deux vaut 0

0

-3

True

Question

La fonction somme_impair(n) doit renvoyer la somme des n premiers entiers impairs consécutifs.

Établir un plan de tests pour cette fonction.

Plan de test fonction somme_impair(n)

cas

n

valeur renvoyée attendue

_

_

_

_

_

_

_

_

_

Solution

Un plan de test possible :

Plan de test fonction somme_impair(n)

cas

n

valeur renvoyée attendue

aucun

0

0

un

1

1

plusieurs

4

1+3+5+7 = 16

Utilisation du module doctest de Python

Le but de cette partie est de mettre en œuvre le module doctest sur 2 fonctions différentes : somme_impair() et contient_e().

Question

Pour mettre en œuvre ce plan de tests de la question précédente, on rédige le code de la fonction, suivi du programme principal qui contient l'appel au module doctest :

1
def somme_impair(n):
2
    """
3
    n - int, entier strictement positif
4
    Sortie: int - somme des n premiers entiers impairs
5
    >>> somme_impair(0)
6
    0
7
    >>> somme_impair(1)
8
    1
9
    >>> somme_impair(4)
10
    16
11
    """
12
    s = 0
13
    for i in range(1, n):
14
        s = s + 2*i+1
15
    return s
16
17
##----- Mise en oeuvre des tests -----##
18
if __name__ == "__main__":
19
    import doctest
20
    doctest.testmod()

Question 1 : Copiez-collez et exécutez ce code. Tous les tests sont-ils passés ?

Question 2 : Dans le cas où des tests ne sont pas passés, corrigez le code pour qu'il ne contienne plus d'erreur de logique.

Solution

Solution question 1

Il y a bien une erreur de logique dans notre code puisque notre console affiche cette dernière ligne :

1
***Test Failed*** 2 failures.

Solution

Solution question 2

La boucle n'est pas parcourue n fois mais seulement n-1 fois. Il faut donc modifier le paramètre de la fonction range() à la ligne 13. Avec cette correction, plus rien ne doit être signalé dans la console.

Question

On considère la fonction contient_e() qui prend en paramètre une chaîne de caractères et qui renvoie un booléen de valeur True si la chaîne contient le caractère 'e' et False sinon.

1
def contient_e(mot):
2
    """
3
    mot – str
4
    Sortie: bool – True si mot contient 'e', False sinon
5
    >>> .............................................................
6
    .............................................
7
    >>> .............................................................
8
    .............................................
9
    """
10
11
    ..................................................................
12
    ..................................................................
13
    ..................................................................
14
    ..................................................................
15
    ..................................................................
16
17
##----- Mise en oeuvre des tests -----##
18
if __name__ == '__main__' :
19
    import doctest
20
    doctest.testmod()

Question 1 : Complétez les lignes 5 à 8 du code ci-dessus qui contient deux tests à réaliser dans la console par le module doctest.

Question 2 : Complétez la définition de la fonction contient_e() afin qu'elle respecte ses spécifications puis testez votre code.

Indice

Question 1 : on pourra utiliser 2 chaînes de caractères différentes...

Question 2 : parcourons notre chaîne avec une boucle...

Solution

Question 1 : Docstrings

Il faut un test pour lequel la valeur renvoyée est True, un autre pour False :

1
def contient_e(mot):
2
    """
3
    mot – str
4
    Sortie: bool – True si mot contient 'e', False sinon
5
    >>> contient_e('abcd')
6
    False
7
    >>> contient_e('Exemple')
8
    True
9
    """

Solution

Question 2 : code de la fonction

On parcourt chaque caractère. Dès qu'on en trouve un qui est un 'e', on renvoie True.

Si on les a tous parcourus et qu'on n'a trouvé aucun 'e', alors on renvoie False.

1
def contient_e(mot):
2
    """
3
    mot – str
4
    Sortie: bool – True si mot contient 'e', False sinon
5
    >>> contient_e('abcd')
6
    False
7
    >>> contient_e('Exemple')
8
    True
9
    """
10
    for carac in mot:
11
        if carac == 'e':
12
            return True
13
    return False
14
15
16
##----- Mise en oeuvre des tests -----##
17
if __name__ == '__main__' :
18
    import doctest
19
    doctest.testmod()

Un seconde code plus simple : L'opérateur in est bien plus efficace car il répond directement à cette question :

1
def contient_e(mot):
2
    """
3
    mot – str
4
    Sortie: bool – True si mot contient 'e', False sinon
5
    >>> contient_e('abcd')
6
    False
7
    >>> contient_e('Exemple')
8
    True
9
    """
10
    return 'e' in mot
11
12
13
##----- Mise en oeuvre des tests -----##
14
if __name__ == '__main__' :
15
    import doctest
16
    doctest.testmod()

Assert : protéger son programme

On considère à nouveau la fonction contient_e() étudiée précédemment.

Question

Question 1 : Utilisez une assertion pour tester que le paramètre saisi est bien une chaîne de caractères.

1
def contient_e(mot):
2
    """
3
    mot – str
4
    Sortie: bool – True si mot contient 'e', False sinon
5
    """
6
7
    assert ..............................................
8
    if 'e' in mot:
9
        return True
10
    else:
11
        return False
12

Question 2 : Testez ensuite ce code dans la console :

1
>>> contient_e('abcd')
2
3
>>> contient_e(17)

Solution

Question 1 :
1
def contient_e(mot):
2
    """
3
    mot – str
4
    Sortie: bool – True si mot contient 'e', False sinon
5
    """
6
7
    assert type(mot) == str, "Le paramètre mot doit être une chaîne de caractères."
8
    if 'e' in mot:
9
        return True
10
    else:
11
        return False

Avec les f-strings (Python 3.6), on peut aller un peu plus loin en faisant :

1
assert isinstance(mot, str), f"Le paramètre {mot} doit être une chaîne de caractères."

Solution

Question 2 :
1
>>> contient_e('abcd')
2
False
3
4
>>> contient_e(17)
5
  File "contient_e.py", line 13, in contient_e
6
    assert type(mot) == str, "Beta, c'est du string"
7
AssertionError: Beta, c'est du string
8
9

ou avec les fstrings :

1
    assert isinstance(mot, str), f"Le paramètre {mot} doit être une chaîne de caractères."
2
AssertionError: Le paramètre 17 doit être une chaîne de caractères.

Erreurs à connaître

Dans ces exercices, votre travail consiste à :

  • reconnaître les erreurs les plus classiques ;

  • comprendre ce qu'elles signifient ;

  • les corriger.

Question

Copiez, collez le code ci-dessous dans un éditeur :

1
def erreur1(a, b):
2
    """
3
    a, b – int ou float
4
    Sortie: int ou float – a-b si a-b est positif, b-a sinon
5
    """
6
        if a > b:
7
            return a-b
8
        else:
9
            return b-a
10

Exécutez ce code. Que signifie l'erreur signalée ?

Corrigez ce code puis testez-le.

Question

Copiez, collez le code ci-dessous dans un éditeur :

1
def erreur2(texte):
2
    """
3
    texte – str
4
    Sortie: str – Le texte dans lequel les caractères sont écrits dans l'autre sens
5
    """
6
    for carac in texte:
7
        reponse = carac + reponse
8
    return reponse
9

Exécutez ce code. Une erreur est-elle signalée ?

Effectuez l'appel :

1
erreur2('exemple')

Que signifie l'erreur signalée ?

Corrigez ce code puis testez-le à nouveau.

Question

Copiez, collez le code ci-dessous dans un éditeur :

1
def erreur3(texte):
2
    """
3
    texte – str
4
    Sortie: str – Le texte dans lequel on ne conserve qu'une lettre sur deux
5
    """
6
    reponse = ""
7
    for i in range(0, len(texte), 2):
8
        reponse = reponse + texte(i)
9
    return reponse
10

Exécutez ce code. Une erreur est-elle signalée ?

Effectuez un appel à la fonction erreur3().

Que signifie l'erreur signalée ?

Corrigez ce code puis testez-le à nouveau.

Question

Copiez, collez le code ci-dessous dans un éditeur :

1
def erreur4(texte):
2
    """
3
    texte – str
4
    Sortie: str – Le texte dans lequel le premier et le dernier caractère sont échangés
5
    """
6
    reponse = texte[len(texte-1)]
7
    for i in range(1, len(texte-1)):
8
        reponse = reponse + texte[i]
9
    reponse = reponse + texte[0]
10
    return reponse
11

Exécutez ce code. Une erreur est-elle signalée ?

Effectuez un appel à la fonction erreur4().

Que signifie l'erreur signalée ?

Corrigez ce code puis testez-le à nouveau.

Question

Copiez, collez le code ci-dessous dans un éditeur :

1
def erreur5(texte):
2
    """
3
    texte – str
4
    Sortie: str – Les caractères de texte ayant pour indice 1, 2, 4, 8, 16, etc...
5
    """
6
    reponse = ''
7
    indice = 1
8
    while indice <= len(texte):
9
        reponse = reponse + texte[indice]
10
        indice = indice*2
11
    return reponse

Exécutez ce code. Une erreur est-elle signalée ?

Effectuez plusieurs appels différents à la fonction erreur5() jusqu'à l'apparition d'une erreur.

Que signifie l'erreur signalée ?

Attention, respectez bien les spécifications : le paramètre d'appel DOIT être une chaîne de caractères.

Corrigez ce code puis testez-le à nouveau.

Question

Copiez, collez le code ci-dessous dans un éditeur :

1
def erreur6(a, b):
2
    """
3
    a, b – int, entiers strictement positifs
4
    Sortie: int – pgcd des entiers a et b
5
    """
6
    while b >= 0:
7
        reste = a%b
8
        a = b
9
        b = reste
10
    return b
11

Exécutez ce code puis effectuez des appels à la fonction erreur6() jusqu'à l'apparition d'une erreur.

Corrigez ce code puis testez-le à nouveau.

Un programme testé et vérifié !

On considère la fonction factorielle() définie par :

1
def factorielle(n):
2
    """
3
    n – int, entier strictement positif
4
    Sortie: int – le produit 1×2×3×...×n.
5
    """
6
    f = 0
7
    for i in range(n):
8
        f = f*i
9
    return f
10

Question

  • Question 1 : Insérez un plan de test dans le docstring de cette fonction. On s'intéressera aux cas particuliers de la fonction factorielle.

  • Question 2 : Ajoutez une assertion afin que le paramètre n respecte les spécifications.

  • Question 3 : Exécutez ce code afin qu'il soit testé automatiquement par le module doctest.

    Vérifiez que les tests ne « passent » pas.

  • Question 4 : Insérez des print() dans ce code pour suivre l'évolution des variables puis corrigez ce code.