Le but va être dans cette partie de réécrire quelques scripts "conventionnels" en les rendant "fonctionnels" ( au sens de "ils devront utiliser une fonction" ).
Dans chaque situation, vous réfléchirez aux spécifications de la fonction, la définirez complètement, écrirez sa docstring et la testerez.
La notion de preuve et de tests est fondamentale en informatique : certains systèmes ne peuvent se contenter d'un fonctionnement approximatif mais doivent au contraire être robustes, c'est à dire fonctionner correctement dans toutes les situations possibles.
Pour prouver qu'une fonction fait toujours correctement le travail pour lequel elle est prévue, il faudrait théoriquement la tester avec tous les arguments possibles et imaginables; c'est bien entendu impossible...
On peut cependant se contenter de tester son bon fonctionnement sur quelques arguments bien choisis : on parle alors de tests unitaires
En Python, on peut utiliser le module doctest
pour réaliser ces tests unitaires; il permet d'indiquer dans la docstring de la fonction des tests à réaliser et le résultat attendu si elle fonctionne bien.
Si ce n'est pas le cas, un message est alors affiché signalant qu'il faut corriger son code !
Voici un exemple avec la fonction division()
:
import doctest
def division( n1, n2 ):
"""
Fonction pour calculer le quotient et le reste de la division de deux nombres.
Pré :
deux nombres n1, n2
Post :
deux entiers dans l'ordre : quotient, reste de la division de n1 par n2
Tests unitaires :
>>> division(1,1)
(1, 0)
>>> division(2,1)
(2, 0)
>>> division(10,3)
(3, 1)
"""
quotient = n1 // n2
reste = n1 % n2
return quotient, reste
# Programme principal
doctest.testmod() # exécution des test unitaires
Un test unitaire correspond aux 3 chevrons ( >>> ) suivis de l'appel de la fonction avec des arguments particuliers; on indique en dessous le résultat attendu.
Si les tests unitaires sont validés, rien ne s'affiche. Par contre, en cas de mauvais fonctionnement, un ou plusieurs avertissement(s) s'affichent indiquant quel(s) test(s) n'ont pas été réussi(s).
Exemple avec la fonction précédente buguée :
import doctest
def division( n1, n2 ):
"""
Fonction pour calculer le quotient et le reste de la division de deux nombres.
Pré :
deux nombres n1, n2
Post :
deux entiers dans l'ordre : quotient, reste de la division de n1 par n2
Tests unitaires :
>>> division(1,1)
(1, 0)
>>> division(2,1)
(2, 0)
>>> division(10,3)
(3, 1)
"""
quotient = n1 / n2 # LA FONCTION EST BUGUÉE !!!
reste = n1 % n2
return quotient, reste
# Programme principal
doctest.testmod() # exécution des test unitaires
*********************************************************************
File "test.py", line 14, in __main__.division
Failed example:
division(1,1)
Expected:
(1, 0)
Got:
(1.0, 0)
**********************************************************************
File "/home/chris/test.py", line 17, in __main__.division
Failed example:
division(2,1)
Expected:
(2, 0)
Got:
(2.0, 0)
**********************************************************************
File "/home/chris/test.py", line 20, in __main__.division
Failed example:
division(10,3)
Expected:
(3, 1)
Got:
(3.3333333333333335, 1)
**********************************************************************
1 items had failures:
3 of 3 in __main__.division
***Test Failed*** 3 failures.
>>>
Une méthode de développement appelé TDD préconise d'ailleurs d'écrire D'ABORD des tests avant même le code d'une fonction...
Vous essayerez de procéder ainsi !
Le code ci-dessous permet la conversion d'un nombre en représentation binaire vers la base 10. Vous réécrirez ce script en y définissant une fonction binTodec()
qui réalise la conversion.
binaire = input('Entrez le nombre binaire :')
decimal = 0
expo = len(binaire) - 1
for car in binaire:
decimal += int(car)*(2**expo)
expo -= 1
print("Valeur en base 10 :", decimal)
Rédigez correctement sa docstring après avoir analysé les entrées et les sorties nécessaires au bon fonctionnement de la fonction.
Vous testerez le bon fonctionnement de la fonction avec des tests bien choisis !
Le script ci-dessous permet de convertir une température de degrés Celsius en Fahrenheit ou l'inverse selon le choix de l'utilisateur :
t = float(input('Entrez la température à convertir :'))
n = int(input('Choisissez la conversion : 1. °C -> F 2. F -> °C '))
if n == 1 :
print(32 + 1.8*t)
elif n == 2 :
print((t - 32)/1.8)
else :
print('Erreur !')
Réécrire le script avec une unique fonction conv()
qui retourne la conversion Celsius → Fahrenheit, ou Fahrenheit → Celsius.
Pour le script des deux dernières applications que vous avez vues dans le chapitre sur les conditions, vous allez écrire et tester deux fonctions :
boolean
, ne pouvant prendre que deux valeurs,
soit la valeur True
( = VRAI ), soit la valeur False
( = FAUX ).
bool1 = True
bool2 = False
def est_bissextile( annee ) :
..............
..............
return bool
def quel_jour( date ) :
.............
.............
# appel de la fonction est_bissextile()
.............
.............
return jour
# Programme principal
.....................
.....................
Pensez à tester d'abord le bon fonctionnement de la première fonction avant de passer à la suite !