Stage Toussaint · dès le 19 octobre
Majorant
📘 Fiche de cours · 1re année📐 MPSI💻 Informatique Informatique communeNiveau · Terminale → Sup

Lire, tester et corriger un programme

Dérouler un programme à la main, reconnaître les patrons max / min / comptage / recherche, et tester un code sur ses cas limites — avec le piège du maximum initialisé à 0 et deux exercices corrigés.

Fiche rédigée par les mentors Majorant — alumni Polytechnique, CentraleSupélec et Mines Paris.

1 définitionsMis à jour le 2026-08-02

Vue d'ensemble

En prépa, la moitié du travail en informatique consiste à lire du code, pas à en écrire. En DS comme aux concours, on te demande sans arrêt de prévoir la sortie d'un programme, de dire ce qu'il calcule, ou de trouver l'erreur dans un code qui ne marche pas. Ce sont trois compétences distinctes de l'écriture — et elles se travaillent.

Cette fiche te donne la méthode : tracer un programme à la main (la table de trace), reconnaître les patrons classiques en lecture (max, min, somme, comptage, recherche), tester proprement avec assert et des jeux de cas bien choisis, et déboguer en lisant le message d'erreur. C'est la boîte à outils du lecteur de code.

Objectif passerelle Terminale → Sup — Dérouler n'importe quel programme à la main sans machine, deviner ce qu'un code calcule en le lisant, écrire des tests avec des cas limites, et savoir quoi faire quand Python affiche une erreur en rouge.

Prérequis

  • Variables, affectation, types de base (int, float, str, list)
  • Boucles for et while, conditions
  • Fonctions : paramètres, return
  • Listes et parcours par élément ou par indice
🎯 Accompagnement Majorant

Tu sais coder mais tu bloques dès qu'il faut lire le code d'un autre ? Prévoir la sortie et repérer un bug sont des compétences à part entière, très évaluées et rarement enseignées. Nos mentors alumni X · Centrale · Mines t'entraînent à dérouler et déboguer n'importe quel programme sans machine.

Trouver un mentor →

1. La table de trace, méthode systématique

Pour prévoir la sortie d'un programme, on ne devine pas : on le déroule, ligne par ligne, en notant la valeur de chaque variable dans un tableau. C'est la table de trace, l'outil numéro un du lecteur de code.

Définition 1.1 — Table de trace

Un tableau où l'on suit l'exécution d'un programme : une colonne par variable (plus éventuellement une colonne pour la condition testée), et une ligne par tour de boucle. On remplit case par case en jouant le rôle de l'ordinateur.

📐 Méthode — tracer un programme.
  1. Note l'état initial des variables (avant la boucle) sur une première ligne.
  2. Pour chaque tour de boucle, crée une nouvelle ligne.
  3. Évalue les conditions avec les valeurs actuelles, puis applique les affectations.
  4. Ne modifie une variable qu'au moment où le code le fait — jamais avant.
  5. La dernière ligne donne les valeurs finales : c'est ce que le programme affiche ou renvoie.

Traçons un programme qui cherche le plus grand élément et son indice :

t = [4, 2, 9, 5]
m = t[0]
imax = 0
for i in range(1, len(t)):
    if t[i] > m:
        m = t[i]
        imax = i
print(m, imax)
Table de trace — une colonne par variable, une ligne par tour
Tourit[i]t[i] > m ?mimax
init40
112faux40
229vrai92
335faux92

Le programme affiche 9 2 : le maximum est 9, situé à l'indice 2. Remarque que range(1, len(t)) commence à 1 : on ne recompare pas le premier élément avec lui-même.

📝 La colonne « condition ». Ajouter une colonne pour la condition du if (ou du while) évite 90 % des erreurs de trace : on écrit noir sur blanc si on entre dans le bloc ou non, au lieu de le décider de tête.
⚠ Modifier une variable trop tôt. À chaque ligne, on lit les anciennes valeurs pour évaluer les conditions, puis on écrit les nouvelles. Si tu mets à jour m avant de tester t[i] > m, ta trace est fausse dès le premier tour.

2. Reconnaître les patrons en lecture

Un examinateur te montre un bout de code et demande : « que calcule cette fonction ? ». Plutôt que de tracer intégralement, on gagne un temps fou en reconnaissant le patron : une variable accumulée dans une boucle trahit presque toujours un max, un min, une somme, un comptage ou une recherche. Voici comment les repérer. (Pour écrire ces algorithmes toi-même, va voir la fiche dédiée « Patrons d'algorithmes classiques sur les listes ».)

Que calcule cette fonction ? Lis-la avant de dérouler la réponse.

def f(t):
    r = t[0]
    for x in t:
        if x < r:
            r = x
    return r
🔍 Décryptage ligne par ligne
r = t[0]Initialisation par un vrai élément. On ne part pas de 0 : signe d'un patron max ou min.
if x < r: r = xOn garde le plus petit vu. Le comparateur est <, donc r descend vers les petites valeurs.
return rVerdict. C'est le minimum de la liste. Avec >, c'eût été le maximum.

Deuxième extrait :

def g(t):
    s = 0
    for x in t:
        s = s + x
    return s / len(t)
🔍 Décryptage ligne par ligne
s = 0Accumulateur à zéro. On additionne : patron somme.
s = s + xAjout de chaque élément. À la fin, s est la somme totale.
return s / len(t)La division change tout. Somme divisée par l'effectif = moyenne.

Troisième extrait — attention au repère du comptage :

def h(t):
    c = 0
    for x in t:
        if x % 2 == 0:
            c = c + 1
    return c
🔍 Décryptage ligne par ligne
c = 0Compteur à zéro. On part de 0 comme la somme, mais…
if x % 2 == 0: c = c + 1… on ajoute 1, pas x. C'est la signature du comptage : on n'ajoute que 1, et seulement sous condition.
return cVerdict. Nombre d'éléments pairs de la liste.

Dernier extrait — un retour anticipé dans la boucle :

def cherche(t, v):
    for i in range(len(t)):
        if t[i] == v:
            return i
    return -1
🔍 Décryptage ligne par ligne
if t[i] == v: return iSortie dès qu'on trouve. Le return dans la boucle stoppe la recherche au premier v rencontré : patron recherche séquentielle.
return -1Le cas « absent ». On n'atteint cette ligne que si la boucle finit sans avoir trouvé : on renvoie l'indice-sentinelle -1.
📝 Le réflexe. Regarde d'abord l'initialisation (0 → somme/comptage ; t[0] → max/min) et le cœur de la boucle (s + x → somme ; c + 1 → comptage ; comparaison → max/min ; return anticipé → recherche). En deux secondes, tu sais à quoi tu as affaire.

3. Tester : assert et jeux de tests

Un programme « qui a l'air juste » n'est pas un programme juste. On le teste : on lui donne des entrées dont on connaît la réponse, et on vérifie qu'il la produit. L'outil de base est l'instruction assert.

Définition 3.1 — assert

assert condition ne fait rien si la condition est vraie, et interrompt le programme avec une AssertionError si elle est fausse. C'est une alarme silencieuse tant que tout va bien.

def somme(t):
    s = 0
    for x in t:
        s = s + x
    return s

assert somme([1, 2, 3]) == 6     # cas normal
assert somme([5]) == 5           # cas limite : un seul élément
assert somme([]) == 0            # cas limite : liste vide
print("Tous les tests passent")
🔍 Décryptage ligne par ligne
assert somme([1, 2, 3]) == 6Cas normal. Une entrée « typique » dont on calcule la réponse à la main : 1+2+3 = 6.
assert somme([5]) == 5Cas limite : un seul élément. La boucle ne tourne qu'une fois — un grand classique de bug.
assert somme([]) == 0Cas limite : liste vide. La boucle ne tourne pas du tout ; somme doit renvoyer 0. Un algorithme mal écrit planterait ici.
print("Tous les tests passent")Signal de vie. Si ce message s'affiche, aucun assert n'a échoué.
📐 Méthode — choisir un bon jeu de tests.
  1. Le cas normal : une entrée représentative dont tu connais la réponse exacte.
  2. Le cas limite « petit » : liste à un seul élément, où la boucle tourne une fois.
  3. Le cas limite « vide » : liste vide, où la boucle ne tourne pas.
  4. Le cas piège : valeurs négatives, doublons, élément absent selon l'algorithme.
⚠ Le cas vide qui fait planter. maximum([]) avec m = t[0] lève une IndexError : la liste vide n'a pas d'élément d'indice 0. Selon le sujet, soit on l'interdit (préconditions), soit on le traite à part. Tester la liste vide révèle immédiatement ce genre de faille.
📝 Pourquoi tester ? Un test qui échoue te dit exactement quelle entrée casse ton code, avant le correcteur. Aux concours d'informatique, écrire soi-même des cas de test bien choisis est régulièrement une question notée : ce n'est pas un bonus, c'est du programme.

4. Déboguer : trouver l'erreur

Quand Python affiche du rouge, ne panique pas : le message te dit quel type d'erreur et à quelle ligne. Apprendre à le lire, c'est déjà régler la moitié des bugs.

4.1 Lire le message d'erreur

Trois erreurs reviennent tout le temps. Il faut les reconnaître d'un coup d'œil.

print(resultat)
# NameError: name 'resultat' is not defined
📝 NameError. Tu utilises un nom qui n'existe pas : variable jamais définie, faute de frappe (resultat vs resutlat), ou définie après son utilisation.
t = [1, 2, 3]
print(t[3])
# IndexError: list index out of range
📝 IndexError. Tu accèdes à un indice qui n'existe pas. Une liste de longueur 3 a des indices 0, 1, 2 : t[3] déborde. Cause typique : range(len(t) + 1) au lieu de range(len(t)).
print("3" + 3)
# TypeError: can only concatenate str (not "int") to str
📝 TypeError. Tu mélanges des types incompatibles, ici une chaîne et un entier. Souvent un input() (qui renvoie une chaîne) qu'on a oublié de convertir avec int(...).

4.2 Déboguer avec print

Le code ne plante pas mais donne un mauvais résultat ? Insère des print pour voir les valeurs pendant l'exécution, au lieu de les imaginer.

def somme_positifs(t):
    s = 0
    for x in t:
        if x > 0:
            s = s + x
        print("x =", x, "| s =", s)   # espion temporaire
    return s

somme_positifs([3, -1, 4])
💡 Ce que révèle l'espion. L'affichage donne x = 3 | s = 3, puis x = -1 | s = 3 (le négatif est bien ignoré), puis x = 4 | s = 7. On voit l'accumulation se faire, tour après tour. Une fois le bug compris, on retire les print espions.

4.3 La dichotomie sur le code

Sur un programme long, on ne relit pas tout : on coupe en deux. On place un print au milieu pour vérifier que les valeurs y sont encore correctes. Si oui, le bug est dans la seconde moitié ; sinon, dans la première. On recommence sur la moitié fautive. En quelques coupes, on encercle la ligne coupable — la même idée que la recherche par dichotomie.

🎯 Passe le cap du débogage

Le débogage, ça se transmet. Savoir lire une IndexError et remonter à la ligne fautive en 30 secondes, ça change une note de DS. Nos mentors alumni X · Centrale · Mines t'apprennent leurs réflexes de lecture et de test, sur tes propres codes.

Être accompagné →

5. Lire une fonction qu'on n'a pas écrite

Face à une fonction inconnue, on ne lit pas au hasard : on suit une checklist qui donne du sens au code en moins d'une minute.

📐 Méthode — comprendre une fonction inconnue.
  1. Le nom : souvent un indice (mais ne pas s'y fier aveuglément).
  2. Les entrées : combien de paramètres, de quels types (liste ? entier ?).
  3. La sortie : que renvoie le return — un nombre, une liste, un booléen ?
  4. La trace : déroule la fonction sur un petit exemple concret (2 ou 3 valeurs).

Applique la méthode à cette fonction au nom volontairement muet :

def mystere(t):
    r = []
    for x in t:
        if x not in r:
            r.append(x)
    return r

Entrées : une liste t. Sortie : une nouvelle liste r (elle démarre vide et on lui ajoute des éléments). Traçons sur [1, 2, 2, 3, 1] :

Trace de mystere([1, 2, 2, 3, 1])
Tourxx déjà dans r ?r après
init[]
11non[1]
22non[1, 2]
32oui[1, 2]
43non[1, 2, 3]
51oui[1, 2, 3]

Verdict : mystere supprime les doublons en conservant l'ordre de première apparition. Le test x not in r n'ajoute un élément que s'il est nouveau. Le petit exemple a tout révélé — bien plus vite qu'en fixant le code.

📝 Choisis bien ton exemple. Un bon exemple d'exploration est petit mais révélateur : ici, il fallait des doublons (les deux 1 et les deux 2) pour voir le comportement clé. Une liste sans répétition n'aurait rien montré.

6. Exercices d'application

À faire de tête, table de trace à l'appui, avant d'ouvrir le corrigé.

Exo 1Prévoir la sortieIntermédiaire

Trace ce programme et donne ce qu'il affiche.

t = [5, 1, 8, 3]
m = t[0]
for x in t:
    if x < m:
        m = x
print(m)
Voir la correction détaillée
Initialisation : m = 5 (le premier élément).
x=5 : 5 < 5 non. x=1 : 1 < 5 oui, m = 1. x=8 : 8 < 1 non. x=3 : 3 < 1 non.
C'est le patron du minimum : affichage 1.
Exo 2Que calcule cette fonction ?Intermédiaire

Trace q sur [3, -1, 4, 0], puis dis en une phrase ce qu'elle calcule.

def q(t):
    c = 0
    for x in t:
        if x > 0:
            c = c + 1
    return c
Voir la correction détaillée
Trace : c=0 ; x=3 > 0 oui, c=1 ; x=-1 non ; x=4 > 0 oui, c=2 ; x=0 > 0 non.
q([3, -1, 4, 0]) renvoie 2.
Initialisation à 0 et c = c + 1 sous condition : c'est un comptage. q compte les éléments strictement positifs de la liste.

7. Erreurs classiques (les pièges qui coûtent des points)

Ces erreurs ne viennent pas d'un manque de connaissances mais d'un manque de méthode. Les connaître, c'est déjà les éviter.

⚠ Répondre sans tracer. « Ça affiche 12, à peu près sûr. » Non : on trace. La table de trace n'est pas une perte de temps, c'est ce qui transforme une réponse « au feeling » en réponse juste. Une ligne oubliée dans la boucle et le résultat change.
⚠ Oublier le cas limite « liste vide ». Un code qui marche sur [3, 7, 2] peut lever une IndexError sur [] (accès à t[0]) ou une ZeroDivisionError sur une moyenne (division par len(t) == 0). Teste toujours la liste vide et la liste à un élément.
⚠ Confondre les erreurs. Un NameError (nom inexistant) n'a rien à voir avec un IndexError (indice hors bornes) ni un TypeError (types incompatibles). Lire le type de l'erreur oriente directement vers la cause ; le confondre, c'est chercher au mauvais endroit.
⚠ print au lieu de return. Une fonction qui fait print(m) au lieu de return m affiche la valeur mais renvoie None. Du coup assert maximum([3, 7]) == 7 échoue, et x = maximum([3, 7]) met None dans x. Pour tester une fonction, il lui faut un vrai return.
⚠ Se fier au nom de la fonction. Une fonction appelée tri ne trie pas forcément, et mystere peut faire quelque chose de simple. Le nom oriente, le code décide : trace toujours pour confirmer.

7. Pour aller plus loin

Lire, tracer et tester sont des réflexes transversaux : tu les réinvestis dans presque tous les chapitres d'informatique. Voici les suites naturelles.

  • Patrons d'algorithmes classiques sur les listes — pour écrire toi-même les algos max, min, somme, comptage et recherche que cette fiche apprend à reconnaître.
  • Recherche par dichotomie — l'algorithme phare pour lequel la table de trace est indispensable, et où le débogage des bornes est un art.
  • Correction et terminaison d'un algorithme — pour prouver rigoureusement qu'un programme fait ce qu'on croit et s'arrête, au-delà des simples tests.

Récap final — Ce qu'il faut absolument retenir

Tu dois pouvoir répondre « oui » sans hésiter à chaque point.

  • Sais-tu dresser une table de trace avec une colonne par variable et une ligne par tour de boucle ?
  • Sais-tu qu'on lit les anciennes valeurs pour tester les conditions, puis qu'on écrit les nouvelles ?
  • Sais-tu reconnaître en lecture les patrons max, min, somme, comptage et recherche ?
  • Sais-tu que l'initialisation (0 ou t[0]) et le cœur de boucle trahissent le patron ?
  • Sais-tu distinguer un comptage (on ajoute 1) d'une somme (on ajoute x) ?
  • Sais-tu écrire des tests avec assert et ce que fait assert quand la condition est fausse ?
  • Sais-tu choisir un jeu de tests : cas normal, un seul élément, liste vide, cas piège ?
  • Sais-tu reconnaître un NameError, un IndexError et un TypeError ?
  • Sais-tu déboguer en insérant des print espions, puis en les retirant ?
  • Sais-tu appliquer la dichotomie sur le code pour encercler la ligne fautive ?
  • Sais-tu comprendre une fonction inconnue (nom, entrées, sortie, trace sur un petit exemple) ?
  • Sais-tu qu'une fonction qui print au lieu de return renvoie None ?

Débloque la fiche complète

Théorèmes, démonstrations à savoir refaire, méthodes-types et pièges de concours : crée ton compte gratuit pour tout lire. Une seule fois pour toutes les fiches et ressources Majorant.

Gratuit · vos données restent confidentielles.

Valide tes acquis

Quiz — Lire et tester

8 questions · une à la fois · seuil de maîtrise 80 %.

Informatique commune · Terminale → SupQuiz — Lire et tester un programmeQuestion 1 / 8
FacileChoix unique1 pt

Pour trouver le maximum d'une liste, par quelle valeur faut-il initialiser la variable m ?

Sélectionne une réponse pour valider.

Fiches associées

Tu veux aller plus loin sur ce chapitre ?

Nos mentors ont passé les mêmes concours, en MPSI, deux à trois ans plus tôt. Ils reprennent ce chapitre avec toi — démonstrations détaillées, exercices type concours, oraux blancs.

Cours particuliers d'informatique en MPSI

Voir aussi : Cours particuliers d'informatique en prépa scientifique