Trois modules d'un même projet calculent un pourcentage de réussite
Exercice supplémentaire · niveau 3 (difficile) · NSI (première), chapitre 11 — Conduire un projet · Ce qui coûte cher
Énoncé
Trois modules d'un même projet calculent un pourcentage de réussite.
def pourcentage_maths(reussis, total):
return round(100 * reussis / total)
def pourcentage_physique(reussis, total):
if total == 0:
return 0
return round(100 * reussis / total)
def pourcentage_info(reussis, total):
if total == 0:
return 0
return round(100 * reussis / total)
- Quel défaut subsiste, et pourquoi est-il typique ?
- Récrire proprement.
- Chiffrer ce que la duplication coûte, en tests et en corrections.
- Toute duplication doit-elle être supprimée ?
Corrigé
1. pourcentage_maths(0, 0) lève une ZeroDivisionError : la garde a été ajoutée dans deux copies sur trois. C'est le défaut typique du code recopié — non pas que la faute soit difficile, mais que la correction doit être faite autant de fois qu'il y a de copies, et qu'une copie est toujours oubliée. Celle qui l'est ici est justement la première écrite, celle dont les deux autres sont issues.
2.
def pourcentage(reussis, total):
"""Part des reussites, en pourcent, arrondie a l'entier.
Renvoie 0 si aucun eleve n'est concerne."""
if total == 0:
return 0
return round(100 * reussis / total)
Les trois modules appellent cette unique fonction. La garde n'existe plus qu'à un seul endroit, donc elle ne peut plus être oubliée à un autre.
3. Le chiffrage tient en un tableau :
| Trois copies | Une fonction | |
|---|---|---|
| Jeux de tests à écrire | ||
| Endroits à corriger par défaut trouvé | ||
| Endroits où l'on peut oublier | ||
| Lignes de code |
Et le coût n'est pas ponctuel : il se paie à chaque correction future, pour toute la durée du projet. C'est ce qu'on appelle une dette : on a gagné du temps une fois, en recopiant, et on le rembourse à chaque modification.
4. Non, et c'est la nuance qui manque souvent. Deux morceaux de code qui se ressemblent aujourd'hui mais répondent à deux besoins différents sont appelés à diverger ; les fondre oblige alors à ajouter des paramètres, puis des conditions, et l'on obtient une fonction plus compliquée que les deux qu'on voulait simplifier.
Le bon critère n'est pas la ressemblance du texte, mais celle-ci : si ce calcul change, doit-il changer partout à la fois ? Ici, oui — un pourcentage est un pourcentage. Alors il n'y a qu'une fonction.
Le lien avec le reste du chapitre : c'est encore une question de spécification. Trois copies, ce sont trois définitions du même concept, dont rien ne garantit qu'elles restent d'accord. Une fonction nommée, documentée et testée est une définition unique — et c'est ce qui la rend maintenable, bien plus que les quatre lignes économisées.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.