Recharger de -50 euros
Un élève recharge sa carte de cantine. Par erreur, le programme reçoit moins 50 euros. Il fait le calcul sans rien dire.
La carte perd 50 euros. Personne ne s'en aperçoit tout de suite. Le défaut apparaît bien plus tard, loin de sa vraie cause.
Une bonne fonction sait dire non quand on lui donne une valeur absurde.
Mots-clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Précondition | Ce qui doit être vrai avant d'appeler la fonction. | montant > 0 |
| Postcondition | Ce que la fonction promet d'être vrai sur son résultat. | Une moyenne est entre le minimum et le maximum |
| Contrat | L'accord entre celui qui appelle et la fonction : si tu donnes ça, je rends ça. | Une liste non vide, une moyenne |
| Valeur absurde | Une valeur qui n'a pas de sens pour la fonction. | Un âge de -3 ans |
| assert | Mot de Python qui arrête le programme si une condition est fausse. | assert montant > 0 |
| Refuser | Arrêter le programme avec un message clair plutôt que continuer avec une valeur absurde. | AssertionError |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Un contrat entre deux personnes
Une fonction passe un contrat avec celui qui l'appelle.
Celui qui appelle promet : « Je te donne des valeurs raisonnables. » C'est la précondition. La fonction promet : « Alors je te rends un bon résultat. » C'est la postcondition.
Si la précondition est fausse, la fonction n'a rien promis. Mieux vaut qu'elle s'arrête tout de suite.
À toi : la carte de cantine
def recharger(solde, montant):
# Ajoute de l'argent sur la carte de cantine.
return solde + montant
print(recharger(10, 20))
print(recharger(10, -50))
# Le deuxième résultat est absurde : la carte perd 50 euros !
# Ajoute au début de la fonction :
# assert montant > 0, "Le montant doit être positif"
# Relance. Que se passe-t-il ?
Exemple travaillé : trois contrats
| Fonction | Précondition (ce qu'elle attend) | Postcondition (ce qu'elle promet) |
|---|---|---|
| recharger(solde, montant) | montant > 0 | Le nouveau solde est plus grand que l'ancien |
| moyenne(notes) | La liste n'est pas vide | Le résultat est entre la plus petite et la plus grande note |
| tarif_bus(age) | age >= 0 | Le tarif vaut 0, 1 ou 2 euros |
| diviser(a, b) | b est différent de 0 | Le résultat multiplié par b redonne a |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Contrôle rapide
À toi de jouer
Contrôle rapide
4 questionsTes réponses sont corrigées ici et ne sont pas conservées. Un compte garde tes résultats.
Où vérifier, et comment
On vérifie les préconditions au tout début de la fonction, avec assert et un message qui explique.
On les écrit aussi dans la docstring (leçon « Écrire pour les autres »). Ainsi, celui qui appelle sait ce qu'il doit donner.
Une postcondition se vérifie à la fin, juste avant le return. Elle aide à trouver tes propres bogues.
À toi : un contrat complet
def moyenne(notes):
assert len(notes) > 0, "Il faut au moins une note"
total = 0
for note in notes:
total = total + note
resultat = total / len(notes)
assert resultat >= min(notes) and resultat <= max(notes), "Moyenne impossible"
return resultat
print(moyenne([12, 8, 16]))
print(moyenne([15]))
# Le dernier appel est refusé : la liste est vide.
# Mets une note entre les crochets pour le faire marcher.
print(moyenne([]))