Dans cet exercice de programmation en Python, tu vas implémenter la fonction factorielle.
Objectifs : manipuler les boucles for, une fonction (et quelques tests automatisés en bonus).
a) Proposer une fonction facto qui admet comme argument un entier naturel ##n## et retourne la factorielle de ##n##.
Définition :
La factorielle d’un entier naturel ##n## notée ##n!## est le produit de tous les nombres entiers entre ##1## et ##n##, compris. Ainsi, pour déterminer la factorielle d’un nombre entier, nous pouvons utiliser la formule suivante :
a) Commence par initialiser une variable result à ##1##.
b) Utilise une boucle for pour parcourir les entiers de ##2## à ##n##.
c) À chaque tour de boucle, multiplie result par l’entier courant.
d) À la fin, retourne result.
a) On commence par initialiser une variable result à ##1## pour prendre en compte les cas ##0! = 1## et ##1! = 1##.
b) Puis on fait une boucle for de ##2## à ##n## .
On utilise ##(n + 1)## dans range(2, n + 1) car la borne supérieure est exclusive, ce qui nous donne bien les valeurs de ##2## à ##n##.
c) À chaque étape de la boucle, on multiplie result par ##i##
def facto(n):
result = 1 # 0! = 1 et 1! = 1
for i in range(2, n + 1): # Pour i de 2 inclus à n inclus
result *= i
return result
Ci-dessous, une version documentée de la fonction. La docstring présente les arguments, la valeur de retour et les exceptions possibles : un format standard utilisé dans les projets Python.
def facto(n):
"""
Calcule la factorielle d'un entier n.
Args:
n (int): Un entier positif ou nul.
Returns:
int: La factorielle de n.
Raises:
ValueError: Si n n'est pas un entier positif ou nul.
"""
result = 1 # 0! = 1 et 1! = 1
for i in range(2, n + 1): # Pour i de 2 inclus à n inclus
result *= i
return result
Aïe, il nous manque le cas où ##n## n’est pas un entier positif ou nul.
On va donc utiliser un contrôle de type isinstance(n, int), ce qui garantit que l’utilisateur fournit bien un entier naturel.
Cela évite des comportements inattendus (comme appeler la fonction avec une chaîne ou un nombre négatif) et permet de signaler clairement l’erreur.
def facto(n):
"""
Calcule la factorielle d'un entier n.
Args:
n (int): Un entier positif ou nul.
Returns:
int: La factorielle de n.
Raises:
ValueError: Si n n'est pas un entier positif ou nul.
"""
if not isinstance(n, int) or n < 0:
raise ValueError("n doit être un entier positif ou nul")
result = 1 # 0! = 1 et 1! = 1
for i in range(2, n + 1): # Pour i de 2 inclus à n inclus
result *= i
return result
Les tests automatisés ci-dessous permettent de valider notre fonction et de garantir qu’elle fonctionne correctement sur plusieurs valeurs clés.
On teste notamment les cas particuliers 0 et 1 (puisque leur factorielle vaut toujours 1), ainsi que plusieurs valeurs croissantes pour vérifier que la boucle produit bien le bon résultat à chaque étape, même lorsque la valeur de ##n## augmente.
Ces tests sont essentiels : ils assurent que notre fonction reste fiable même si elle évolue, et permettent de détecter rapidement les erreurs de logique.
def facto(n):
"""
Calcule la factorielle d'un entier n.
Args:
n (int): Un entier positif ou nul.
Returns:
int: La factorielle de n.
Raises:
ValueError: Si n n'est pas un entier positif ou nul.
"""
if not isinstance(n, int) or n < 0:
raise ValueError("n doit être un entier positif ou nul")
result = 1 # 0! = 1 et 1! = 1
for i in range(2, n + 1): # Pour i de 2 inclus à n inclus
result *= i
return result
# Tests automatisés
assert facto(0) == 1
assert facto(1) == 1
assert facto(2) == 2
assert facto(3) == 6
assert facto(4) == 24
assert facto(5) == 120
assert facto(6) == 720
assert facto(7) == 5040
assert facto(8) == 40320
assert facto(9) == 362_880
assert facto(10) == 3_628_800
print("Tous les tests ont réussi !")