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).

Exercice

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 :

$$n! = 1 \times 2 \times 3 \times \dots \times (n – 1) \times n$$

Besoin d'un coup de pouce ?

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.

Correction détaillée

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##

python
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

Documentation

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.

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.

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.
    """
    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

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.

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.
    """
    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 !")