Tutoriels gratuits et ouverts à toutes et à tous · conçus au Lycée Chevrollier — AngersÀ propos

Série « Parcours Python » · partie 5 / 8

Python niveau 4 — Organiser son code

Les fonctions : découper un problème en petits morceaux réutilisables : niveau 4 du parcours Python, avec exercices corrigés et QCM.

Développement✎ B. Jousseaume📅 17 octobre 2026⏱ 5 h📶 Intermédiaire

1. Pourquoi des fonctions ?

Tu utilises déjà des fonctions : print(), input(), len(), int()… Ce sont des morceaux de code rangés sous un nom, qu’on appelle quand on en a besoin. Créer ses propres fonctions permet :

  • d’éviter de copier-coller le même code à plusieurs endroits ;
  • de découper un gros problème en petits problèmes simples ;
  • de nommer ce que fait un bloc de code, ce qui rend le programme lisible ;
  • de tester chaque morceau séparément.

2. Définir et appeler une fonction

def dire_bonjour():                 # définition : rien ne s'exécute encore
    print("Bonjour !")
    print("Bienvenue dans le programme.")

dire_bonjour()                      # appel : le code s'exécute
dire_bonjour()                      # on peut l'appeler autant de fois qu'on veut
  • def + nom + parenthèses + deux-points, puis le corps indenté.
  • La fonction doit être définie avant d’être appelée (en haut du fichier en général).
  • Nom en minuscules avec _, de préférence un verbe : calculer_total, afficher_menu.

3. Les paramètres

Les paramètres sont des variables qui reçoivent des valeurs au moment de l’appel. Ces valeurs s’appellent les arguments.

def saluer(prenom, langue):
    if langue == "fr":
        print(f"Bonjour {prenom} !")
    elif langue == "en":
        print(f"Hello {prenom}!")

saluer("Léa", "fr")
saluer("Tom", "en")

On peut donner une valeur par défaut à un paramètre ; il devient alors facultatif :

def saluer(prenom, langue="fr"):
    ...

saluer("Léa")                 # langue vaudra "fr"
saluer("Tom", langue="en")

4. Renvoyer un résultat : return

return renvoie une valeur au code qui a appelé la fonction, et termine la fonction.

def prix_ttc(prix_ht, taux=0.20):
    return prix_ht * (1 + taux)

total = prix_ttc(100)                  # total vaut 120.0
print(f"{prix_ttc(50):.2f} €")         # 60.00 €
somme = prix_ttc(10) + prix_ttc(20)    # on peut calculer avec

Une fonction peut renvoyer plusieurs valeurs, séparées par des virgules :

def division(a, b):
    return a // b, a % b

quotient, reste = division(17, 5)     # quotient = 3, reste = 2

5. La portée des variables

Une variable créée dans une fonction est locale : elle n’existe que pendant l’exécution de la fonction et est invisible à l’extérieur.

def calculer():
    resultat = 42       # variable locale
    return resultat

calculer()
print(resultat)         # NameError : resultat n'existe pas ici

valeur = calculer()     # la bonne façon : récupérer ce qui est renvoyé
print(valeur)

6. Documenter et tester

Juste sous la ligne def, un texte entre triples guillemets (la docstring) explique ce que fait la fonction. assert vérifie qu’un résultat est bien celui attendu : si ce n’est pas le cas, le programme s’arrête avec une erreur.

def est_majeur(age):
    """Renvoie True si age est supérieur ou égal à 18."""
    return age >= 18

# Tests
assert est_majeur(18) == True
assert est_majeur(17) == False
assert est_majeur(40) == True
print("Tous les tests sont passés.")

Tester les cas limites (ici 17 et 18) est essentiel : c’est là que se cachent la plupart des erreurs.

7. Structurer un programme

Un programme bien organisé ressemble à ceci : les imports en haut, puis les fonctions, puis le programme principal, souvent rangé dans une fonction main().

import random

def lancer_de(faces=6):
    """Simule le lancer d'un dé."""
    return random.randint(1, faces)

def lancer_plusieurs(nb, faces=6):
    """Lance nb dés et renvoie la somme."""
    total = 0
    for i in range(nb):
        total += lancer_de(faces)
    return total

def main():
    nb = int(input("Combien de dés ? "))
    print(f"Résultat : {lancer_plusieurs(nb)}")

main()

8. Mini-projet : la calculatrice

9. Bilan

Exercices corrigés

Ce qui compte dans ce niveau, c’est le découpage. Si tes fonctions ont des noms différents mais font la même chose, c’est très bien. Vérifie surtout que chaque fonction renvoie son résultat au lieu de l’afficher.

Exercice 4.1 — Fonctions de calcul

Voir le corrigé
def carre(n):
    return n * n

def est_pair(n):
    return n % 2 == 0

def maximum(a, b, c):
    plus_grand = a
    if b > plus_grand:
        plus_grand = b
    if c > plus_grand:
        plus_grand = c
    return plus_grand

def moyenne(a, b, c):
    return (a + b + c) / 3

def mention(note):
    if note >= 16:
        return "Très bien"
    elif note >= 14:
        return "Bien"
    elif note >= 12:
        return "Assez bien"
    elif note >= 10:
        return "Passable"
    return "Insuffisant"

assert carre(4) == 16
assert est_pair(10) and not est_pair(7)
assert maximum(3, 9, 5) == 9
assert moyenne(10, 12, 14) == 12
assert mention(14) == "Bien"

Explication

Chaque fonction a une seule responsabilité et renvoie une valeur. Dans est_pair, la comparaison n % 2 == 0 est déjà un booléen : inutile d’écrire if ... return True else return False. Dans mention, le dernier return n’a pas besoin de else puisque les return précédents terminent la fonction.

Pour aller plus loin

# Versions avec les fonctions intégrées de Python
def maximum(a, b, c):
    return max(a, b, c)

def moyenne(*nombres):             # accepte autant de nombres que l'on veut
    return sum(nombres) / len(nombres)

Exercice 4.2 — Contrôle de saisie réutilisable

Voir le corrigé
def demander_entier(question, mini, maxi):
    """Redemande jusqu'à obtenir un entier entre mini et maxi."""
    n = int(input(question))
    while n < mini or n > maxi:
        print(f"Merci d'entrer un nombre entre {mini} et {maxi}.")
        n = int(input(question))
    return n

age = demander_entier("Âge : ", 0, 120)
mois = demander_entier("Mois : ", 1, 12)

Si l’utilisateur tape du texte, int() plante encore : le niveau 6 réglera ce problème avec try/except.

Explication

La fonction est générique grâce à ses paramètres : la même logique sert pour l’âge, le mois, une note… Elle s’utilise ensuite en une ligne.

Mini-projet

Voir le corrigé
def afficher_menu():
    print("\n+  -  *  /  ^ (puissance)  q (quitter)")

def demander_nombre(question):
    return float(input(question))

def calculer(a, b, operation):
    if operation == "+":
        return a + b
    elif operation == "-":
        return a - b
    elif operation == "*":
        return a * b
    elif operation == "/":
        if b == 0:
            return None
        return a / b
    elif operation == "^":
        return a ** b
    return None

def main():
    while True:
        afficher_menu()
        op = input("Opération : ")
        if op == "q":
            print("Au revoir !")
            break
        if len(op) != 1 or op not in "+-*/^":
            print("Opération inconnue.")
            continue
        a = demander_nombre("Premier nombre : ")
        b = demander_nombre("Second nombre : ")
        resultat = calculer(a, b, op)
        if resultat is None:
            print("Calcul impossible (division par zéro).")
        else:
            print(f"Résultat : {resultat}")

assert calculer(2, 3, "+") == 5
assert calculer(10, 0, "/") is None
assert calculer(2, 3, "^") == 8
main()

Explication

main() ne fait qu’orchestrer : afficher le menu, lire le choix, appeler calculer. Les tests assert sont placés avant main() : si un calcul est faux, on le sait dès le lancement. La condition len(op) != 1 évite qu’une saisie vide ou « +- » soit acceptée.

🧠 Testez vos connaissances

5 questions. Répondez puis cliquez sur « Corriger ». Rien n’est enregistré : c’est de l’auto-évaluation.

1. Quelle est la différence entre print et return dans une fonction ?

💬 Une fonction de calcul renvoie ; c’est le programme principal qui affiche.

2. Que vaut b après def double(x): print(x * 2) puis b = double(5) ?

💬 La fonction affiche 10 mais ne renvoie rien : b vaut None.

3. Une variable créée dans une fonction…

💬 C’est la portée locale. Pour transmettre une valeur, on utilise return.

4. À quoi sert assert moyenne(10, 12, 14) == 12 ?

💬 Si le test échoue, le programme s’arrête immédiatement et signale l’erreur.

5. Pourquoi regrouper la validation des saisies dans une seule fonction ?

💬 Un contrôle copié-collé partout finit toujours par être oublié quelque part : c’est ainsi que naissent les failles.

© 2026 Bruno Jousseaume. Ce cours est publié sous licence CC BY-NC-SA 4.0 : vous pouvez le partager et l’adapter en citant l’auteur et un lien vers cette page, sans usage commercial, et en partageant vos adaptations sous la même licence.

Pour aller plus loin