Aller au contenu

Numérique et sciences informatiques (spécialité) · TerminaleBac

Mise au point des programmes : exercices corrigés de Terminale NSI

Publié le 7 novembre 2026 · Mis à jour le 7 novembre 2026 · Signaler une erreur

L'essentiel

  • La mise au point commence par reproduire le bug : sans cas de test qui le déclenche à coup sûr, on corrige à l'aveugle.
  • Un programme fautif ne plante pas toujours : il peut s'exécuter jusqu'au bout et donner un résultat faux.
  • Une assertion ne teste qu'un seul point précis du programme.
  • On localise l'erreur en suivant les valeurs des variables (trace d'exécution), puis on corrige une chose à la fois et on relance les tests.
  • Un programme découpé en petites fonctions, bien nommées, est plus facile à mettre au point.

Comment utiliser ces exercices

La mise au point d'un programme, que l'on appelle aussi débogage, consiste à repérer une erreur, à la comprendre, puis à la corriger 2. Au programme de Terminale NSI, elle fait l'objet d'une ressource d'accompagnement dédiée, à côté de la gestion des bugs 3. Ces exercices te font pratiquer cette démarche sur de petits programmes Python que tu pourras recopier et exécuter toi-même.

Chaque exercice contient un bug différent. Pour progresser, ne cherche pas la correction tout de suite : lis d'abord le code, devine ce qu'il fait, puis vérifie en l'exécutant.

Pourquoi écrire des programmes faciles à mettre au point

La difficulté d'une mise au point dépend en grande partie de la façon dont le code a été écrit : certaines habitudes d'écriture la rendent bien plus simple 2. Concrètement, tu peux appliquer des réflexes simples :

  • découper le travail en petites fonctions qui font une seule chose ;
  • donner aux variables et aux fonctions des noms parlants ;
  • écrire les tests en même temps que la fonction, pas après ;
  • éviter de modifier plusieurs choses en même temps lors d'une correction.

Les exercices

Exercice 1 Reproduire un bug sur une moyenne

★☆☆Environ 8 min

On considère la fonction suivante.

def moyenne(liste):
    return sum(liste) / len(liste)
  1. Quelle valeur renvoie moyenne([12, 8, 10]) ?
  2. Trouve une entrée qui fait planter la fonction et indique le type d'erreur obtenu.
  3. Propose une correction qui renvoie None dans ce cas et écris une assertion qui la vérifie.

Donne comme réponse numérique le résultat de la question 1.

Indice 1

Calcule la somme, puis divise par le nombre d'éléments.

Indice 2

Pense à la liste qui ne contient aucun élément : combien vaut len(liste) ?

Voir la correction pas à pas
  1. Question 1 : la somme vaut 12 + 8 + 10 = 30 et la liste compte 3 éléments, donc la fonction renvoie 30 / 3 = 10.0.

  2. Question 2 : on reproduit le bug avec la liste vide []. Alors sum([]) vaut 0 et len([]) vaut 0, donc Python tente la division 0 / 0 et lève une erreur ZeroDivisionError. L'entrée [] déclenche le bug à chaque exécution : il est reproductible.

  3. Question 3 : on traite le cas à part avec un test au début de la fonction : if len(liste) == 0: return None, puis on garde la ligne de calcul.

  4. On écrit ensuite une assertion unique pour ce comportement précis : assert moyenne([]) is None. Une seconde assertion distincte, assert moyenne([12, 8, 10]) == 10, vérifie le cas normal.

Le bug apparaît uniquement pour une entrée particulière, la liste vide. C'est pourquoi on teste toujours les cas limites (vide, un seul élément) en plus d'un cas ordinaire.

Exercice 2 Écrire des assertions pour une fonction maximum

★☆☆Environ 10 min

Voici une fonction censée renvoyer le plus grand élément d'une liste non vide.

def maximum(liste):
    m = 0
    for x in liste:
        if x > m:
            m = x
    return m
  1. Écris trois assertions, chacune testant un point précis, dont une qui met la fonction en échec.
  2. Explique l'origine du bug.
  3. Corrige la fonction.
Indice 1

Que renvoie la fonction si tous les nombres de la liste sont négatifs ?

Indice 2

Par quelle valeur faut-il initialiser m pour que cela marche avec n'importe quelle liste non vide ?

Voir la correction pas à pas
  1. On écrit une assertion par comportement : assert maximum([3, 9, 4]) == 9 (cas ordinaire), assert maximum([7]) == 7 (un seul élément) et assert maximum([-5, -2, -8]) == -2 (nombres négatifs). Chaque assertion ne teste qu'un point.

  2. On exécute : les deux premières passent, la troisième échoue. La fonction renvoie 0 au lieu de -2.

  3. Explication : m est initialisé à 0. Aucun élément négatif n'est strictement supérieur à 0, donc m ne change jamais et la fonction renvoie 0, valeur qui n'est même pas dans la liste.

  4. Correction : on initialise m avec le premier élément de la liste, m = liste[0]. Le maximum est alors toujours un élément de la liste.

  5. On relance les trois assertions : elles passent toutes.

Le bug ne se manifestait qu'avec un type de données précis (nombres négatifs). Trois assertions séparées ont permis d'isoler le cas fautif sans ambiguïté, ce qu'une assertion unique mélangeant plusieurs cas n'aurait pas fait.

Exercice 3 Suivre une boucle : l'erreur d'un cran

★★☆Environ 10 min

Cette fonction doit calculer la somme des entiers de 1 à n.

def somme(n):
    total = 0
    for i in range(1, n):
        total = total + i
    return total
  1. Construis le tableau de trace pour somme(5).
  2. Donne l'écart entre le résultat attendu et le résultat renvoyé pour n = 5.
  3. Corrige la fonction.
Indice 1

Dans range(1, n), la valeur n est-elle atteinte ?

Indice 2

Note à chaque passage la valeur de i et celle de total.

Voir la correction pas à pas
  1. Trace pour n = 5 : la boucle parcourt i = 1, 2, 3, 4. Après chaque passage, total vaut successivement 1, 3, 6, puis 10.

  2. La fonction renvoie donc 10, alors que la somme attendue 1 + 2 + 3 + 4 + 5 vaut 15.

  3. L'écart vaut 15 - 10 = 5, c'est-à-dire exactement la valeur de n : la dernière valeur n'est jamais ajoutée. La borne de droite de range est exclue, d'où cette erreur d'un cran.

  4. Correction : for i in range(1, n + 1):.

  5. Vérification par assertion : assert somme(5) == 15. On ajoute assert somme(1) == 1 pour le plus petit cas.

Le programme ne plante pas et renvoie un nombre plausible, mais faux. Seule la comparaison avec une valeur attendue calculée à part révèle le bug. Le tableau de trace a montré précisément quelle valeur manquait.

Exercice 4 Un bug sans plantage : la conversion de température

★★☆Environ 12 min

On veut convertir des degrés Celsius en degrés Fahrenheit avec la formule F=C×95+32F = C \times \frac{9}{5} + 32. Un élève écrit :

def en_fahrenheit(c):
    return c + 32 * 9 / 5
  1. Quelle valeur la fonction renvoie-t-elle pour c = 100 ? Quelle valeur est attendue ?
  2. Donne l'écart entre les deux.
  3. Explique le bug et corrige la fonction.
  4. Propose deux assertions : une pour la glace (0 °C) et une pour l'ébullition (100 °C).
Indice 1

Respecte les priorités des opérations : la multiplication passe avant l'addition.

Indice 2

Quelle valeur la formule donne-t-elle pour c = 0 ?

Voir la correction pas à pas
  1. Pour c = 100, la fonction calcule 100+32×9/5=100+57,6=157,6100 + 32 \times 9 / 5 = 100 + 57{,}6 = 157{,}6.

  2. La formule correcte donne 100×95+32=180+32=212100 \times \frac{9}{5} + 32 = 180 + 32 = 212.

  3. L'écart vaut 212−157,6=54,4212 - 157{,}6 = 54{,}4.

  4. Le bug vient de la place de c : dans le code, c'est 32 qui est multiplié par 9 / 5 et c est simplement additionné. La correction est return c * 9 / 5 + 32.

  5. Assertions : assert en_fahrenheit(0) == 32 et assert en_fahrenheit(100) == 212. Avec le code fautif, la première donne 57,6 et échoue immédiatement.

Aucune erreur n'est affichée : le programme est syntaxiquement correct, seul le sens du calcul est faux. Tester une valeur dont on connaît la réponse (0 °C donne 32 °F) suffit à le détecter.

Exercice 5 Récursivité sans cas de base

★★★Environ 15 min

Voici une fonction récursive censée calculer la factorielle de n, c'est-à-dire le produit n×(n−1)×⋯×1n \times (n-1) \times \dots \times 1 pour n entier positif.

def fact(n):
    return n * fact(n - 1)
  1. Que se passe-t-il quand on appelle fact(3) ? Écris la suite des appels.
  2. Quel est le bug ?
  3. Corrige la fonction en tenant compte du cas n = 0, pour lequel la factorielle vaut 1.
  4. Donne la valeur de fact(4) avec la fonction corrigée.
Indice 1

La fonction a-t-elle une condition qui arrête les appels ?

Indice 2

Écris sous forme de tableau les valeurs de n pour chaque appel.

Voir la correction pas à pas
  1. L'appel fact(3) appelle fact(2), qui appelle fact(1), puis fact(0), fact(-1), fact(-2), et ainsi de suite : n continue de diminuer sans jamais s'arrêter.

  2. Python finit par interrompre l'exécution lorsque la pile d'appels devient trop profonde et affiche une erreur de dépassement de récursion (RecursionError). Le bug se reproduit avec n'importe quelle entrée.

  3. Le bug : il manque le cas de base, la condition qui arrête la récursion sans nouvel appel.

  4. Correction : if n == 0: return 1 avant la ligne de récurrence, puis return n * fact(n - 1).

  5. Avec la fonction corrigée : fact(4) = 4 × fact(3) = 4 × 3 × fact(2) = 4 × 3 × 2 × fact(1) = 4 × 3 × 2 × 1 × fact(0) = 4 × 3 × 2 × 1 × 1 = 24.

  6. Assertions : assert fact(0) == 1 et assert fact(4) == 24.

Une fonction récursive a toujours deux parties : un cas de base qui s'arrête, et un appel sur une valeur plus petite. Ici la seconde partie existait, mais pas la première.

Exercice 6 Mettre au point un programme complet

★★★Environ 20 min

Le programme suivant doit renvoyer, pour une liste de notes, le nombre de notes supérieures ou égales à 10, puis le pourcentage correspondant.

def nb_reussites(notes):
    compteur = 0
    for i in range(1, len(notes)):
        if notes[i] > 10:
            compteur += 1
    return compteur

def pourcentage(notes):
    return nb_reussites(notes) / len(notes) * 100
  1. Choisis une liste de notes qui met en évidence deux bugs différents dans nb_reussites.
  2. Pour cette liste, donne le résultat attendu et le résultat obtenu.
  3. Corrige nb_reussites.
  4. Que se passe-t-il pour pourcentage([]) ? Propose une décision et justifie-la.
  5. Écris des assertions, une par comportement.
Indice 1

Regarde les bornes de la boucle : quel indice est le premier élément ?

Indice 2

Regarde la comparaison : une note égale à 10 est-elle comptée ?

Voir la correction pas à pas
  1. Bug 1 : range(1, len(notes)) commence à l'indice 1, donc la première note est ignorée. Bug 2 : la comparaison utilise > au lieu de >=, donc une note égale à 10 n'est pas comptée.

  2. Liste choisie : [10, 8, 14]. Résultat attendu : les notes 10 et 14 sont supérieures ou égales à 10, donc 2. Résultat obtenu : l'indice 0 (la note 10) est ignoré, la note 8 ne compte pas, la note 14 compte : le programme renvoie 1.

  3. Pour bien séparer les deux bugs, on peut aussi tester [12, 5] (le bug 1 donne 0 au lieu de 1) et [5, 10] (le bug 2 donne 0 au lieu de 1) : chaque liste met en évidence une seule erreur.

  4. Correction : for i in range(len(notes)): et if notes[i] >= 10:. On peut aussi écrire for note in notes: pour supprimer toute erreur d'indice.

  5. pourcentage([]) provoque une division par zéro, comme dans le premier exercice. Une décision cohérente est de renvoyer None pour une liste vide, car un pourcentage n'a pas de sens sans aucune note ; l'appelant décide alors quoi afficher.

  6. Assertions, une par comportement : assert nb_reussites([10, 8, 14]) == 2, assert nb_reussites([12, 5]) == 1, assert nb_reussites([5, 10]) == 1, assert nb_reussites([]) == 0 et assert pourcentage([]) is None.

  7. On corrige un bug à la fois et on relance toutes les assertions après chaque modification, pour être sûr de ne pas en introduire un troisième.

Quand plusieurs bugs coexistent, des tests séparés les distinguent : un test qui mélange tout indique seulement que « quelque chose » ne va pas. La fonction découpée en deux petites fonctions a aussi permis de tester chaque partie à part, ce qui rend la mise au point plus simple.

Les questions qu'on se pose

Par où commencer quand mon programme ne marche pas ?

Commence par reproduire le bug avec une entrée précise, car savoir le mettre en évidence et le reproduire est la première étape de la mise au point 2. Écris ensuite ce que tu attendais comme résultat, puis compare avec ce que le programme donne. Ce n'est qu'après que tu cherches la ligne fautive.

Comment écrire de bonnes assertions ?

Une assertion ne teste qu'un point précis du programme 1. Écris-en une pour un cas ordinaire, une pour un cas limite (liste vide, un seul élément, zéro) et une pour chaque bug déjà rencontré. Si une assertion échoue, tu sais immédiatement quel comportement corriger.

Mon programme ne plante pas mais le résultat est faux : est-ce un bug ?

Oui. Un programme erroné ne plante pas toujours, selon la donnée d'entrée 2. Seule la comparaison avec un résultat attendu, calculé à part, permet de le repérer. Prends l'habitude de vérifier tes fonctions sur des valeurs dont tu connais la réponse.

Sources

  1. Mise au point de programmes, gestion des bugs, Éduscol. Consulté le 7 novembre 2026.
  2. Gestion des bugs NSI - Ressources d'accompagnement, Éduscol. Consulté le 7 novembre 2026.
  3. Programmes et ressources en numérique et sciences informatiques, Éduscol. Consulté le 7 novembre 2026.
  4. Programmation impérative, Wikipédia. Consulté le 7 novembre 2026.

Les numéros dans le texte renvoient à ces sources. Une source qui ne dit pas ce qu'on lui fait dire ? Signale-le.

Signaler une erreur sur cette page

Je suis en…

Primaire

  • CP Bientôt
  • CE1 Bientôt
  • CE2 Bientôt
  • CM1 Bientôt
  • CM2 Bientôt

Collège

Lycée

Supérieur

  • BTS Bientôt
  • BUT Bientôt
  • Licence Bientôt
  • Prépas Bientôt

Sur cette page