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
absetafficheAbs; 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
absetafficheAbs?
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 )