Les fonctions#
À faire
Synchroniser avec Semaine4/01-fonctions.md; notamment la MySTification des exercices
Documentation d’une fonction#
Lorsqu’on écrit une fonction, est important de la documenter, c’est-à-dire de fournir des informations claires et précises sur ce que fait la fonction, comment l’utiliser correctement, et ce à quoi s’attendre en termes de comportement et de résultats. Cette documentation est généralement écrite sous forme de commentaires dans le code source de la fonction.
Exemple :
def factorielle(n):
""" Fonction qui calcule la factorielle
Paramètre n : un nombre entier positif
Retourne n!
"""
Une bonne documentation :
Est concise et précise
Donne les préconditions sur les paramètres
Décrit le résultat (ce que fait la fonction)
Astuce pour être efficace :
Toujours commencer par écrire la documentation
De toute façon il faut réfléchir à ce que la fonction va faire!
Tests d’une fonction#
En informatique, il est important d’apprendre à écrire des tests qui permettent de valider le bon fonctionnement des ses fonctions et programmes.
Il existe en Python un mot-clé, assert
, qui permet de tester une expression booléenne. Vous l’avez déjà rencontré dans les TPs précédents. Si cette expression s’évalue à True, il ne se passe rien.
Astuces pour être efficace :
Commencer par écrire les tests d’une fonction
De toute façon il faut réfléchir à ce qu’elle va faire!
Tester les cas particuliers
Tant que l’on est pas sûr que la fonction est correcte :
Faire des essais supplémentaires
Capitaliser ces essais sous forme de tests
Si l’on trouve un bogue (ou bug en anglais, une erreur) :
Ajouter un test caractérisant le bogue
Astuce
Les fonctions préexistantes en python
En python, on peut appeler de nombreuses fonctions préexistantes. Vous en avez déjà vu quelques unes : type()
, print()
, range()
… Nous en découvrirons d’autres au fur et à mesure des TPs.
Exercice 1 : renvoyer versus afficher#
Les deux cellules suivantes définissent respectivement les fonctions
abs
etafficheAbs
; notez les différences entre ces deux fonctions, puis exécutez les cellules.
def abs(a):
""" Une fonction qui calcule la valeur absolue
Paramètres : a, un entier
Retour : la valeur absolue de a
"""
if (a > 0):
return a
else:
return -a
def afficheAbs(a):
""" Une fonction qui affiche la valeur absolue
Paramètres : a, un entier
"""
if (a > 0):
print(a)
else :
print(-a)
Observez les appels suivants; y a-t-il une différence entre
abs
etafficheAbs
?
abs(-3)
3
abs(-3)
3
afficheAbs(-3)
3
afficheAbs(-3)
3
Indication
Explication
abs
renvoie une valeur alors que afficheAbs
l”affiche. On
notera ci-dessus que, avec abs(3);
, Jupyter ne montre pas du tout la
valeur alors que, avec abs(3)
, Jupyter montre la valeur avec son
type (int
). Inversement afficheAbs
affiche la valeur mais ne la
renvoie pas.
Exercice 1 (suite)
Essayez de deviner le résultat des appels suivants puis exécutez pour vérifier :
abs(-5) + abs(3)
8
afficheAbs(-5) + afficheAbs(3)
5
3
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[8], line 1
----> 1 afficheAbs(-5) + afficheAbs(3)
TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'
La seconde cellule vous donne une erreur, comprenez-vous pourquoi?
Indication
Explication
afficheAbs
ne fait qu’afficher une valeur sans la renvoyer (type de
retour void
); il n’est donc pas possible de réutiliser cette valeur
par la suite, par exemple pour faire un calcul ou un test.
Exercice 2 : une fonction utilisant une fonction#
Complétez la fonction ci-dessous dont on donne la documentation.
⚠️ Vous devez utiliser un appel à l’une des deux fonctions
précédentes, afficheAbs
ou abs
; laquelle faut-il choisir ?
Pourquoi ? ⚠️
def distance(a, b):
""" Distance de deux points sur une droite
Paramètre : a un entier: la coordonnée du premier point
Paramètre : b un entier: la coordonnée du deuxième point
Retour : la valeur absolue de la différence entre a et b
"""
### BEGIN SOLUTION
return abs(b-a)
### END SOLUTION
Vérifiez le comportement de votre fonction distance
sur l’exemple
ci-dessous; essayez sur quelques autres exemples; corrigez la fonction
si nécessaire :
distance(5,3)
2
Les tests ci-dessous automatisent partiellement la vérification du
comportement de votre fonction; comme la valeur attendue est
spécifiée, il ne reste qu’à vérifier que l’on obtient bien true
à
chaque fois :
distance(5,3) == 2
True
distance(-4,2) == 6
True
distance(2,-5) == 7
True
Exercice 3 : tests automatiques#
Dans l’exercice précédent, on a testé la fonction
distance
. Cependant, il a fallu exécuter les trois cellules de test
séparément et s’assurer pour chacune d’entre elles que true
était
affiché et pas false
. Pour n’être averti que s’il y a un problème et
savoir d’où il provient, nous allons rassembler les tests en une seule
cellule à l’aide de l’infrastructure d’automatisation des tests aperçue dans les TPs précédents.
Essayez les exemples suivants. .
Astuce
À chaque fois que vous redémarrez le noyau, allez ensuite dans
Cellule
-> Exécuter toutes les précédentes
. Cela exécute toutes
les cellules qui sont avant celle où vous vous trouvez. Vous éviterez
ainsi de perdre du temps à chercher où sont les cellules qu’il faut
ré-exécuter.
assert ( 1 < 2 )
assert ( 1 > 2 )
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
Cell In[14], line 2
1 assert ( 1 < 2 )
----> 2 assert ( 1 > 2 )
AssertionError:
On remarque que, si la condition en paramètre de assert
est vraie, il
n’y a aucun affichage. Par contre si la condition est fausse, un
message d’erreur indiquant la condition fausse est affiché.
Avec assert
, les tests de la fonction distance
se mettent sous la
forme :
assert ( distance(5,3) == 2 )
assert ( distance(-4,2) == 6 )
assert ( distance(2,-5) == 7 )
### BEGIN HIDDEN TESTS
assert ( distance(-5,-2) == 3)
### END HIDDEN TESTS
Exécutez ces tests. Leur exécution ne devrait rien afficher.
Exécutez les deux cellules suivantes pour définir et tester la
fonction maxAbs
. Corrigez la fonction pour qu’elle passe les tests.
def maxAbs(a, b):
""" Une fonction qui renvoie la valeur absolue du plus grand des deux entiers
en valeur absolue
Paramètre : a, un entier
Paramètre : b un entier
Retour : la valeur absolue du plus grand des deux entiers en valeur absolue
"""
print(abs(a))
print(abs(b))
if abs(a) >= abs(b):
return a
else :
return b
assert( maxAbs( 6, 2) == 6 )
assert( maxAbs(-15, 5) == 15 )
assert( maxAbs( -2, -3) == 3 )
6
2
15
5
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
Cell In[17], line 2
1 assert( maxAbs( 6, 2) == 6 )
----> 2 assert( maxAbs(-15, 5) == 15 )
3 assert( maxAbs( -2, -3) == 3 )
AssertionError:
Exercice 4#
Mêmes consignes que pour l’exercice 1 :
def sommeAbs(a, b):
""" somme des valeurs absolues (aussi appelée norme L1)
Paramètre : a un entier
Paramètre : b un entier
Retour : la somme des valeurs absolues de a et b
"""
### BEGIN SOLUTION
return abs(a) + abs(b)
### END SOLUTION
sommeAbs(5,-3)
8
sommeAbs(5,-3) == 8
True
sommeAbs(-4,-2) == 6
True
sommeAbs(2,5) == 7
True
Exercice 5 : suivre la documentation et les tests#
Implantez la fonction nombreSecondes
dont la documentation est
donnée ci-dessous :
### BEGIN SOLUTION
def nombreSecondes(j, h, m, s):
""" Renvoie en secondes la durée décrite en jours, heures, minutes, secondes
Paramètre : j un entier représentant le nombre de jours
Paramètre : h un entier représentant le nombre d heures
Paramètre : m un entier représentant le nombre de minutes
Paramètre : s un entier représentant le nombre de secondes
Retour : la durée totale en secondes
"""
return s + (60 * (m + 60 * (h + 24*j)))
### END SOLUTION
Vérifiez son fonctionnement sur les exemples et tests ci-dessous :
nombreSecondes(1,1,1,1)
90061
assert( nombreSecondes(0,0,0,1) == 1 )
assert( nombreSecondes(0,0,1,0) == 60 )
assert( nombreSecondes(0,1,0,0) == 3600 )
assert( nombreSecondes(1,0,0,0) == 86400 )
assert( nombreSecondes(3,2,5,25) == 266725 )