Aller au contenu

Chapitre 4 : Mise au point de programmes⚓︎

Le but de ce chapitre est de travailler sur la mise au point de programmes robustes à travers l'écriture de jeux de tests et la compréhension des messages d'erreur.

Utilisation du module doctest⚓︎

La fonction min_et_max définie ci-dessous a pour rôle de renvoyer la plus petite et la plus grande des valeurs stockées dans un tableau non vide.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
def min_et_max(tab):
    """
    Renvoie la plus petite et la plus grande valeur d'un tableau.
    - Entrée : tab (tableau non vide)
    - Sortie : (plus_petit, plus_grand) (couple d'éléments du tableau)
    """
    if type(tab) != list:
        raise TypeError("l'argument doit être un tableau")
    if len(tab) == 0:
        raise ValueError("l'argument doit être un tableau non vide")
    plus_petit = tab[0]
    plus_grand = tab[0]
    for k in range(1, len(tab)):
        if tab[k] < plus_petit:
            plus_petit = tab[k]
        if tab[k] > plus_grand:
            plus_grand = tab[k]
    return plus_petit, plus_grand

Pour vérifier que la fonction a le bon comportement, on effectue une série de tests. Par exemple,

1
2
print(min_et_max([1, 7, 9, 3, 2, 0, 2, 0]))  # doit afficher le couple (0, 9)
print(min_et_max([0 for _ in range(1000)]))  # doit afficher le couple (0, 0)
1
2
3
4
from random import randint, shuffle
T = [-10000, 10000] + [randint(-10000, 10000) for _ in range(998)]
shuffle(T)
print(min_et_max(T))  # doit afficher le couple (-10000, 10000)
1
2
print(min_et_max("tableau"))  # doit provoquer une erreur de type
print(min_et_max([]))  # doit provoquer une erreur de valeur

Il est possible d'intégrer directement ces tests à la docstring de la fonction min_et_max en procédant de la façon suivante :

  • Les tests s'écrivent à la fin de la docstring.
  • Les lignes de code à exécuter au cours du test sont précédées de trois chevrons >>>.
  • Le résultat attendu pour chaque test est indiqué sur la ligne juste en dessous des trois chevrons.

Les tests intégrés à la docstring sont appelés doctests.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def min_et_max(tab):
    """
    Retourne la plus petite et la plus grande valeur d'un tableau.
    - Entrée : tab (tableau non vide)
    - Sortie : (plus_petit, plus_grand) (couple d'éléments du tableau)

    >>> min_et_max([1, 7, 9, 3, 2, 0, 2, 0])
    (0, 9)

    >>> min_et_max([0 for _ in range(1000)])
    (0, 0)

    >>> from random import randint, shuffle
    >>> T = [-10000, 10000] + [randint(-10000, 10000) for _ in range(998)]
    >>> shuffle(T)
    >>> min_et_max(T)
    (-10000, 10000)

    >>> min_et_max("tableau")
    Traceback (most recent call last):
        ...
    TypeError: l'argument doit être un tableau

    >>> min_et_max([])
    Traceback (most recent call last):
        ...
    ValueError: l'argument doit être un tableau non vide
    """
    # Code de la fonction...

Pour lancer les tests présents dans la docstring d'une fonction, il suffit d'appeler la fonction run_docstring_examples du module doctest. Le premier argument est le nom de la fonction à tester, le second est globals().

1
2
import doctest as dt
dt.run_docstring_examples(min_et_max, globals())

Le fait que rien ne s'affiche à l'exécution de la cellule ci-dessus signifie que tous les tests ont été passés avec succès.

En passant l'argument True au paramètre optionnel verbose, on obtient un affichage détaillé des tests effectués.

1
dt.run_docstring_examples(min_et_max, globals(), verbose=True)

Il est également possible de tester l'ensemble des doctests présents dans un fichier ou dans un carnet Jupyter. Il suffit pour cela d'appeler la fonction testmod du module doctest sans aucun argument (sauf le paramètre optionnel verbose).

Messages d'erreur⚓︎

(voir activité "Messages d'erreur classiques")

Exercices et activités⚓︎

Exercices

Carnet Jupyter à télécharger ici

Corrigé disponible ici

Carnet Jupyter à télécharger ici

Corrigé disponible ici

Activités

L'objectif de l'activité est de comprendre, et donc d'apprendre à éviter, une trentaine de messages d'erreur.

Carnet Jupyter à télécharger ici

Corrigé disponible ici

Il s'agit de disposer huit reines sur un échiquier de sorte qu'aucune n'en menace une autre.

Une manière de résoudre ce problème est de mettre en oeuvre un algorithme de backtracking.

Version jouable à télécharger ici

L'objectif de l'activité est de créer un solveur de grille de Sudoku et de réaliser un certain nombre de tests de validation.

Carnet Jupyter à télécharger ici

Corrigé disponible ici