Un programme réel compte des milliers de lignes, écrites par plusieurs personnes. Pour s’y retrouver, on le découpe en modules aux interfaces bien documentées, on choisit un style de programmation adapté, et on le teste systématiquement. Ce chapitre réunit ces bonnes pratiques, et montre qu’il existe des questions qu’aucun programme ne peut résoudre.

Une question sur ce cours ?
ULU, le tuteur d’ULUMINE, t’aide à partir de ce cours.
Objectifs
- Utiliser et créer des modules, lire la documentation d’une API
- Distinguer les paradigmes impératif, fonctionnel et objet
- Identifier les principales erreurs à l’exécution et écrire des tests avec assert
- Comprendre qu’un programme est une donnée et que le problème de l’arrêt est indécidable
1. Modules et API
Module : Fichier Python (.py) regroupant des fonctions, des classes ou des constantes réutilisables. Une bibliothèque est un ensemble de modules.
API (interface de programmation) : Ensemble documenté des fonctions et classes qu’un module met à disposition, avec leurs paramètres et leur rôle. On peut s’en servir sans connaître leur code.
import math # on écrit ensuite math.sqrt(16)
from random import randint # on écrit directement randint(1, 6)
def aire_disque(r):
"""Renvoie l’aire d’un disque de rayon r (r >= 0)."""
return math.pi * r * r
if __name__ == "__main__":
print(aire_disque(1)) # exécuté seulement si on lance ce fichier directement2. Paradigmes de programmation
| Paradigme | Idée principale | En Python |
|---|---|---|
| Impératif | Suite d’instructions qui modifient l’état (variables) du programme | Affectations, boucles for et while |
| Fonctionnel | Calcul par composition de fonctions, sans modifier d’état | Fonctions pures, fonctions passées en paramètre, lambda |
| Objet | Objets regroupant données et méthodes, qui interagissent | Classes, attributs, méthodes |
Fonction pure : Fonction dont le résultat ne dépend que de ses paramètres et qui ne produit aucun effet de bord (pas de modification de variable globale, de paramètre modifiable, d’affichage…).
def appliquer(f, L):
return [f(x) for x in L]
print(appliquer(lambda x: x * x, [1, 2, 3])) # [1, 4, 9]3. Erreurs, tests et mise au point
| Erreur | Cause typique | Exemple |
|---|---|---|
| SyntaxError | Code mal écrit, détecté avant l’exécution | Oubli des deux-points après if |
| IndexError | Indice hors des bornes | L[3] avec L = [1, 2, 3] |
| KeyError | Clé absente d’un dictionnaire | d["b"] avec d = {"a": 1} |
| TypeError | Opération sur des types incompatibles | "3" + 4 |
| ZeroDivisionError | Division par zéro | 1 / 0 |
| NameError | Variable ou fonction non définie | print(x) sans affectation de x |
Les erreurs les plus sournoises ne provoquent aucun message : le programme s’exécute mais donne un résultat faux (erreur de logique, comme un range qui oublie un indice). On les détecte par des tests.
def est_bissextile(a):
return (a % 4 == 0 and a % 100 != 0) or a % 400 == 0
assert est_bissextile(2024)
assert not est_bissextile(2023)
assert not est_bissextile(1900) # cas particulier : siècle
assert est_bissextile(2000) # cas particulier : multiple de 400- assert condition ne fait rien si la condition est vraie et lève une AssertionError sinon.
- Bien choisir ses tests : cas courants, cas limites (liste vide, 0, bornes), cas particuliers.
- Pour localiser un bug : lire le message d’erreur (type, numéro de ligne), afficher des valeurs intermédiaires, réduire l’exemple qui échoue.
4. Un programme est une donnée : calculabilité
Un programme est un texte : il peut être la donnée d’un autre programme. Un interpréteur exécute des programmes, un compilateur les traduit, un antivirus les analyse.
Problème de l’arrêt : Existe-t-il un programme arret(p, x) qui, pour tout programme p et toute entrée x, renvoie True si p s’arrête sur x et False sinon ? Alan Turing a démontré en 1936 qu’un tel programme ne peut pas exister : le problème de l’arrêt est indécidable.
Idée de la démonstration (raisonnement par l’absurde)
- Supposons que arret existe. On écrit paradoxe(p) : si arret(p, p) est vrai, paradoxe boucle à l’infini ; sinon il s’arrête.
- Si paradoxe(paradoxe) s’arrête, alors arret(paradoxe, paradoxe) est vrai, donc il boucle : contradiction.
- S’il ne s’arrête pas, arret renvoie False, donc il s’arrête : contradiction.
L’hypothèse est fausse : aucun programme ne décide l’arrêt de tous les programmes.
À retenir
- Un module regroupe du code réutilisable ; son API documente ce qu’il propose.
- Impératif : on modifie un état. Fonctionnel : on compose des fonctions pures. Objet : on fait interagir des objets.
- Lire le type d’erreur et la ligne indiquée est la première étape du débogage.
- assert permet d’écrire des tests ; tester les cas limites est indispensable.
- Le problème de l’arrêt est indécidable : aucun programme ne peut le résoudre pour tous les cas.

Et maintenant, à toi !
Vérifie que tu as compris avec les exercices, puis révise avec la fiche.