Collection « Challenges » · Apprendre à coder en Python · Collégiens · Master
Mon projet de jeu de A à Z — 4 mois pour créer, documenter et transmettre « Attrape-lettres »
En quatre mois, tu mènes un vrai projet de jeu de A à Z : des données bien rangées, des personnages qui sont des objets, un jeu en images, un projet documenté… et tu apprends à le présenter et à l'enseigner aux autres.
32 épisodes · 4 mois2 épisodes par semaine (mardi et jeudi)Basthon, Capytale, Thonny et Pyxel≈ 25 min / épisode
BOOST · 5 JOURSPasser des blocs au texte et créer ton premier quiz.
PRO · 20 JOURSCréer un mini-jeu avec boucles, listes, hasard et tes propres fonctions.
MASTER · 4 MOISMener un projet de jeu complet et l'expliquer aux autres.
Le fil rouge. Inès, 13 ans, en 4e (personnage fictif), a créé « Le mot mystère ». Le collège prépare ses portes ouvertes : elle y présentera un vrai jeu en images et animera un atelier pour des CM2.
Chaque semaine = un épisode « Comprendre » le mardi, un épisode « Pratiquer » le jeudi. Chaque arc se termine par un bilan et un badge.
Tes données restent chez toi. Ta progression et ton journal sont enregistrés seulement dans ce navigateur. Dans les exercices, utilise des pseudos, jamais de vrais noms.
Règle d'or. Un code que tu ne comprends pas, tu ne le lances pas.
Ce que tu sais déjàTu écris, lances et répares un programme (Boost, épisodes 1 à 4). Tu fais répéter avec for et while (Pro, épisode 1), tu travailles le texte et les f-strings (Pro, épisode 3), tu ranges des valeurs dans des listes (Pro, épisode 6), tu tires au hasard (Pro, épisode 8), tu crées tes propres fonctions (Pro, épisode 11) et tu écris un code lisible (Pro, épisode 13). Tu chasses les bugs, tu utilises un débogueur et tu écris un plan de test (Pro, épisodes 16, 18 et 19). Tu démarres ici sans avoir suivi le Boost et le Pro ? Le kit de rattrapage est en fin de livre.
ARC 1 · SEMAINES 1 À 4
Des données plus riches
Avant de faire bouger quoi que ce soit, un jeu a besoin de données bien rangées : des mots, des joueurs, des scores. En quatre semaines, tu construis le tableau des meilleurs scores d'Attrape-lettres.
Semaine 1 · Les dictionnaires
01
S1 · MARDI · Comprendre
Des étiquettes à la place des numéros
Ranger des valeurs sous des noms avec un dictionnaire, les retrouver, les modifier et les parcourir.
⏱ 20 min de lecture · 5 min de quiz
[1]Scénario
Inès · Mardi, 12 h 40
Le principal est passé au club : pour les portes ouvertes du printemps, il veut un stand avec un jeu à faire essayer aux futurs élèves. Inès a déjà une idée, « Attrape-lettres », et une première envie : afficher les meilleurs scores. Elle crée deux listes, pseudos et scores. Malik ajoute un joueur dans la première liste, oublie la seconde… et son score de 8 se retrouve attribué à Comete. « Il faudrait que chaque score porte le nom de son joueur », soupire Inès.
[2]Concept
Le dictionnaire, un rangement par étiquettes
Une liste range des valeurs par numéro (indice 0, 1, 2… voir Pro, épisode 6). Un dictionnaire les range par étiquette : chaque valeur est rangée sous une clé. On l'écrit entre accolades, avec des paires clé: valeur séparées par des virgules.
Code
scores = {"Pixel": 9, "Lynx": 7}
print(scores["Pixel"])
scores["Comete"] = 4
scores["Lynx"] = 8
print(scores)
print(len(scores))
print("Nova" in scores)
for pseudo, score in scores.items():
print(f"{pseudo} : {score}")
print(scores.get("Nova", 0))
Une clé est unique. Écrire scores["Lynx"] = 8 alors que "Lynx" existe déjà remplace l'ancienne valeur : il n'y a jamais deux « Lynx ».
Si la clé n'existe pas, scores["Nova"] arrête le programme avec une erreur que tu sais lire (voir Boost, épisode 2) :
Ce que tu vois
print(scores["Nova"])
KeyError: 'Nova'
Key = clé. Pour éviter cette erreur, on vérifie avec in, ou on lit avec .get(clé, valeur par défaut).
Liste
Dictionnaire
["Pixel", "Lynx"]
{"Pixel": 9, "Lynx": 7}
on retrouve par numéro : liste[0]
on retrouve par clé : scores["Pixel"]
l'ordre et les numéros comptent
ce qui compte, c'est l'étiquette
Suivre les variables · un dictionnaire qui change
Ce qui s'affiche
[3]Recherche
Ce que disent les sources
Tutoriel officiel de Python — Un dictionnaire associe des clés à des valeurs ; les clés sont uniques, et ranger une valeur sous une clé qui existe déjà remplace l'ancienne. Lire une clé absente provoque une KeyError ; get renvoie une valeur par défaut à la place. in teste la présence d'une clé, et items() donne les paires clé-valeur dans une boucle [1].
Depuis Python 3.7 (2018) — L'ordre d'un dictionnaire est garanti : c'est l'ordre dans lequel les clés ont été ajoutées. Modifier la valeur d'une clé existante ne change pas sa place [2].
Ce que peut être une clé — Un texte ou un nombre ; pas une liste, car une clé ne doit pas pouvoir changer [1].
[4]Mythes
« Un dictionnaire range ses clés par ordre alphabétique. »
il garde l'ordre dans lequel les clés ont été ajoutées : « Comete » arrive après « Lynx » parce qu'elle a été ajoutée après.
« Un dictionnaire peut contenir deux fois la même clé. »
chaque clé est unique ; ranger une nouvelle valeur sous une clé existante remplace l'ancienne.
« On lit un dictionnaire avec un numéro, comme une liste. »
on le lit avec une clé : scores["Pixel"], pas scores[0].
[5]Quiz
1. Après d = {"a": 1, "b": 2} puis d["a"] = 5, qu'affiche print(d["a"], len(d)) ?
la clé "a" existait : sa valeur est remplacée, et le dictionnaire a toujours 2 paires (sortie vérifiée).
2. scores = {"Pixel": 9}. Que donne scores.get("Lynx", 0) ?
la clé n'existe pas, get renvoie la valeur par défaut donnée, ici 0.
3. Que teste "Pixel" in scores ?
pour un dictionnaire, in regarde les clés.
[6]Kit
🎒 Ton kit — Épisode 1
15 min
Exercice : prédire trois dictionnaires. Écris sur papier ce que chaque programme affiche, puis lance-le.
# Programme C
niveaux = {"facile": 4, "moyen": 6}
for nom in niveaux:
print(nom)
print("difficile" in niveaux)
print(niveaux.get("difficile", "inconnu"))
Corrigé (sorties réelles) :
A → 3, puis jaune.
B → {'Pixel': 2, 'Lynx': 3}.
C → facile, moyen, False, inconnu. Une boucle for sur un dictionnaire, sans .items(), donne seulement les clés.
Checklist
Je sais créer un dictionnaire, lire une valeur et en ajouter une.
Je sais pourquoi scores["Nova"] peut provoquer une KeyError, et comment l'éviter.
J'ai prédit puis vérifié les 3 programmes.
Vigilanceles clés sont sensibles aux majuscules et aux accents : "Pixel" et "pixel" sont deux clés différentes. Choisis une écriture et garde-la partout.
[7]Journal
✍️ Journal de bord
Dans un jeu ou une application que tu connais, quelles informations sont rangées « par étiquette » plutôt que « par numéro » ? Donne deux exemples.
Python Software Foundation, modification de la documentation des types natifs : « Dict order is guaranteed to be insertion order » (version 3.7), annonce python-checkins de juin 2018, consulté le 29/10/2026. (mail.python.org/pipermail/python-checkins/2018-June/155422.html)
02
S1 · JEUDI · Pratiquer
Compter avec un dictionnaire
Utiliser un dictionnaire comme compteur à étiquettes, et garder le meilleur score de chaque joueur.
⏱ 20 min de pratique · 5 min de quiz
[1]Scénario
Inès · Jeudi, 17 h 30
Inès a noté sur une feuille les parties jouées au club cette semaine : Pixel, Lynx, Pixel, Comete, Pixel, Lynx… Elle veut savoir qui a joué combien de fois, et garder pour chacun son meilleur score. Compter à la main, c'est long et elle se trompe. Ce soir, elle laisse un dictionnaire compter pour elle.
[2]Méthode
« Le compteur à étiquettes »
Rappel en une phrase : un dictionnaire range des valeurs sous des clés, et .get(clé, 0) lit une valeur sans erreur si la clé n'existe pas encore (voir épisode 1).
Crée un dictionnaire vide : compteur = {}.
Pour chaque élément, ajoute 1 à son compteur : compteur[x] = compteur.get(x, 0) + 1. La première fois, get donne 0, donc le compteur passe à 1.
Affiche le résultat avec .items() et une f-string.
Compter les lettres d'un mot
Code
mot = "attrape"
compteur = {}
for lettre in mot:
compteur[lettre] = compteur.get(lettre, 0) + 1
print(compteur)
for lettre, nombre in compteur.items():
print(f"{lettre} : {nombre}")
Affiche {'a': 2, 't': 2, 'r': 1, 'p': 1, 'e': 1}, puis une ligne par lettre.
Garder le meilleur score de chaque joueur : au lieu d'ajouter 1, on ne remplace la valeur que si le nouveau score est meilleur.
Code
def enregistrer(meilleurs, pseudo, score):
"""Garde le meilleur score de chaque pseudo."""
if pseudo not in meilleurs or score > meilleurs[pseudo]:
meilleurs[pseudo] = score
meilleurs = {}
enregistrer(meilleurs, "Pixel", 6)
enregistrer(meilleurs, "Lynx", 8)
enregistrer(meilleurs, "Pixel", 9)
enregistrer(meilleurs, "Lynx", 5)
print(meilleurs)
Affiche {'Pixel': 9, 'Lynx': 8} : le 9 de Pixel a remplacé son 6, mais le 5 de Lynx n'a pas remplacé son 8. or veut dire « ou » : on enregistre si le joueur est nouveau ou si son score est meilleur. La fonction modifie directement le dictionnaire qu'on lui donne : elle n'a pas besoin de return.
[3]Pourquoi ça marche
Le dictionnaire fait le travail de tri à ta place : chaque joueur a sa propre case, retrouvée par son pseudo, et personne ne peut se retrouver avec le score d'un autre. C'est exactement le problème des deux listes de mardi. La méthode get avec une valeur par défaut, décrite dans le tutoriel officiel, évite de devoir tester à chaque fois si la clé existe déjà [1].
À retenircompter = d[x] = d.get(x, 0) + 1. Garder le meilleur = remplacer seulement si c'est nouveau ou mieux.
[4]Entraînement
Bon réflexe ou piège ?
J'écris compteur[lettre] = compteur[lettre] + 1 dès la première lettre.
la première fois, la clé n'existe pas encore : KeyError. Utilise get(lettre, 0).
Je crée le dictionnaire vide avant la boucle.
dans la boucle, il serait remis à zéro à chaque tour.
J'utilise le pseudo comme clé.
un pseudo est unique, c'est une bonne étiquette.
J'écris le vrai prénom des joueurs dans mes données.
utilise des pseudos inventés, même pour un jeu de club.
Dans enregistrer, je remplace le score à chaque partie.
on garderait le dernier score, pas le meilleur.
[5]Quiz
1. Après le compteur de lettres sur le mot "attrape", que vaut compteur["a"] ?
il y a deux « a » dans « attrape » (sortie vérifiée).
compteur[x] provoquerait une KeyError pour une clé nouvelle.
3. On appelle enregistrer(meilleurs, "Lynx", 5) alors que meilleurs["Lynx"] vaut 8. Que se passe-t-il ?
Lynx existe déjà et 5 n'est pas plus grand que 8 : la condition est fausse.
[6]Kit
🎒 Ton kit — Épisode 2
20 min
Exercice : les statistiques du club
Compte les lettres de ton mot préféré avec la méthode du compteur.
Écris la liste des pseudos des parties de la semaine (au moins 8, pseudos inventés) et compte les parties de chaque joueur.
Utilise enregistrer pour garder le meilleur score de chacun, avec au moins 6 appels.
Affiche le tout avec des f-strings.
Code à copier : la fonction enregistrer ci-dessus.
Checklist
Mon compteur de lettres donne le bon résultat sur un mot vérifié à la main.
Je compte les parties de chaque joueur.
Mon dictionnaire meilleurs garde bien le meilleur score, pas le dernier.
[7]Journal
✍️ Journal de bord
Quelle autre chose pourrais-tu compter avec un dictionnaire (dans un jeu, dans ta classe, dans un livre) ? Explique ce qui serait la clé et ce qui serait la valeur.
Grouper des valeurs dans un tuple, et combiner listes et dictionnaires pour décrire des choses plus riches.
⏱ 20 min de lecture · 5 min de quiz
[1]Scénario
Inès · Mardi, 14 h
Inès dessine sur papier l'écran de son futur jeu : une lettre « A » en haut à gauche, une lettre « T » un peu plus loin, le robot en bas. Pour chaque lettre, il faut retenir deux nombres qui vont toujours ensemble : sa position de gauche à droite et sa position de haut en bas. Et pour chaque joueur, plusieurs informations : pseudo, score, niveau. Un seul dictionnaire ne suffit plus.
[2]Concept
Grouper et combiner
Le tuple : des valeurs qui vont ensemble. Un tuple groupe quelques valeurs, entre parenthèses, séparées par des virgules. On le lit comme une liste, par indice.
Code
position = (40, 100)
print(position[0])
x, y = position
print(x, y)
lettres = [("A", 40, 0), ("T", 90, 20)]
for caractere, x, y in lettres:
print(f"{caractere} en ({x}, {y})")
Affiche 40, puis 40 100, puis A en (40, 0) et T en (90, 20).
x, y = positiondéballe le tuple : chaque valeur part dans sa variable. Il faut autant de variables que de valeurs.
Une boucle peut déballer chaque tuple d'une liste : for caractere, x, y in lettres:.
Un tuple ne se modifie pas.
Code
position = (40, 100)
position[0] = 50
Python s'arrête avec : TypeError: 'tuple' object does not support item assignment. Pour changer de position, on crée un nouveau tuple : position = (50, 100).
Liste
Tuple
Écriture
[40, 100]
(40, 100)
Se modifie ?
oui (append, liste[0] = …)
non
Usage typique
plusieurs choses du même genre, qui changent (des mots, des scores)
quelques valeurs qui vont ensemble (une position, un résultat)
Combiner listes et dictionnaires. Les boîtes peuvent se ranger les unes dans les autres.
Affiche 9, puis Pixel (facile) : 9 et Lynx (moyen) : 7, puis pirate.
Une fiche : un dictionnaire qui décrit une chose (un joueur) avec plusieurs informations.
Une liste de fiches : tous les joueurs.
Un dictionnaire de listes : les mots rangés par niveau. mots["difficile"][0] se lit de gauche à droite : la liste du niveau difficile, puis son premier mot.
Attention aux guillemets : dans une f-string entre guillemets doubles, on écrit la clé entre guillemets simples (joueur['pseudo']).
Remets les lignes dans l'ordre · clique les lignes une par une
Ton programme
Lignes à placer
[3]Recherche
Ce que disent les sources
Tutoriel officiel de Python — Un tuple ne peut pas être modifié : affecter un de ses éléments provoque une erreur. On peut « emballer » des valeurs dans un tuple et les « déballer » dans des variables, à condition d'avoir autant de variables que de valeurs [1].
Tutoriel officiel de Python — Les tuples servent souvent à grouper des valeurs de natures différentes, lues par déballage ; les listes, à ranger des éléments du même genre, que l'on parcourt et que l'on modifie [1].
[4]Mythes
« Un tuple, c'est juste une liste avec des parenthèses. »
un tuple ne se modifie pas. C'est une protection : une position ou un résultat ne change pas par erreur.
« Il faut choisir entre listes et dictionnaires. »
on les combine : une liste de fiches, un dictionnaire de listes…
« Plus c'est imbriqué, mieux c'est. »
deux niveaux suffisent presque toujours. Au-delà, on ne s'y retrouve plus.
[5]Quiz
1. Qu'affiche ce programme ? p = (3, 7), puis a, b = p, puis print(b - a)
le déballage donne a = 3 et b = 7, donc 7 − 3 = 4 (sortie vérifiée).
2. Que se passe-t-il avec position = (40, 100) puis position[0] = 50 ?
pour changer de position, on crée un nouveau tuple.
3. mots = {"facile": ["chat", "lune"]}. Que vaut mots["facile"][1] ?
d'abord la liste du niveau facile, puis son élément d'indice 1.
[6]Kit
🎒 Ton kit — Épisode 3
15 min
Exercice : ranger trois sortes de données
Range les positions de 3 lettres dans une liste de tuples (caractère, x, y) et affiche-les avec une boucle qui déballe.
Crée une liste de 3 fiches de joueurs (pseudo, score, niveau) et affiche-la.
Crée un dictionnaire de listes : 2 niveaux, 3 mots chacun. Affiche le dernier mot de chaque niveau.
Checklist
Je sais créer et déballer un tuple.
Je sais pourquoi on ne peut pas modifier un tuple.
J'ai créé une liste de fiches et un dictionnaire de listes.
Vigilanceun tuple d'une seule valeur s'écrit avec une virgule : (5,). Sans virgule, (5) n'est qu'un nombre entre parenthèses. Tu en auras rarement besoin, mais c'est un piège classique.
[7]Journal
✍️ Journal de bord
Dessine (ou décris) les données de ton futur jeu : qu'est-ce qui serait un tuple, une fiche, une liste ?
Dessiner ses données avant de les coder, puis écrire les mots par niveau et les fiches des joueurs d'Attrape-lettres.
⏱ 25 min de pratique · 5 min de quiz
[1]Scénario
Inès · Jeudi, 12 h 40
Au club, Inès et Malik ne sont pas d'accord. Malik veut tout ranger dans une seule grande liste. Inès veut des dictionnaires partout. L'animatrice leur tend une feuille : « Avant de coder, dessinez vos données. Des boîtes, des étiquettes, des flèches. Le code viendra après. »
[2]Méthode
« Dessiner ses données avant de les coder »
Rappels : tuples, fiches et dictionnaires de listes (voir épisode 3) ; dictionnaires (voir épisode 1) ; tirage au hasard (voir Pro, épisode 8).
Liste ce que le jeu doit retenir : les mots, classés par niveau ; les joueurs, avec leur nombre de parties et leur meilleur score.
Pour chaque chose, choisis la boîte : plusieurs du même genre → liste ; une chose décrite par plusieurs informations → fiche (dictionnaire) ; un rangement par étiquette → dictionnaire.
Dessine : une boîte par conteneur, les étiquettes écrites sur les compartiments.
Code en suivant le dessin, puis affiche pour vérifier.
Les données qui ne changent pas pendant le jeu s'écrivent en majuscules (voir Pro, épisode 13).
Code
import random
MOTS_PAR_NIVEAU = {
"facile": ["chat", "lune", "robot"],
"moyen": ["pirate", "python", "fusee"],
"difficile": ["dinosaure", "astronaute", "labyrinthe"],
}
JOUEURS = [
{"pseudo": "Pixel", "parties": 5, "meilleur": 9},
{"pseudo": "Lynx", "parties": 8, "meilleur": 7},
{"pseudo": "Comete", "parties": 2, "meilleur": 4},
]
niveau = input("Niveau (facile, moyen, difficile) ? ").strip().lower()
if niveau in MOTS_PAR_NIVEAU:
mot = random.choice(MOTS_PAR_NIVEAU[niveau])
print(f"Mot tiré : {mot} ({len(mot)} lettres)")
else:
print("Ce niveau n'existe pas.")
print(f"{len(JOUEURS)} joueurs inscrits.")
Essai réel avec moyen (le mot change à chaque lancement) :
Ce que tu vois
Niveau (facile, moyen, difficile) ? moyen
Mot tiré : python (6 lettres)
3 joueurs inscrits.
Avec ␣␣Facile␣, le niveau est reconnu grâce à .strip().lower() ; avec expert, le programme répond Ce niveau n'existe pas. au lieu de s'arrêter sur une KeyError, grâce au test in.
[3]Pourquoi ça marche
Le dessin oblige à choisir chaque boîte avant d'écrire une ligne : on voit tout de suite qu'un joueur a plusieurs informations (une fiche) et qu'il y a plusieurs joueurs (une liste de fiches). Les erreurs de structure se corrigent sur papier, gratuitement. Le test in avant de lire une clé évite l'arrêt du programme quand le joueur tape un niveau qui n'existe pas.
À retenird'abord le dessin, ensuite le code. Et on vérifie qu'une clé existe avant de la lire.
[4]Entraînement
Bon réflexe ou piège ?
Je range les mots de tous les niveaux dans une seule liste.
impossible ensuite de tirer un mot « facile ».
J'écris MOTS_PAR_NIVEAU en majuscules parce qu'il ne change pas pendant le jeu.
c'est la convention vue au Pro.
Je lis MOTS_PAR_NIVEAU[niveau] sans vérifier ce que le joueur a tapé.
un niveau inconnu provoque une KeyError.
J'écris les mots sans accent ni majuscule.
le joueur n'aura pas à taper « É ».
Je dessine mes données avant de coder.
c'est là qu'on voit les erreurs de structure.
[5]Quiz
1. Pour ranger les mots par niveau, quelle structure ?
on retrouve la liste de chaque niveau par son nom.
2. Que se passe-t-il si le joueur tape expert ?
le test niveau in MOTS_PAR_NIVEAU est faux, c'est le else qui s'exécute (testé).
3. Comment lire le meilleur score du deuxième joueur ?
d'abord la fiche d'indice 1 (le deuxième), puis sa clé "meilleur".
[6]Kit
🎒 Ton kit — Épisode 4
25 min
Exercice : les données d'Attrape-lettres
Sur une feuille, dessine les données de ton jeu : mots par niveau, fiches des joueurs.
Écris MOTS_PAR_NIVEAU avec au moins 3 niveaux et 4 mots par niveau (sans accent).
Écris JOUEURS avec au moins 3 fiches (pseudos inventés).
Demande un niveau, tire un mot, affiche sa longueur ; teste avec un niveau existant, un niveau en majuscules et un niveau inconnu.
Code à copier : le programme ci-dessus.
Checklist
J'ai dessiné mes données avant de les coder.
Mon programme tire un mot du bon niveau.
Un niveau inconnu ne fait pas planter le programme.
[7]Journal
✍️ Journal de bord
Compare ton dessin et ton code : as-tu dû changer quelque chose en codant ? Qu'est-ce que le dessin t'a évité ?
Écrire les recherches de base : trouver un élément, trouver le plus grand, compter ce qui vérifie une condition.
⏱ 20 min de lecture · 5 min de quiz
[1]Scénario
Inès · Mardi, 17 h
Le club a joué toute la semaine : il y a maintenant des dizaines de parties. « Qui a le meilleur score ? » demande Malik. Sur trois joueurs, Inès le voit d'un coup d'œil. Sur deux cents parties, impossible. L'ordinateur, lui, ne « voit » rien d'un coup : il doit regarder les données une par une. Il faut lui dire comment.
[2]Concept
Trois recherches à connaître par cœur
Chercher dans des données, c'est toujours la même idée : parcourir (avec for, voir Pro, épisode 1) et comparer. Trois recherches reviennent sans arrêt.
1. Chercher un élément : on s'arrête dès qu'on l'a trouvé.
Code
def chercher_joueur(fiches, pseudo):
"""Renvoie la fiche du pseudo, ou None s'il n'existe pas."""
for fiche in fiches:
if fiche["pseudo"] == pseudo:
return fiche
return None
return sort de la fonction dès que la fiche est trouvée (voir Pro, épisode 11). Si la boucle va jusqu'au bout sans rien trouver, la fonction renvoie None.
2. Chercher le plus grand : on garde le meilleur vu jusqu'ici.
Code
def meilleur_score(fiches):
"""Renvoie le plus grand score de la liste, ou None si elle est vide."""
if len(fiches) == 0:
return None
meilleur = fiches[0]["meilleur"]
for fiche in fiches:
if fiche["meilleur"] > meilleur:
meilleur = fiche["meilleur"]
return meilleur
On part du premier score, puis on le remplace à chaque fois qu'on rencontre plus grand. Une liste vide n'a pas de plus grand élément : on le prévoit avant la boucle.
3. Compter : on ajoute 1 à chaque élément qui vérifie la condition.
Code
def compter_actifs(fiches, minimum):
"""Compte les joueurs qui ont joué au moins `minimum` parties."""
nombre = 0
for fiche in fiches:
if fiche["parties"] >= minimum:
nombre = nombre + 1
return nombre
Avec les trois joueurs de l'épisode 4 : chercher_joueur(JOUEURS, "Lynx") renvoie la fiche de Lynx, chercher_joueur(JOUEURS, "Nova") renvoie None, meilleur_score(JOUEURS) renvoie 9, meilleur_score([]) renvoie None et compter_actifs(JOUEURS, 5) renvoie 2 (sorties vérifiées).
Les raccourcis de Python. Pour une simple liste de nombres, Python a déjà ces outils : max, min et sum.
Affiche 9 4 20. Mais max([]) sur une liste vide s'arrête avec ValueError: max() iterable argument is empty. Savoir écrire la recherche toi-même te permet de chercher dans des fiches, de choisir ce qu'on renvoie quand c'est vide, et de comprendre ce que fait max.
Suivre les variables · chercher le meilleur score
Ce qui s'affiche
[3]Recherche
Ce que disent les sources
Documentation officielle de Python — max renvoie le plus grand élément d'un itérable et min le plus petit ; sur un itérable vide, ils provoquent une ValueError (sauf si l'on donne une valeur par défaut). En cas d'égalité, c'est le premier élément rencontré qui est renvoyé [1].
Programme du cycle 4 (BO du 5 mars 2026) — La pensée informatique s'appuie sur l'algorithmique : décrire une suite d'étapes précises pour résoudre un problème [2]. Une recherche est un algorithme : parcourir, comparer, garder.
[4]Mythes
« L'ordinateur voit toutes les données d'un coup et trouve instantanément. »
il les regarde une par une. Il va simplement très vite.
« Pour chercher dans des données, il faut d'abord les trier. »
chercher le plus grand ou un pseudo se fait en un seul parcours, sans trier.
« max marche toujours. »
sur une liste vide, il s'arrête avec une erreur. C'est à toi de prévoir ce cas.
[5]Quiz
1. Dans chercher_joueur, que se passe-t-il quand la fiche est trouvée au 2e tour ?
return arrête la fonction ; les fiches suivantes ne sont pas regardées.
2. Dans le widget, pourquoi meilleur ne change-t-il pas au 4e tour, quand score vaut 9 ?
la condition est score > meilleur, et 9 > 9 est faux.
3. Que renvoie meilleur_score([]) ?
la fonction teste la liste vide avant la boucle et renvoie None (sortie vérifiée).
[6]Kit
🎒 Ton kit — Épisode 5
15 min
Exercice : tes trois recherches. Recopie les trois fonctions, puis teste-les sur la liste JOUEURS de l'épisode 4.
Code à copier : les fonctions chercher_joueur, meilleur_score et compter_actifs ci-dessus.
Cherche un pseudo qui existe, puis un pseudo qui n'existe pas.
Trouve le meilleur score, puis teste avec une liste vide.
Compte les joueurs qui ont joué au moins 3 parties.
Bonus : écris plus_petit_score(fiches) sur le même modèle que meilleur_score.
Checklist
Je sais écrire une recherche qui s'arrête dès qu'elle trouve.
Je sais garder le meilleur vu jusqu'ici, et prévoir la liste vide.
J'ai testé mes fonctions avec une liste vide.
Vigilancequand une fonction peut renvoyer None, le programme qui l'appelle doit le prévoir. chercher_joueur(JOUEURS, "Nova")["meilleur"] s'arrêterait avec une erreur.
[7]Journal
✍️ Journal de bord
Explique avec tes mots la recherche du plus grand, comme si tu décrivais comment trouver le plus grand élève d'une file sans tous les mesurer en même temps.
Appliquer les recherches aux données du jeu, en se posant toujours les trois mêmes questions.
⏱ 25 min de pratique · 5 min de quiz
[1]Scénario
Inès · Jeudi, 12 h 40
L'animatrice veut afficher les records du club sur le mur : le mot le plus long du jeu, le joueur le plus assidu, le nombre de parties gagnées. Malik se propose d'écrire les trois fonctions en dix minutes. Au premier test avec une liste vide, sa fonction plante. Inès sourit : « Tu as oublié la troisième question. »
[2]Méthode
« Une recherche, trois questions »
Rappel en une phrase : chercher, c'est parcourir et comparer ; on trouve un élément, le plus grand, ou on compte (voir épisode 5).
Avant d'écrire une recherche, réponds à trois questions :
Que cherche-t-on ? (un élément, le plus grand, un nombre)
Que garde-t-on en mémoire pendant le parcours ? (le meilleur vu jusqu'ici, un compteur)
Que renvoie-t-on si la liste est vide ou si rien n'est trouvé ? (None, 0…)
Code
def mot_plus_long(mots):
"""Renvoie le mot le plus long (le premier en cas d'égalité), ou None."""
if len(mots) == 0:
return None
plus_long = mots[0]
for mot in mots:
if len(mot) > len(plus_long):
plus_long = mot
return plus_long
def plus_actif(fiches):
"""Renvoie le pseudo qui a joué le plus de parties, ou None."""
if len(fiches) == 0:
return None
meilleure = fiches[0]
for fiche in fiches:
if fiche["parties"] > meilleure["parties"]:
meilleure = fiche
return meilleure["pseudo"]
def compter_gagnees(resultats):
"""Compte les parties gagnées dans une liste de résultats."""
nombre = 0
for resultat in resultats:
if resultat == "gagné":
nombre = nombre + 1
return nombre
Tests réels :
mot_plus_long(["chat", "pirate", "python", "lune"]) → pirate (à égalité avec « python », le premier rencontré est gardé, car on compare avec >).
mot_plus_long([]) → None.
plus_actif(...) avec Pixel (5 parties) et Lynx (8 parties) → Lynx ; avec une liste vide → None.
compter_gagnees(["gagné", "perdu", "gagné", "gagné"]) → 3 ; avec une liste vide → 0.
Dans plus_actif, on garde la fiche entière en mémoire, pour pouvoir renvoyer son pseudo à la fin.
[3]Pourquoi ça marche
La troisième question vise le cas qu'on oublie toujours : la liste vide, ou l'élément introuvable. C'est le premier cas de ton plan de test (voir Pro, épisode 19). Et le choix entre > et >= décide de qui gagne en cas d'égalité : avec >, le premier rencontré reste ; avec >=, ce serait le dernier. La documentation de max fait le même choix : en cas d'égalité, le premier rencontré [1].
À retenirtrois questions avant de coder : quoi chercher, quoi garder, quoi renvoyer si c'est vide.
[4]Entraînement
Bon réflexe ou piège ?
Je teste ma recherche avec une liste vide.
c'est le cas qui plante le plus souvent.
Je commence plus_long à "" au lieu du premier mot, sans le dire dans la docstring.
avec une liste vide, la fonction renverrait "" sans prévenir. Quel que soit ton choix, écris-le dans la docstring.
J'écris return nombre dans la boucle de compter_gagnees.
la fonction s'arrêterait au premier tour.
Je garde la fiche entière plutôt que seulement le nombre de parties.
à la fin, j'ai besoin du pseudo.
Je mets une docstring qui dit ce qui est renvoyé quand c'est vide.
celui qui utilise la fonction le saura.
[5]Quiz
1. Que renvoie mot_plus_long(["chat", "pirate", "python"]) ?
« pirate » et « python » ont 6 lettres ; avec >, le premier rencontré est gardé (sortie vérifiée).
2. Que renvoie compter_gagnees([]) ?
le compteur commence à 0 et la boucle ne tourne jamais.
3. Pourquoi plus_actif garde-t-il toute la fiche, et pas seulement le nombre de parties ?
le nombre de parties seul ne dit pas à qui il appartient.
[6]Kit
🎒 Ton kit — Épisode 6
25 min
Exercice : le mur des records
Pour chaque fonction, écris d'abord sur papier tes réponses aux trois questions.
Écris les trois fonctions et teste-les sur tes données de l'épisode 4.
Teste chacune avec une liste vide.
Affiche « le mur des records » : trois lignes en f-string.
Code à copier : les trois fonctions ci-dessus.
Checklist
J'ai répondu aux trois questions avant de coder chaque fonction.
Chaque fonction a été testée avec une liste vide.
Mon mur des records s'affiche.
[7]Journal
✍️ Journal de bord
Dans une égalité (deux joueurs avec le même score), qui devrait gagner selon toi ? Le premier arrivé, le dernier, ou les deux ? Comment le coder ?
Comprendre comment fonctionne un tri en le faisant à la main, puis trier avec sorted.
⏱ 25 min de lecture · 5 min de quiz
[1]Scénario
Inès · Mardi, 14 h
Pour le tableau des meilleurs scores, il faut que le premier soit en haut. Inès prend six cartes à jouer et les étale sur sa table dans le désordre : 7, 3, 9, 1, 6, 4. « Comment je fais, moi, pour les ranger ? » Elle cherche la plus petite, la met à gauche, puis recommence avec celles qui restent. Sans le savoir, elle vient d'exécuter un algorithme célèbre.
[2]Concept
Trier
Le tri par sélection, à la main. Pour ranger du plus petit au plus grand :
cherche le plus petit élément de la partie pas encore rangée ;
échange-le avec le premier élément de cette partie ;
la partie rangée a grandi d'une case : recommence sur le reste.
Avec 7, 3, 9, 1, 6, 4 (étapes réelles) :
Étape
Liste après l'étape
1
1, 3, 9, 7, 6, 4 (le 1 échangé avec le 7)
2
1, 3, 9, 7, 6, 4 (le 3 est déjà à sa place)
3
1, 3, 4, 7, 6, 9 (le 4 échangé avec le 9)
4
1, 3, 4, 6, 7, 9 (le 6 échangé avec le 7)
5 et 6
1, 3, 4, 6, 7, 9 (plus rien à échanger)
En Python, c'est une recherche du plus petit (voir épisode 5) répétée :
Code
def tri_selection(liste):
"""Renvoie une copie de la liste, triée du plus petit au plus grand."""
nombres = list(liste)
for debut in range(len(nombres)):
position_min = debut
for i in range(debut + 1, len(nombres)):
if nombres[i] < nombres[position_min]:
position_min = i
nombres[debut], nombres[position_min] = nombres[position_min], nombres[debut]
return nombres
scores = [7, 3, 9, 1, 6, 4]
print(tri_selection(scores))
print(scores)
Affiche [1, 3, 4, 6, 7, 9], puis [7, 3, 9, 1, 6, 4] : la liste d'origine n'a pas bougé, car on a travaillé sur une copie (list(liste)). La ligne de l'échange utilise le déballage de tuples (voir épisode 3) : les deux valeurs sont lues, puis rangées à la place l'une de l'autre.
Trier avec Python. Dans tes programmes, tu utiliseras l'outil tout prêt :
Affiche None, puis [3, 7, 9]. sorted(liste)renvoie une nouvelle liste et ne touche pas l'originale ; liste.sort()modifie la liste et ne renvoie rien. Écrire resultat = scores.sort() est donc un piège.
Trier des tuples. Python compare deux tuples élément par élément : d'abord le premier, et seulement en cas d'égalité, le suivant.
Affiche [(9, 'Pixel'), (9, 'Nova'), (7, 'Lynx'), (4, 'Comete')]. Les scores sont bien classés. Pour les deux 9, Python compare les pseudos, et comme on trie à l'envers, « Pixel » passe avant « Nova » (P vient après N dans l'alphabet). Mettre le score en premier dans le tuple, c'est ce qui fait trier par score.
Simulateur de tri · le tri par sélection, étape par étape
[3]Recherche
Ce que disent les sources
Guide officiel du tri en Python — sorted() renvoie une nouvelle liste triée ; list.sort() modifie la liste et renvoie None. Le paramètre reverse trie dans l'ordre décroissant. Le tri de Python est stable : des éléments considérés comme égaux gardent leur ordre de départ [1].
Tutoriel officiel de Python — Deux séquences (comme deux tuples) se comparent élément par élément : la première paire d'éléments différents décide du résultat [2].
Au lycée — Le tri par sélection fait partie des algorithmes étudiés en spécialité NSI, avec une étude de son coût : pour n éléments, il fait de l'ordre de n² comparaisons [3].
[4]Mythes
« Trier, c'est facile pour l'ordinateur : il voit tout de suite l'ordre. »
il compare deux éléments à la fois, beaucoup de fois. Le tri par sélection fait 15 comparaisons pour 6 cartes.
« sorted(scores) range ma liste. »
il en renvoie une nouvelle, rangée ; scores ne change pas.
« Pour trier par score, il faut un outil spécial. »
il suffit de mettre le score en premier dans chaque tuple.
[5]Quiz
1. Que renvoie sorted([(5, "b"), (5, "a"), (2, "z")]) ?
d'abord par le premier élément ; pour les deux 5, par le deuxième : « a » avant « b » (sortie vérifiée).
2. Après scores = [7, 3, 9] et x = scores.sort(), que vaut x ?
.sort() modifie scores et ne renvoie rien.
3. Dans le tri par sélection, que fait-on à chaque étape ?
c'est une recherche du plus petit, répétée sur une partie de plus en plus courte.
[6]Kit
🎒 Ton kit — Épisode 7
20 min
Exercice : trier à la main, puis avec Python
Prends 6 cartes (ou écris 6 nombres sur des papiers) et trie-les par sélection, en notant la liste après chaque étape.
Lance tri_selection sur les mêmes nombres et compare avec tes notes.
Trie une liste de 4 tuples (score, pseudo) du meilleur au moins bon avec sorted(..., reverse=True).
Code à copier : la fonction tri_selection ci-dessus.
Checklist
Je sais expliquer le tri par sélection avec des cartes.
Je connais la différence entre sorted(liste) et liste.sort().
J'ai trié une liste de tuples par score.
Vigilancen'écris jamais liste = liste.sort() : ta liste deviendrait None, et la ligne suivante qui l'utilise s'arrêterait avec une erreur.
[7]Journal
✍️ Journal de bord
Comment ranges-tu tes cartes, tes livres ou tes affaires « à la main » ? Ta méthode ressemble-t-elle au tri par sélection, ou à une autre ?
Ton outil de synthèse, le récapitulatif de l'arc et ton badge.
⏱ 25 min · arbre de décision · carrousel · quiz final
[1]Scénario
Inès · Jeudi, 12 h 40
Première séance de test au club : chacun joue plusieurs parties du mot mystère, et Inès note les scores. Il y a un mois, elle aurait eu deux listes qui se mélangeaient. Aujourd'hui, ses données sont dessinées, rangées dans des dictionnaires et des tuples, et elle sait chercher et trier. À la fin de la séance, le tableau des meilleurs scores s'affiche, classé. Malik est deuxième… à égalité.
[2]Outil
« Liste, dictionnaire ou tuple ? »
Aide à la décision interactive
[3]Carrousel
🎨 Carrousel récapitulatif — Arc 1
MASTER · ARC 1 · 1/5
Des données plus riches
Quatre semaines pour bien ranger, retrouver et classer les données de ton jeu.
2/5
Les dictionnaires
{"Pixel": 9}
lire avec une clé
une clé est unique
in, .get(clé, défaut), .items()
3/5
Tuples et fiches
(40, 100) ne se modifie pas
x, y = position
une fiche = un dictionnaire
une liste de fiches
4/5
Chercher
parcourir et comparer
s'arrêter dès qu'on trouve
garder le meilleur
compter
prévoir la liste vide
5/5
Trier
le tri par sélection à la main
sorted renvoie une nouvelle liste
reverse=True
le premier élément du tuple décide. Arc suivant : des objets dans le jeu.
[4]Quiz final
1. Après t = {"x": 1}, puis t["x"] = t.get("x", 0) + 1 et t["y"] = t.get("y", 0) + 1, que vaut t ?
« x » existait (1 + 1 = 2) ; « y » n'existait pas (0 + 1 = 1) (sortie vérifiée).
2. Pour ranger la position d'une lettre (x et y), quelle structure ?
deux valeurs qui vont ensemble : c'est le rôle du tuple.
3. Quelle fonction renvoie le meilleur score d'une liste vide sans planter ?
max([]) provoque une ValueError, et sorted([])[0] une IndexError.
4. Pour classer des joueurs du meilleur au moins bon, on trie des tuples…
le premier élément décide, et reverse=True met le plus grand en premier.
5. Que vaut une liste après liste = liste.sort() ?
.sort() renvoie None : c'est ce qui est rangé dans liste.
[5]Kit
🎒 Ton kit de fin d'arc
20 min
Le tableau des meilleurs scores
Synthèse : un dictionnaire pseudo → meilleur score (épisode 2), transformé en liste de tuples (score, pseudo), triée (épisode 7), affichée avec le rang.
Code
def enregistrer(meilleurs, pseudo, score):
"""Garde le meilleur score de chaque pseudo."""
if pseudo not in meilleurs or score > meilleurs[pseudo]:
meilleurs[pseudo] = score
def classement(meilleurs):
"""Renvoie la liste des (score, pseudo), du meilleur au moins bon."""
paires = []
for pseudo, score in meilleurs.items():
paires.append((score, pseudo))
return sorted(paires, reverse=True)
def afficher_tableau(meilleurs):
"""Affiche le tableau des meilleurs scores, avec le rang."""
print("=== Meilleurs scores ===")
rang = 1
for score, pseudo in classement(meilleurs):
print(f"{rang}. {pseudo} — {score} points")
rang = rang + 1
meilleurs = {}
enregistrer(meilleurs, "Pixel", 6)
enregistrer(meilleurs, "Lynx", 8)
enregistrer(meilleurs, "Comete", 4)
enregistrer(meilleurs, "Pixel", 9)
enregistrer(meilleurs, "Nova", 8)
afficher_tableau(meilleurs)
Nova et Lynx ont 8 points : comme on trie les tuples à l'envers, Nova passe avant Lynx (N vient après L). C'est un choix du programme, pas une règle du jeu : à toi de décider s'il te convient (voir ton journal de l'épisode 6). Les scores restent en mémoire pendant que le programme tourne : quand on le ferme, ils disparaissent. Pour ton stand, ce sera le tableau de la séance.
Consigne : utilise ce tableau avec tes propres données, puis branche-le sur ton mot mystère du Pro (voir Pro, épisode 20) : à la fin de chaque partie, demande un pseudo et enregistre le score (par exemple, le nombre d'erreurs restantes). Exporte ensuite ton carnet de bord.
Checklist
J'ai exporté mon carnet (bouton dans le menu).
Je sais expliquer quand choisir une liste, un dictionnaire ou un tuple.
Mon tableau des meilleurs scores s'affiche, classé.
[6]Journal
✍️ Journal de bord — bilan
En un mois, quelle notion de cet arc t'a le plus servi pour ton jeu ? Et laquelle te paraît encore floue ?
✦ GARDIENNE · GARDIEN DES DONNÉES · ARC 1 ✦
Bravo ! Tu as terminé l'arc 1. Tu sais ranger des données dans des dictionnaires et des tuples, y chercher ce que tu veux et les classer.
ARC 2 · SEMAINES 5 À 8
Des objets dans le jeu
Le robot et les lettres deviennent des objets qui savent se déplacer, puis ils prennent vie à l'écran. En quatre semaines, tu obtiens une première version jouable d'Attrape-lettres.
Semaine 5 · Les classes
09
S5 · MARDI · Comprendre
Un plan pour fabriquer des objets
Définir une classe, fabriquer des objets avec __init__, et donner à chacun ses propres attributs.
⏱ 25 min de lecture · 5 min de quiz
[1]Scénario
Inès · Mardi, 12 h 40
Dans Attrape-lettres, il y aura un robot et une dizaine de lettres qui tombent. Chaque lettre a son caractère, sa position et sa vitesse. Inès commence une liste de fiches, comme à l'arc 1, puis s'arrête : chaque lettre devra aussi savoir tomber, repartir en haut, se dessiner… Malik se souvient de Scratch : « Un lutin, et plein de clones. Chaque clone a sa propre position. » L'animatrice approuve : « En Python, le lutin modèle s'appelle une classe. »
[2]Concept
La classe et ses objets
Une classe est un plan : elle décrit ce qu'aura chaque objet fabriqué à partir d'elle. Un objet est un exemplaire fabriqué d'après ce plan. Comme les clones d'un lutin dans Scratch : même modèle, mais chacun sa position.
class Robot: commence la définition de la classe. Le nom d'une classe s'écrit avec une majuscule à chaque mot (Robot, JeuDeLettres), contrairement aux fonctions et aux variables (voir Pro, épisode 13).
__init__ (deux tirets bas de chaque côté) est une fonction spéciale de la classe : Python l'appelle automatiquement à chaque fois qu'on fabrique un objet. C'est là qu'on donne à l'objet ses valeurs de départ.
self désigne l'objet en train d'être fabriqué. self.x = x veut dire : « range la valeur reçue dans l'attribut x de cet objet ».
Robot(40) fabrique un objet : Python appelle __init__ avec x = 40. Les parenthèses fonctionnent comme un appel de fonction (voir Pro, épisode 11).
robot1.x se lit « l'attribut x de robot1 ». Chaque objet a ses propres attributs : modifier robot1.x ne change pas robot2.x.
Dans Scratch
En Python
le lutin modèle
la classe Robot
un clone
un objet : Robot(40)
« quand je commence comme un clone »
__init__
une variable « pour ce lutin uniquement »
un attribut : self.x
Le piège du self oublié.
Code
class Robot:
def __init__(self, x):
x = x
self.vies = 3
robot = Robot(40)
print(robot.x)
Python s'arrête avec : AttributeError: 'Robot' object has no attribute 'x'. La ligne x = x range la valeur dans une variable locale de __init__ (voir Pro, épisode 11), qui disparaît à la fin de l'appel : l'objet, lui, n'a jamais reçu d'attribut x. Attribute = attribut.
Suivre les variables · deux objets, chacun ses attributs
Ce qui s'affiche
[3]Recherche
Ce que disent les sources
Tutoriel officiel de Python — Quand une classe définit une méthode __init__, la création d'un objet appelle automatiquement __init__ pour ce nouvel objet. Les attributs d'un objet lui sont propres et existent dès leur première affectation [1].
Tutoriel officiel de Python — Le premier paramètre s'appelle souvent self : ce n'est qu'une convention, mais s'en écarter rend le code moins lisible pour les autres programmeurs [1].
PEP 8 — Les noms de classes s'écrivent en « CapWords » (une majuscule au début de chaque mot) [2].
Équipe Scratch — Un clone commence avec les mêmes costumes, sons, scripts et variables que l'original, mais il est ensuite indépendant [3].
[4]Mythes
« Une classe, c'est un objet. »
la classe est le plan ; les objets sont fabriqués d'après elle. Un plan, beaucoup d'objets.
« Tous les objets d'une classe partagent les mêmes valeurs. »
chaque objet a ses propres attributs ; changer robot1.x ne touche pas robot2.x.
« __init__, il faut l'appeler soi-même. »
Python l'appelle automatiquement quand on écrit Robot(40).
[5]Quiz
1. Qu'affiche ce programme ? Une classe Boite dont __init__ fait self.n = n, puis b1 = Boite(2), b2 = Boite(5), b1.n = b2.n + 1 et print(b1.n, b2.n).
b1.n reçoit 5 + 1 = 6 ; b2.n ne change pas (sortie vérifiée).
2. Quand Python exécute-t-il __init__ ?
__init__ prépare chaque nouvel objet, automatiquement.
3. Dans __init__, que désigne self ?
self.x = x range la valeur dans l'attribut de cet objet-là.
[6]Kit
🎒 Ton kit — Épisode 9
15 min
Exercice : prédire deux lettres. Écris sur papier ce que ce programme affiche, puis lance-le.
Code à copier
class Lettre:
def __init__(self, caractere, x):
self.caractere = caractere
self.x = x
self.y = 0
a = Lettre("A", 20)
b = Lettre("B", 60)
a.y = a.y + 10
b.x = a.x
print(a.caractere, a.x, a.y)
print(b.caractere, b.x, b.y)
Corrigé (sortie réelle) : A 20 10, puis B 20 0. b.x = a.x copie la valeur de a.x dans b.x ; ensuite, les deux attributs restent indépendants.
Puis écris ta propre classe Robot, fabrique deux robots, modifie l'un et vérifie que l'autre ne change pas.
Checklist
Je sais écrire une classe avec __init__ et des attributs self.….
Je sais fabriquer un objet et lire ses attributs.
J'ai vérifié que deux objets ont des attributs indépendants.
Vigilancedans __init__, chaque attribut s'écrit self.nom = valeur. Sans self., la valeur est perdue à la fin de __init__ (l'AttributeError du concept).
[7]Journal
✍️ Journal de bord
Choisis un jeu que tu connais. Quelles « classes » y vois-tu (des choses qui existent en plusieurs exemplaires) ? Quels seraient leurs attributs ?
[8]Sources
Python Software Foundation, Tutoriel Python — 9. Classes, 9.3 « Une première approche des classes », consulté le 29/10/2026.
Transformer les fiches de l'arc 1 en classes, puis fabriquer une liste d'objets au hasard.
⏱ 25 min de pratique · 5 min de quiz
[1]Scénario
Inès · Jeudi, 17 h 30
Inès ressort le dessin de ses données (épisode 4). Chaque fiche de joueur avait des étiquettes : pseudo, parties, meilleur. Ce soir, elle refait le même dessin pour le robot et pour une lettre qui tombe. Elle remarque que les étiquettes de ses fiches ressemblent beaucoup aux attributs d'une classe.
[2]Méthode
« De la fiche à la classe »
Rappel en une phrase : une classe est un plan, __init__ donne à chaque objet ses attributs self.… (voir épisode 9).
Écris la fiche de l'objet, comme à l'arc 1 : quelles étiquettes ?
Chaque étiquette devient un attribut dans __init__. Ce qui change d'un objet à l'autre devient un paramètre ; ce qui est pareil pour tous au départ reçoit une valeur fixe.
Fabrique les objets et range-les, si besoin, dans une liste.
Affiche leurs attributs pour vérifier.
Fiche (arc 1)
Classe (arc 2)
{"x": 72, "vies": 3, "score": 0}
Robot(72) avec self.x, self.vies, self.score
fiche["vies"]
robot.vies
une liste de fiches
une liste d'objets
Code
import random
LARGEUR = 160
ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
class Robot:
def __init__(self, x):
self.x = x
self.y = 108
self.largeur = 16
self.hauteur = 8
self.vies = 3
self.score = 0
class Lettre:
def __init__(self, caractere, x, y, vitesse):
self.caractere = caractere
self.x = x
self.y = y
self.vitesse = vitesse
robot = Robot(72)
lettres = []
for i in range(5):
caractere = random.choice(ALPHABET)
x = random.randint(0, LARGEUR - 4)
lettres.append(Lettre(caractere, x, 0, random.randint(1, 3)))
print(f"Robot en x = {robot.x}, {robot.vies} vies")
for lettre in lettres:
print(f"{lettre.caractere} en ({lettre.x}, {lettre.y}), vitesse {lettre.vitesse}")
Essai réel (les lettres changent à chaque lancement) :
Ce que tu vois
Robot en x = 72, 3 vies
K en (38, 0), vitesse 2
U en (12, 0), vitesse 1
R en (24, 0), vitesse 2
S en (14, 0), vitesse 3
G en (9, 0), vitesse 1
Le robot a 6 attributs mais un seul paramètre, x : ses vies, son score et sa taille sont les mêmes au départ pour tous les robots. random.choice marche aussi sur une chaîne : il tire un de ses caractères (voir Pro, épisode 8).
[3]Pourquoi ça marche
Une fiche et un objet décrivent la même chose : un ensemble d'informations sur une seule chose. Mais l'objet pourra aussi, dès la semaine prochaine, faire des choses (se déplacer, tomber), ce qu'une fiche ne sait pas. Le tutoriel officiel le dit : les attributs d'un objet lui sont propres et existent dès qu'on leur donne une valeur [1]. Partir de ta fiche évite d'oublier un attribut.
À retenirune étiquette de fiche = un attribut. Ce qui change d'un objet à l'autre = un paramètre de __init__.
[4]Entraînement
Bon réflexe ou piège ?
Je mets vies en paramètre alors que tous les robots commencent avec 3 vies.
ce n'est pas faux, mais il faudra écrire Robot(72, 3) partout. Une valeur fixe dans __init__ suffit.
Je fabrique les lettres dans une boucle et je les range dans une liste.
on pourra les faire toutes tomber avec une seule boucle.
J'écris robot["vies"] comme pour une fiche.
un objet se lit avec un point : robot.vies.
J'appelle ma classe lettre en minuscules.
une classe prend une majuscule (Lettre), ce qui la distingue d'une variable comme lettre.
J'affiche les attributs de mes objets pour vérifier.
c'est le « tester seul » du Pro, appliqué aux objets.
[5]Quiz
1. Pour lire les vies d'un objet robot, on écrit…
un attribut se lit avec un point.
2. Combien de paramètres faut-il donner pour fabriquer Robot(…) dans le code ci-dessus ?
seul x est un paramètre de __init__ (sans compter self, que Python donne tout seul).
3. Que contient lettres après la boucle ?
chaque tour fabrique un objet et l'ajoute avec append.
[6]Kit
🎒 Ton kit — Épisode 10
20 min
Exercice : tes deux classes
Écris la fiche du robot et la fiche d'une lettre, sur papier.
Écris les classes Robot et Lettre.
Fabrique un robot et une liste de 5 lettres au hasard.
Affiche tous les attributs avec des f-strings.
Code à copier : le programme ci-dessus.
Checklist
Mes deux classes ont un nom avec une majuscule et un __init__.
Ma liste contient 5 objets Lettre.
J'ai affiché leurs attributs pour vérifier.
[7]Journal
✍️ Journal de bord
Quels attributs as-tu mis en paramètre, et lesquels as-tu fixés dans __init__ ? Pourquoi ce choix ?
Donner des méthodes à une classe, pour que chaque objet sache agir sur ses propres attributs.
⏱ 25 min de lecture · 5 min de quiz
[1]Scénario
Inès · Mardi, 14 h
Pour déplacer le robot, Inès a écrit une fonction deplacer_robot(robot, dx) ; pour faire tomber une lettre, faire_tomber(lettre). Le programme marche, mais les fonctions sont éparpillées loin des classes, et Malik a appelé faire_tomber(robot) par erreur. « Et si chaque objet savait lui-même ce qu'il peut faire ? »
[2]Concept
Les méthodes
Une méthode est une fonction rangée dans la classe. Elle travaille sur l'objet qui l'exécute, grâce à self.
Code
LARGEUR = 160
HAUTEUR = 120
class Robot:
def __init__(self, x):
self.x = x
self.largeur = 16
def deplacer(self, dx):
"""Déplace le robot de dx pixels, sans sortir de l'écran."""
self.x = self.x + dx
if self.x < 0:
self.x = 0
if self.x > LARGEUR - self.largeur:
self.x = LARGEUR - self.largeur
class Lettre:
def __init__(self, caractere, x, vitesse):
self.caractere = caractere
self.x = x
self.y = 0
self.vitesse = vitesse
def tomber(self):
"""Fait descendre la lettre de sa vitesse."""
self.y = self.y + self.vitesse
def est_tombee(self):
"""Renvoie True si la lettre est sortie par le bas de l'écran."""
return self.y > HAUTEUR
robot = Robot(140)
robot.deplacer(10)
print(robot.x)
robot.deplacer(-50)
print(robot.x)
lettre = Lettre("A", 30, 50)
lettre.tomber()
lettre.tomber()
print(lettre.y, lettre.est_tombee())
lettre.tomber()
print(lettre.y, lettre.est_tombee())
Affiche 144, puis 94, puis 100 False, puis 150 True.
Une méthode se définit avec def, décalée dans la classe, et son premier paramètre est self.
On l'appelle avec un point : robot.deplacer(10). Python donne tout seul l'objet robot comme self ; on ne fournit que les autres paramètres (dx = 10).
Une méthode peut modifier l'objet (deplacer, tomber) ou renvoyer une valeur (est_tombee), comme une fonction (voir Pro, épisode 11).
Dans deplacer, le robot part de 140 et avance de 10 : il serait à 150, mais l'écran fait 160 pixels et le robot 16 de large, donc il s'arrête à 144. C'est l'objet qui veille lui-même à ne pas sortir de l'écran.
Fonction séparée
Méthode
deplacer_robot(robot, 10)
robot.deplacer(10)
on peut lui donner le mauvais objet
elle appartient à la classe Robot
définie n'importe où
rangée avec les attributs qu'elle utilise
Machine à méthode · robot.deplacer(dx) sur un écran de 160 de large
Choisis un robot et un déplacement pour voir ce que fait la méthode.
[3]Recherche
Ce que disent les sources
Tutoriel officiel de Python — Une méthode est une fonction qui « appartient » à un objet. Quand on écrit x.f(), l'objet x est passé automatiquement comme premier argument de la fonction : c'est pour cela qu'on ne l'écrit pas entre les parenthèses [1].
Tutoriel officiel de Python — Le nom self n'a rien de magique pour Python ; c'est une convention suivie par presque tous les programmeurs [1].
[4]Mythes
« self est un mot magique de Python. »
c'est le nom habituel du premier paramètre d'une méthode. Python y met l'objet ; garde ce nom, tout le monde l'utilise.
« Une méthode, c'est complètement différent d'une fonction. »
c'est une fonction rangée dans une classe, qui reçoit l'objet en premier paramètre.
« Pour appeler robot.deplacer(10), il faut aussi donner self. »
Python le donne tout seul ; on écrit seulement 10.
[5]Quiz
1. Une classe Compteur a self.valeur = 0 dans __init__ et une méthode ajouter(self, n) qui fait self.valeur = self.valeur + n. Après c = Compteur(), c.ajouter(3) et c.ajouter(4), que vaut c.valeur ?
0 + 3 + 4 = 7 ; chaque appel modifie le même objet (sortie vérifiée).
2. Combien de valeurs écrit-on entre les parenthèses de robot.deplacer(…) ?
Python donne robot comme self ; on fournit seulement dx.
3. Que renvoie lettre.est_tombee() quand lettre.y vaut 120 et que l'écran mesure 120 pixels de haut ?
la méthode teste self.y > HAUTEUR, et 120 > 120 est faux.
[6]Kit
🎒 Ton kit — Épisode 11
15 min
Exercice : prédire les positions. Recopie les classes ci-dessus. Pour chaque ligne, écris sur papier la position attendue, puis vérifie.
Un robot part de 72 et fait deplacer(4), puis deplacer(-20).
Un robot part de 2 et fait deplacer(-4).
Une lettre de vitesse 3 part de y = 0 et appelle tomber() 5 fois.
Code à copier : les classes Robot et Lettre ci-dessus.
Checklist
Je sais définir une méthode avec self comme premier paramètre.
Je sais appeler une méthode avec un point, sans donner self.
J'ai prédit puis vérifié les positions.
Vigilanceles méthodes sont décalées dans la classe (4 espaces), et leur corps encore de 4 espaces de plus. Une méthode mal décalée devient une fonction ordinaire, en dehors de la classe.
[7]Journal
✍️ Journal de bord
Quelle méthode pourrait encore avoir ton robot (au moins deux idées) ? Laquelle modifierait l'objet, laquelle renverrait une valeur ?
Tester un objet seul, puis simuler la chute d'une lettre dans la console avant de passer à l'écran.
⏱ 25 min de pratique · 5 min de quiz
[1]Scénario
Inès · Jeudi, 12 h 40
Avant de dessiner quoi que ce soit, l'animatrice demande à Inès de prouver que sa lettre sait tomber et repartir en haut. « À l'écran, tout ira trop vite pour voir les erreurs. Dans la console, tu verras chaque étape. » Inès ajoute une méthode repartir, et lance dix tours de chute.
[2]Méthode
« Tester un objet seul »
Rappel en une phrase : une méthode est une fonction de la classe, appelée avec un point (voir épisode 11).
Fabrique un seul objet, avec des valeurs faciles à suivre (ici, une vitesse de 40 pour voir la lettre sortir vite).
Appelle ses méthodes dans une boucle, comme le fera le jeu.
Affiche ses attributs à chaque tour (c'est le « tester chaque fonction seule » du Pro, voir Pro, épisode 12).
Compare avec ce que tu attendais.
Code
import random
HAUTEUR = 120
LARGEUR = 160
class Lettre:
def __init__(self, caractere, x, vitesse):
self.caractere = caractere
self.x = x
self.y = 0
self.vitesse = vitesse
def tomber(self):
"""Fait descendre la lettre de sa vitesse."""
self.y = self.y + self.vitesse
def est_tombee(self):
"""Renvoie True si la lettre est sortie par le bas de l'écran."""
return self.y > HAUTEUR
def repartir(self, caractere):
"""Remet la lettre en haut, à une place au hasard, avec un nouveau caractère."""
self.caractere = caractere
self.x = random.randint(0, LARGEUR - 4)
self.y = 0
lettre = Lettre("A", 30, 40)
for tour in range(1, 11):
lettre.tomber()
if lettre.est_tombee():
lettre.repartir("B")
print(f"tour {tour} : {lettre.caractere} en y = {lettre.y}")
Affiche (sortie réelle) :
Ce que tu vois
tour 1 : A en y = 40
tour 2 : A en y = 80
tour 3 : A en y = 120
tour 4 : B en y = 0
tour 5 : B en y = 40
tour 6 : B en y = 80
tour 7 : B en y = 120
tour 8 : B en y = 0
tour 9 : B en y = 40
tour 10 : B en y = 80
Au tour 3, la lettre est à 120 : elle touche le bord sans être sortie (> et non >=). Au tour 4, elle descend à 160, sort, et repart aussitôt en haut avec le caractère « B ».
Remets les lignes dans l'ordre · clique les lignes une par une
Ton programme
Lignes à placer
[3]Pourquoi ça marche
Dans un jeu, l'écran se redessine environ 30 fois par seconde : une erreur de position passe inaperçue. Dans la console, chaque tour s'affiche sur sa ligne, et on peut vérifier les valeurs une par une, comme avec le débogueur (voir Pro, épisode 18). Un objet qui marche seul marchera dans le jeu.
À reteniron teste chaque objet seul, dans la console, avant de le mettre à l'écran.
[4]Entraînement
Bon réflexe ou piège ?
Je choisis une grande vitesse pour mes tests, pour voir la lettre sortir en peu de tours.
on vérifie vite le cas « la lettre sort ».
Dans repartir, j'oublie de remettre self.y à 0.
la lettre change de caractère mais reste en bas, et sort à chaque tour.
J'affiche les attributs à chaque tour.
c'est un print de contrôle (voir Pro, épisode 16).
Je passe directement à l'écran sans tester l'objet seul.
à 30 images par seconde, impossible de voir où ça coince.
Je donne une docstring à chaque méthode.
elles serviront pour le mode d'emploi du projet (arc 3).
[5]Quiz
1. Au tour 3 du test, la lettre est à y = 120. Pourquoi ne repart-elle pas en haut ?
elle ne sort qu'au tour suivant, à 160.
2. Que fait lettre.repartir("B") ?
c'est le même objet, dont on change les attributs.
3. Pourquoi tester dans la console avant l'écran ?
un tour = une ligne : on peut vérifier chaque valeur.
[6]Kit
🎒 Ton kit — Épisode 12
20 min
Exercice : la chute en console
Ajoute tomber, est_tombee et repartir à ta classe Lettre.
Lance le test des 10 tours et compare avec la sortie du livre.
Change la vitesse (25, puis 7) : prédis le tour où la lettre repart, puis vérifie.
Bonus : fais tomber 3 lettres à la fois avec une liste et une boucle.
Code à copier : le programme ci-dessus.
Checklist
Ma lettre tombe, sort et repart en haut.
J'ai prédit le tour de sortie pour deux vitesses.
Mes méthodes ont une docstring.
[7]Journal
✍️ Journal de bord
Qu'est-ce que le test en console t'a appris sur ta lettre, que tu n'aurais pas vu à l'écran ?
Découvrir Pyxel : l'écran en pixels, les coordonnées, et la boucle de jeu update / draw.
⏱ 25 min de lecture · 5 min de quiz
[1]Scénario
Inès · Mardi, 12 h 40
Jusqu'ici, tout se passait dans la console. Au club, l'animatrice ouvre une activité Pyxel Studio dans Capytale : une petite fenêtre, de gros pixels, 16 couleurs. Elle lance un programme de vingt lignes, et un rectangle vert apparaît en bas de l'écran. « Voilà ton robot. Le reste, ce sont tes objets. »
[2]Concept
Pyxel et la boucle de jeu
Pyxel est une bibliothèque de jeu pour Python : un module qui sait ouvrir une fenêtre, dessiner, lire le clavier et jouer des sons. Il imite les vieilles consoles : petit écran, 16 couleurs.
Où l'utiliser ? Sans rien installer toi-même :
au collège, dans l'activité Pyxel Studio de Capytale, si ton professeur la propose (accès par l'ENT) ;
à la maison, dans Thonny, si un adulte installe Pyxel (menu Outils → Gérer les paquets ; Tools → Manage packages dans la version anglaise).
L'écran en pixels. L'écran d'Attrape-lettres mesure 160 pixels de large et 120 de haut. Chaque point a des coordonnées (x, y) :
x va de 0 (à gauche) à 159 (à droite) ;
y va de 0 (en haut) à 119 (en bas). Attention : y grandit vers le bas, contrairement aux repères de maths.
La boucle de jeu. Un jeu vidéo n'est pas un film : environ 30 fois par seconde, il recalcule tout (update), puis redessine tout (draw). Ce qui bouge, c'est un objet dont les attributs changent un peu à chaque image.
Étape
Rôle
Exemples
update
calculer : lire le clavier, déplacer, tester les collisions
self.robot.deplacer(2)
draw
dessiner l'image : effacer, puis tout redessiner
pyxel.cls(…), pyxel.rect(…)
Le premier programme, écrit avec une classe Jeu, comme les exemples officiels de Pyxel :
Le premier écran d'Attrape-lettres (capture réelle, Pyxel 2.9.9).
Instruction
Ce qu'elle fait
pyxel.init(160, 120, title="…")
crée l'écran de 160 × 120 pixels
pyxel.run(self.update, self.draw)
lance la boucle : appelle update puis draw, environ 30 fois par seconde
pyxel.cls(couleur)
efface tout l'écran avec une couleur
pyxel.rect(x, y, largeur, hauteur, couleur)
dessine un rectangle plein, coin en haut à gauche en (x, y)
pyxel.text(x, y, "texte", couleur)
écrit un texte ; chaque caractère mesure 4 × 6 pixels
pyxel.COLOR_NAVY, COLOR_LIME…
les 16 couleurs, par leur nom en anglais
pass veut dire « ne rien faire » : update n'a encore rien à calculer.
self.update est donné sans parenthèses à pyxel.run : on ne l'appelle pas, on dit à Pyxel quelle méthode appeler à chaque image.
La police de Pyxel n'a pas d'accents : « é » ne s'affiche pas (testé). Dans le jeu, on écrit « GAGNE » et « C'etait ».
Pourquoi une classe Jeu ? Les objets du jeu (le robot, les lettres) deviennent ses attributs (self.robot), et update et draw peuvent tous les utiliser.
Écran simulé · 160 × 120 pixels, affiché agrandi
Clique sur l'écran : ses coordonnées (x, y) s'affichent ici. Le coin (0, 0) est en haut à gauche ; y grandit vers le bas.
[3]Recherche
Ce que disent les sources
Pyxel — Un moteur de jeu rétro pour Python, sous licence MIT, créé par Takashi Kitao. Il n'affiche que 16 couleurs et gère 4 canaux de son. Version 2.9.9, publiée le 12 août 2026 ; elle demande Python 3.11 ou plus récent [1][2].
Documentation de Pyxel — init(width, height, title=…, fps=30, …) : l'écran et, par défaut, 30 images par seconde. run(update, draw) appelle update puis draw à chaque image [2].
Exemples officiels — Le premier exemple fourni avec Pyxel est écrit avec une classe : pyxel.init et pyxel.run(self.update, self.draw) dans __init__ [2].
Capytale — Pyxel Studio a été intégré à Capytale en 2023 : l'enseignant propose un début de programme, l'élève le complète, l'enseignant évalue [3].
Thonny — Un menu permet d'installer des paquets Python sans ligne de commande (Outils → Gérer les paquets) [4].
[4]Mythes
« Un jeu vidéo, c'est un film qu'on regarde. »
il recalcule et redessine chaque image, environ 30 fois par seconde, d'après les attributs de ses objets.
« Comme en maths, y grandit vers le haut. »
sur un écran, y vaut 0 en haut et grandit vers le bas.
« Pour faire un jeu, il faut un logiciel professionnel. »
Pyxel est un module Python gratuit, pensé pour des petits jeux simples.
[5]Quiz
1. Sur l'écran de 160 × 120 pixels, où se trouve le point (0, 119) ?
x = 0 à gauche, et y grandit vers le bas : 119 est la dernière ligne.
2. Qu'est-ce qui doit aller dans update ?
update calcule ; draw dessine.
3. Pourquoi écrit-on pyxel.run(self.update, self.draw) sans parenthèses après update ?
avec des parenthèses, on les appellerait une seule fois, tout de suite.
[6]Kit
🎒 Ton kit — Épisode 13
20 min
Exercice : ton premier écran
Ouvre Pyxel (activité Capytale ou Thonny avec Pyxel installé par un adulte).
Lance le premier programme et retrouve l'écran de la capture.
Déplace le « A » en (100, 50), puis change sa couleur.
Ajoute deux autres lettres et un deuxième rectangle, en prévoyant leurs coordonnées sur papier.
Code à copier : le premier programme ci-dessus.
Checklist
J'ai ouvert Pyxel sans rien installer moi-même.
Je sais que y grandit vers le bas.
Je sais ce qui va dans update et ce qui va dans draw.
VigilancePyxel s'installe uniquement depuis sa source officielle, par un adulte, ou s'utilise dans l'activité Capytale de ton collège. N'installe jamais un « Pyxel » trouvé sur un site de téléchargement.
[7]Journal
✍️ Journal de bord
Dans un jeu que tu connais, qu'est-ce qui change d'une image à l'autre ? Qu'est-ce qui reste toujours au même endroit ?
[8]Sources
Pyxel, page du projet sur PyPI (version 2.9.9 du 12/08/2026, licence MIT), consulté le 29/10/2026. (pypi.org/project/pyxel)
T. Kitao, documentation et exemples livrés avec Pyxel 2.9.9 (README, signatures de init et run, exemple 01_hello_pyxel.py), consulté le 29/10/2026. (pypi.org/project/pyxel)
Capytale, annonce de l'intégration de Pyxel Studio (2023) et documentation de l'activité (capytale.forge.apps.education.fr/documentation/PyxelStudio/), consulté le 29/10/2026. (x.com/CapytaleFr/status/1674431513507807233)
Faire bouger le robot avec les flèches : calculer dans update, dessiner dans draw.
⏱ 25 min de pratique · 5 min de quiz
[1]Scénario
Inès · Jeudi, 17 h 30
Le rectangle vert est là, mais il ne bouge pas. Inès a déjà une classe Robot avec une méthode deplacer qui l'empêche de sortir de l'écran (épisode 11). Il reste à la brancher sur le clavier. Malik parie qu'elle va essayer de déplacer le robot dans draw. Elle ne lui fait pas ce plaisir.
[2]Méthode
« Calculer dans update, dessiner dans draw »
Rappels : la classe Robot et sa méthode deplacer (voir épisode 11) ; la boucle update / draw (voir épisode 13).
Dans __init__ du jeu : fabrique les objets (self.robot = Robot(72)), avantpyxel.run.
Dans update : lis le clavier et change les attributs. pyxel.btn(pyxel.KEY_LEFT) vaut True tant que la flèche gauche est enfoncée.
Dans draw : efface, puis demande à chaque objet de se dessiner (une méthode dessiner).
Teste : maintiens une flèche jusqu'au bord de l'écran ; le robot doit s'arrêter.
Code
import pyxel
LARGEUR = 160
HAUTEUR = 120
class Robot:
def __init__(self, x):
self.x = x
self.y = 108
self.largeur = 16
self.hauteur = 8
def deplacer(self, dx):
"""Déplace le robot de dx pixels, sans sortir de l'écran."""
self.x = self.x + dx
if self.x < 0:
self.x = 0
if self.x > LARGEUR - self.largeur:
self.x = LARGEUR - self.largeur
def dessiner(self):
"""Dessine le robot à sa position."""
pyxel.rect(self.x, self.y, self.largeur, self.hauteur, pyxel.COLOR_LIME)
class Jeu:
def __init__(self):
pyxel.init(LARGEUR, HAUTEUR, title="Attrape-lettres")
self.robot = Robot(72)
pyxel.run(self.update, self.draw)
def update(self):
if pyxel.btn(pyxel.KEY_LEFT):
self.robot.deplacer(-2)
if pyxel.btn(pyxel.KEY_RIGHT):
self.robot.deplacer(2)
def draw(self):
pyxel.cls(pyxel.COLOR_NAVY)
self.robot.dessiner()
Jeu()
Vérifié en simulant le clavier (Pyxel sans fenêtre) : flèche droite pendant 21 images puis flèche gauche pendant 30 images → le robot passe de 72 à 114, puis à 54. Flèche droite maintenue 200 images → il s'arrête à 144, au bord droit (160 − 16).
À 30 images par seconde, 2 pixels par image font 60 pixels par seconde : le robot traverse l'écran en un peu moins de 3 secondes.
[3]Pourquoi ça marche
Séparer « calculer » et « dessiner » garde chaque méthode simple : update ne dessine rien, draw ne change rien. Si le robot est mal placé, l'erreur est dans update ; s'il est bien placé mais mal dessiné, elle est dans draw. Et comme le robot sait lui-même se déplacer et se dessiner, le jeu se contente de lui demander. C'est la structure de tous les exemples officiels de Pyxel [1].
À retenirupdate change les attributs, draw les montre. Les objets sont fabriqués avant pyxel.run.
[4]Entraînement
Bon réflexe ou piège ?
Je déplace le robot dans draw.
draw doit seulement dessiner ; mélanger les deux rend les bugs difficiles à trouver.
Je fabrique le robot après pyxel.run.
pyxel.run lance la boucle et ne rend pas la main ; la ligne d'après n'est jamais exécutée, et update ne trouve pas self.robot.
J'utilise la méthode deplacer qui gère déjà le bord de l'écran.
la règle est écrite une seule fois, dans la classe.
J'oublie pyxel.cls(…) au début de draw.
les anciennes positions restent à l'écran, le robot laisse une traînée.
Je teste en maintenant une flèche jusqu'au bord.
c'est le cas limite du plan de test.
[5]Quiz
1. Que vaut pyxel.btn(pyxel.KEY_RIGHT) quand personne ne touche le clavier ?
btn vaut True seulement tant que la touche est enfoncée.
2. Le robot part de 72 et la flèche droite reste enfoncée 21 images. Où est-il ?
21 images × 2 pixels = 42, et 72 + 42 = 114 (vérifié en simulant le clavier).
3. Pourquoi le robot s'arrête-t-il à 144 et pas à 160 ?
c'est la règle écrite dans deplacer.
[6]Kit
🎒 Ton kit — Épisode 14
25 min
Exercice : ton robot au clavier
Recopie le programme et lance-le.
Teste les deux flèches et les deux bords.
Change la vitesse (3 pixels par image) et vérifie qu'il ne sort toujours pas.
Bonus : fais aussi tomber une lettre (classe Lettre de l'épisode 12) : tomber() dans update, pyxel.text(…) dans draw.
Code à copier : le programme ci-dessus.
Checklist
Mon robot bouge avec les flèches.
Il ne sort pas de l'écran, ni à gauche ni à droite.
Rien n'est déplacé dans draw.
Vigilancen'utilise Pyxel que dans l'activité Capytale de ton collège, ou installé par un adulte depuis la source officielle.
[7]Journal
✍️ Journal de bord
Quelle sensation donne ton robot quand il bouge (trop lent, trop rapide, juste bien) ? Quel nombre changerais-tu, et dans quelle méthode ?
[8]Sources
T. Kitao, exemples livrés avec Pyxel 2.9.9 et documentation de btn, consulté le 29/10/2026. (pypi.org/project/pyxel)
Semaine 8 · Attraper et compter
15
S8 · MARDI · Comprendre
Attraper, éviter, compter
Détecter qu'une lettre touche le robot, réagir, et savoir quand la partie est gagnée ou perdue.
⏱ 25 min de lecture · 5 min de quiz
[1]Scénario
Inès · Mardi, 14 h
Les lettres tombent, le robot bouge… mais elles passent à travers lui comme des fantômes. Malik joue cinq minutes et ne marque aucun point. « L'ordinateur ne voit pas que ça se touche ? » Non : il ne voit rien du tout. Il ne connaît que des nombres. Pour qu'il sache que deux choses se touchent, il faut le lui calculer.
[2]Concept
Les collisions et les règles du jeu
Deux rectangles se touchent-ils ? Le robot et chaque lettre occupent un rectangle (position du coin en haut à gauche, largeur, hauteur). Deux rectangles se chevauchent si, en même temps :
le bord gauche de chacun est avant le bord droit de l'autre (sur l'axe des x) ;
le bord du haut de chacun est avant le bord du bas de l'autre (sur l'axe des y).
Code
def touche(a, b):
"""Renvoie True si les rectangles des objets a et b se chevauchent."""
return (a.x < b.x + b.largeur and b.x < a.x + a.largeur
and a.y < b.y + b.hauteur and b.y < a.y + a.hauteur)
and veut dire « et » : les quatre conditions doivent être vraies. Une longue condition peut être coupée sur deux lignes à l'intérieur des parenthèses. Comme touche lit seulement les attributs x, y, largeur et hauteur, elle marche pour le robot comme pour une lettre : il suffit que la lettre ait aussi self.largeur = 4 et self.hauteur = 6 (la taille d'un caractère).
Tests réels avec un robot en (70, 108) de 16 × 8, et une lettre de 4 × 6 :
Lettre en
Touche ?
Pourquoi
(75, 105)
True
elle recouvre le haut du robot
(75, 90)
False
encore trop haut
(90, 110)
False
trop à droite (le robot s'arrête à 86)
(67, 110)
True
elle dépasse à gauche, mais recouvre le bord du robot
Les règles d'Attrape-lettres, écrites dans update :
chaque lettre tombe ;
si elle touche le robot : bonne lettre du mot → elle est ajoutée aux lettres trouvées et le score augmente ; mauvaise lettre → une vie en moins ; dans les deux cas, elle repart en haut avec un nouveau caractère ;
si elle sort par le bas sans être attrapée : elle repart en haut ;
fin de partie : toutes les lettres du mot trouvées → gagné ; plus de vie → perdu. Un attribut self.etat ("jeu", "gagné", "perdu") le retient, et update ne fait plus rien quand la partie est finie.
Le nouveau caractère est tiré au hasard (voir Pro, épisode 8) : une fois sur deux, une lettre utile du mot, sinon n'importe quelle lettre. Les fonctions afficher_mot et mot_trouve du mot mystère resservent telles quelles (voir Pro, épisode 14).
Écran simulé · collision entre le robot (70, 108) et une lettre
Pour aller plus loin : la carte micro:bit. Si ton collège a des cartes micro:bit, tu peux programmer de petits jeux en MicroPython (une version de Python pour les cartes électroniques) avec l'éditeur officiel de la carte, dans le navigateur. Avec un adulte ou ton professeur.
[3]Recherche
Ce que disent les sources
Documentation de Pyxel — La police par défaut dessine des caractères de 4 pixels de large et 6 de haut (constantes FONT_WIDTH et FONT_HEIGHT) [1].
Tests de ce livre — Les quatre cas du tableau et des parties complètes ont été exécutés avec Pyxel 2.9.9 : la collision, les vies et la fin de partie se comportent comme décrit (journal de test).
Micro:bit Educational Foundation — L'éditeur Python de la micro:bit est un outil gratuit et libre, utilisable dans le navigateur, pour écrire des programmes MicroPython pour la carte [2].
[4]Mythes
« L'ordinateur voit que deux images se touchent. »
il compare des nombres : les positions et les tailles des deux rectangles.
« Si deux objets se touchent, Python le signale tout seul. »
rien ne se passe tant que ton programme ne teste pas touche à chaque image.
« Une collision demande des maths compliquées. »
quatre comparaisons suffisent pour deux rectangles.
[5]Quiz
1. Le robot est en (70, 108) et mesure 16 × 8. Une lettre de 4 × 6 est en (75, 90). Se touchent-ils ?
la lettre finit à y = 96, avant le haut du robot (108) (testé).
2. Que se passe-t-il quand une mauvaise lettre touche le robot ?
c'est la règle 2.
3. À quoi sert l'attribut self.etat ?
update s'arrête quand la partie est finie, et draw affiche le bon message.
[6]Kit
🎒 Ton kit — Épisode 15
20 min
Exercice : la collision sur papier, puis en Python
Sur du papier quadrillé, dessine le robot en (70, 108) et 4 lettres de 4 × 6 à des positions de ton choix.
Prédis pour chacune si elle touche le robot.
Vérifie avec ce programme de test :
Code à copier
class Rectangle:
def __init__(self, x, y, largeur, hauteur):
self.x = x
self.y = y
self.largeur = largeur
self.hauteur = hauteur
def touche(a, b):
"""Renvoie True si les rectangles a et b se chevauchent."""
return (a.x < b.x + b.largeur and b.x < a.x + a.largeur
and a.y < b.y + b.hauteur and b.y < a.y + a.hauteur)
robot = Rectangle(70, 108, 16, 8)
for x, y in [(75, 105), (75, 90), (90, 110), (67, 110)]:
lettre = Rectangle(x, y, 4, 6)
print((x, y), touche(robot, lettre))
Remplace les 4 positions par les tiennes.
Checklist
Je sais expliquer les quatre conditions d'une collision.
J'ai prédit puis vérifié 4 cas.
Je connais les règles d'Attrape-lettres (attraper, éviter, fin de partie).
[7]Journal
✍️ Journal de bord
Invente une règle de plus pour Attrape-lettres (une lettre bonus, une vitesse qui augmente…). Quels attributs et quelles méthodes faudrait-il ajouter ?
[8]Sources
T. Kitao, Pyxel 2.9.9, constantes FONT_WIDTH et FONT_HEIGHT, consulté le 29/10/2026. (pypi.org/project/pyxel)
Micro:bit Educational Foundation, Python Editor, consulté le 29/10/2026.
16
S8 · JEUDI · Pratiquer · Bilan d'arc
Des objets dans le jeu : le bilan
Ton outil de synthèse, le récapitulatif de l'arc et ton badge.
⏱ 30 min · arbre de décision · carrousel · quiz final
[1]Scénario
Inès · Jeudi, 12 h 40
Première partie d'Attrape-lettres au club. Malik attrape le C, le H, le A… puis un X qui lui coûte une vie, et enfin le T : « GAGNE ! ». Il réclame une revanche. Il y a un mois, Inès rangeait des scores dans des dictionnaires. Aujourd'hui, ses objets savent se déplacer, tomber, se dessiner et se toucher. La première version est jouable.
[2]Outil
« Où mettre ce code ? »
Aide à la décision interactive
[3]Carrousel
🎨 Carrousel récapitulatif — Arc 2
MASTER · ARC 2 · 1/5
Des objets dans le jeu
Quatre semaines pour que le robot et les lettres prennent vie.
2/5
Les classes
une classe est un plan
un objet est un exemplaire
__init__ donne les attributs self.…
chaque objet a les siens
3/5
Les méthodes
une fonction rangée dans la classe
self en premier
appelée avec un point, sans donner self
4/5
La boucle de jeu
update calcule, draw dessine, environ 30 fois par seconde
y grandit vers le bas
une classe Jeu garde les objets
5/5
Les collisions
deux rectangles se touchent si quatre comparaisons sont vraies ; un etat pour la fin de partie. Arc suivant : un projet bien rangé.
[4]Quiz final
1. Qu'affiche print(robot.x) après robot = Robot(140) et robot.deplacer(10), si l'écran fait 160 de large et le robot 16 ?
deplacer empêche le robot de dépasser 160 − 16 = 144 (sortie vérifiée).
2. Où se lit le clavier ?
lire le clavier sert à calculer les nouvelles positions.
3. Une AttributeError: 'Robot' object has no attribute 'x' apparaît. Quelle est la cause la plus probable ?
sans self., l'attribut n'a jamais été créé sur l'objet.
4. Pourquoi la lettre a-t-elle des attributs largeur et hauteur ?
touche lit x, y, largeur et hauteur de chaque objet.
5. La partie est perdue. Que doit faire update ?
draw continue d'afficher le message de fin.
[5]Kit
🎒 Ton kit de fin d'arc
30 min
Attrape-lettres, première version
Synthèse : toutes les pièces de l'arc dans un seul programme.
Code à copier
import random
import pyxel
LARGEUR = 160
HAUTEUR = 120
ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
MOTS = ["CHAT", "LUNE", "ROBOT", "PIRATE"]
class Robot:
def __init__(self, x):
self.x = x
self.y = 108
self.largeur = 16
self.hauteur = 8
self.vies = 3
self.score = 0
def deplacer(self, dx):
"""Déplace le robot de dx pixels, sans sortir de l'écran."""
self.x = self.x + dx
if self.x < 0:
self.x = 0
if self.x > LARGEUR - self.largeur:
self.x = LARGEUR - self.largeur
def dessiner(self):
"""Dessine le robot à sa position."""
pyxel.rect(self.x, self.y, self.largeur, self.hauteur, pyxel.COLOR_LIME)
class Lettre:
def __init__(self, caractere, x, vitesse):
self.caractere = caractere
self.x = x
self.y = 0
self.largeur = 4
self.hauteur = 6
self.vitesse = vitesse
def tomber(self):
"""Fait descendre la lettre de sa vitesse."""
self.y = self.y + self.vitesse
def est_tombee(self):
"""Renvoie True si la lettre est sortie par le bas de l'écran."""
return self.y > HAUTEUR
def repartir(self, caractere):
"""Remet la lettre en haut, à une place au hasard, avec un nouveau caractère."""
self.caractere = caractere
self.x = random.randint(0, LARGEUR - self.largeur)
self.y = 0
def dessiner(self):
"""Dessine la lettre à sa position."""
pyxel.text(self.x, self.y, self.caractere, pyxel.COLOR_YELLOW)
def touche(a, b):
"""Renvoie True si les rectangles des objets a et b se chevauchent."""
return (a.x < b.x + b.largeur and b.x < a.x + a.largeur
and a.y < b.y + b.hauteur and b.y < a.y + a.hauteur)
def afficher_mot(mot, trouvees):
"""Renvoie le mot avec un tiret à la place de chaque lettre pas encore trouvée."""
affichage = ""
for lettre in mot:
if lettre in trouvees:
affichage = affichage + lettre + " "
else:
affichage = affichage + "_ "
return affichage.strip()
def mot_trouve(mot, trouvees):
"""Renvoie True si toutes les lettres du mot ont été trouvées."""
for lettre in mot:
if lettre not in trouvees:
return False
return True
class Jeu:
def __init__(self):
pyxel.init(LARGEUR, HAUTEUR, title="Attrape-lettres")
self.mot = random.choice(MOTS)
self.trouvees = []
self.robot = Robot(72)
self.lettres = []
for i in range(3):
lettre = Lettre(self.nouveau_caractere(), 0, random.randint(1, 2))
lettre.repartir(lettre.caractere)
lettre.y = -30 * i
self.lettres.append(lettre)
self.etat = "jeu"
pyxel.run(self.update, self.draw)
def nouveau_caractere(self):
"""Une fois sur deux, une lettre utile du mot ; sinon, une lettre au hasard."""
manquantes = []
for lettre in self.mot:
if lettre not in self.trouvees:
manquantes.append(lettre)
if len(manquantes) > 0 and random.randint(1, 2) == 1:
return random.choice(manquantes)
return random.choice(ALPHABET)
def update(self):
if self.etat != "jeu":
return
if pyxel.btn(pyxel.KEY_LEFT):
self.robot.deplacer(-2)
if pyxel.btn(pyxel.KEY_RIGHT):
self.robot.deplacer(2)
for lettre in self.lettres:
lettre.tomber()
if touche(self.robot, lettre):
if lettre.caractere in self.mot:
if lettre.caractere not in self.trouvees:
self.trouvees.append(lettre.caractere)
self.robot.score = self.robot.score + 1
else:
self.robot.vies = self.robot.vies - 1
lettre.repartir(self.nouveau_caractere())
elif lettre.est_tombee():
lettre.repartir(self.nouveau_caractere())
if mot_trouve(self.mot, self.trouvees):
self.etat = "gagné"
elif self.robot.vies == 0:
self.etat = "perdu"
def draw(self):
pyxel.cls(pyxel.COLOR_NAVY)
pyxel.text(5, 5, afficher_mot(self.mot, self.trouvees), pyxel.COLOR_WHITE)
pyxel.text(110, 5, f"Vies : {self.robot.vies}", pyxel.COLOR_PINK)
for lettre in self.lettres:
lettre.dessiner()
self.robot.dessiner()
if self.etat == "gagné":
pyxel.text(55, 55, "GAGNE !", pyxel.COLOR_LIME)
elif self.etat == "perdu":
pyxel.text(40, 55, f"PERDU ! C'etait {self.mot}", pyxel.COLOR_RED)
Jeu()
Trois détails :
au départ, les trois lettres sont décalées vers le haut (lettre.y = -30 * i), pour ne pas tomber toutes ensemble ;
return tout seul, au début d'update, arrête la méthode quand la partie est finie ;
les messages sont écrits sans accents, car la police de Pyxel n'en a pas.
Partie gagnée : le mot CHAT est complet (capture réelle, Pyxel 2.9.9).Partie perdue : plus de vie, le mot est révélé (capture réelle, Pyxel 2.9.9).
Vérifié : 9 parties complètes jouées sans fenêtre avec Pyxel 2.9.9. Un joueur automatique qui va vers les bonnes lettres gagne ses 6 parties ; un robot qui ne bouge pas en perd 2 sur 3.
Consigne : lance le jeu, joue trois parties, puis applique le plan de test du Pro (voir Pro, épisode 19) : gagner, perdre, attraper deux fois la même bonne lettre, rester collé à un bord. Note ce qui te surprend. Exporte ensuite ton carnet de bord.
Checklist
J'ai exporté mon carnet (bouton dans le menu).
Je sais expliquer où va chaque morceau de code (méthode, update, draw).
Ma première version d'Attrape-lettres est jouable, avec une fin gagnée et une fin perdue.
[6]Journal
✍️ Journal de bord — bilan
Qu'est-ce qui t'a le plus surprise ou surpris en voyant ton code devenir un jeu à l'écran ? Qu'aimerais-tu améliorer en premier ?
✦ CRÉATRICE · CRÉATEUR DE MONDES · ARC 2 ✦
Bravo ! Tu as terminé l'arc 2. Tu sais créer des classes et des objets, leur donner des méthodes, et en faire un jeu qui tourne à l'écran.
ARC 3 · SEMAINES 9 À 12
Un projet bien rangé
Ton jeu marche. Maintenant, il doit pouvoir être lu, lancé et amélioré par quelqu'un d'autre que toi. En quatre semaines, tu le découpes en fichiers, tu ranges son dossier, tu écris son mode d'emploi, et tu apprends à lire un code que tu n'as pas écrit.
Semaine 9 · Les modules
17
S9 · MARDI · Comprendre
Un fichier pour chaque chose
Découper un programme en plusieurs fichiers, et utiliser import et from … import avec tes propres modules.
⏱ 25 min de lecture · 5 min de quiz
[1]Scénario
Inès · Mardi, 12 h 40
Le fichier d'Attrape-lettres fait maintenant 150 lignes. Pour changer une couleur, Inès fait défiler l'écran, dépasse la ligne, remonte, se trompe de classe. Malik, lui, voudrait ajouter un mot à la liste, mais il n'ose pas toucher au fichier : « J'ai peur de tout casser. » L'animatrice ouvre un vrai projet sur l'écran du club : une dizaine de fichiers courts, chacun avec un nom clair. « Vous connaissez déjà import random. Aujourd'hui, vous importez vos propres fichiers. »
[2]Concept
Les modules, ce sont aussi tes fichiers
Tu sais importer un module fourni avec Python, comme random (voir Pro, épisode 8). Bonne nouvelle : chaque fichier .py que tu écris est aussi un module. Son nom de module est le nom du fichier, sans .py.
Étape 1 : un fichier personnages.py, dans le même dossier que le jeu. On y déplace les classes Robot et Lettre et la fonction touche, sans rien changer.
Code
import random
import pyxel
LARGEUR = 160
HAUTEUR = 120
class Robot:
... # la classe Robot, copiée telle quelle depuis le jeu
class Lettre:
... # la classe Lettre, copiée telle quelle
def touche(a, b):
... # la fonction touche, copiée telle quelle
(Les ... remplacent ici le code déjà écrit à l'arc 2 : dans ton fichier, tu colles le vrai code.)
Affiche 144. Avec import personnages, on écrit le nom du module, un point, puis ce qu'on veut : personnages.Robot, comme random.randint.
Code
from personnages import Robot, Lettre
robot = Robot(72)
lettre = Lettre("A", 50, 40)
for tour in range(4):
lettre.tomber()
print(robot.x, lettre.y, lettre.est_tombee())
Affiche 72 160 True. Avec from personnages import Robot, Lettre, on choisit les noms à importer, et on les écrit ensuite sans le nom du module.
Le piège : mélanger les deux.
Code
import personnages
robot = Robot(72)
Python s'arrête avec : NameError: name 'Robot' is not defined. Avec import personnages, seul le nom personnages est connu : il faut écrire personnages.Robot.
Le début de jeu.py devient :
Code
import random
import pyxel
from personnages import LARGEUR, HAUTEUR, Robot, Lettre, touche
ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
MOTS = ["CHAT", "LUNE", "ROBOT", "PIRATE"]
Le reste de jeu.py (les fonctions du mot mystère et la classe Jeu) ne change pas.
L'ordre des imports, en haut du fichier : d'abord les modules fournis avec Python (random), puis les bibliothèques ajoutées (pyxel), puis tes propres modules (personnages), avec une ligne vide entre chaque groupe.
Trois règles à retenir :
les fichiers à importer sont dans le même dossier que le fichier que tu lances : c'est là que Python cherche en premier ;
importn'est pas un copier-coller : le code reste dans personnages.py, et Python va le chercher. Si tu corriges une classe, tu la corriges à un seul endroit ;
jamais un fichier qui porte le nom d'un module existant : un fichier random.py ou pyxel.py dans ton dossier serait importé à la place du vrai (voir Pro, épisode 8).
Remets les lignes dans l'ordre · clique les lignes une par une
Ton programme
Lignes à placer
[3]Recherche
Ce que disent les sources
Tutoriel officiel de Python — Un module est un fichier contenant des définitions et des instructions ; son nom de fichier est le nom du module suffixé de .py [1].
Tutoriel officiel de Python — Le dossier contenant le script lancé est placé au début de la liste des dossiers où Python cherche les modules, avant les dossiers de bibliothèques [1].
Tutoriel officiel de Python — Les instructions d'un module ne sont exécutées que la première fois qu'il est importé [1].
PEP 8 — Les imports se placent en haut du fichier, regroupés dans cet ordre : bibliothèque standard, bibliothèques tierces, modules de ton application, avec une ligne vide entre les groupes [2].
Tests de ce livre — Les trois programmes de ce concept ont été lancés depuis leur dossier, sous Python 3.12.13 et 3.15.0 : sorties 144 et 72 160 True, et la NameError du piège (journal de test).
[4]Mythes
« Plusieurs fichiers, c'est plus compliqué qu'un seul. »
chaque fichier est plus court et a un seul rôle ; on sait tout de suite où chercher.
« import copie le code dans mon fichier. »
le code reste dans son module ; import permet de s'en servir. Une correction faite dans personnages.py profite à tous les fichiers qui l'importent.
« Un module, c'est forcément quelque chose qu'on télécharge. »
random est fourni avec Python, et ton fichier personnages.py est un module lui aussi.
[5]Quiz
1. Le fichier outils.py contient une fonction doubler. Dans jeu.py, on écrit import outils. Comment appeler la fonction ?
avec import outils, on écrit le nom du module, un point, puis la fonction.
2. Après from personnages import Robot, on écrit robot = Robot(140), puis robot.deplacer(10) et print(robot.x). Qu'est-ce qui s'affiche ? (L'écran fait 160 de large, le robot 16.)
from … import rend le nom Robot utilisable directement, et deplacer arrête le robot à 160 − 16 (sortie vérifiée).
3. Où Python cherche-t-il d'abord personnages.py ?
le dossier du script lancé passe en premier.
[6]Kit
🎒 Ton kit — Épisode 17
20 min
Exercice : sortir les personnages du jeu
Fais une copie du dossier de ton jeu (pour pouvoir revenir en arrière).
Crée personnages.py dans le même dossier. Déplaces-y les lignes LARGEUR = … et HAUTEUR = …, les classes Robot et Lettre et la fonction touche, avec leurs imports.
En haut de jeu.py, ajoute from personnages import LARGEUR, HAUTEUR, Robot, Lettre, touche.
Lance jeu.py : le jeu doit marcher exactement comme avant.
Bonus : dans un fichier d'essai, écris import personnages, fabrique un robot avec personnages.Robot(140) et vérifie que deplacer(10) l'arrête à 144.
Code à copier : le début de jeu.py ci-dessus.
Dans Capytale : l'éditeur de Pyxel Studio permet d'ajouter des fichiers au projet ; si ton activité n'en propose qu'un, demande à ton professeur. Dans Thonny : enregistre les deux fichiers dans le même dossier.
Checklist
personnages.py et jeu.py sont dans le même dossier.
Le jeu se lance depuis jeu.py et marche comme avant.
Je sais la différence entre import personnages et from personnages import Robot.
Vigilancen'appelle jamais un de tes fichiers comme un module existant (random.py, pyxel.py).
[7]Journal
✍️ Journal de bord
Dans ton jeu, quel morceau aimerais-tu pouvoir modifier sans toucher au reste ? Dans quel fichier le mettrais-tu ?
Trois fichiers, trois rôles : les données, les personnages et la partie.
⏱ 25 min de pratique · 5 min de quiz
[1]Scénario
Inès · Jeudi, 17 h 30
Malik veut un fond violet et un robot rose. Inès lui montre où sont les couleurs… dans deux fichiers différents. « Et la taille de l'écran, elle est dans personnages.py ? C'est bizarre, non ? » Il a raison : chaque chose doit avoir sa place. Inès décide d'un troisième fichier, rien que pour les données.
[2]Méthode
« Un module, un rôle »
Rappels : importer ses propres modules (voir épisode 17) ; la classe Jeu (voir épisode 13).
Liste les rôles : les données qu'on règle (taille, mots, couleurs), les personnages (classes et collision), la partie (règles, update, draw).
Un fichier par rôle : donnees.py, personnages.py, jeu.py.
Chaque fichier importe ce dont il a besoin, et rien de plus.
Relance après chaque déplacement : si le jeu ne marche plus, l'erreur vient du dernier morceau déplacé.
import random
import pyxel
from donnees import LARGEUR, HAUTEUR, COULEUR_ROBOT, COULEUR_LETTRE
et, dans les deux méthodes dessiner, pyxel.COLOR_LIME devient COULEUR_ROBOT, pyxel.COLOR_YELLOW devient COULEUR_LETTRE.
jeu.py : le début devient
Code
import random
import pyxel
from donnees import LARGEUR, HAUTEUR, ALPHABET, MOTS, COULEUR_FOND
from personnages import Robot, Lettre, touche
et, dans draw, pyxel.cls(pyxel.COLOR_NAVY) devient pyxel.cls(COULEUR_FOND). Tout le reste est inchangé.
Fichier
Son rôle
Ce qu'il importe
donnees.py
les réglages
pyxel (pour les couleurs)
personnages.py
le robot, les lettres, la collision
random, pyxel, donnees
jeu.py
la partie : règles, update, draw — le fichier à lancer
random, pyxel, donnees, personnages
Vérifié : la version en trois fichiers a joué les mêmes 9 parties que la première version (même tirage au hasard) : à la fin de chaque partie, toutes les positions, les lettres, les vies et les scores sont identiques, et les images à l'écran sont identiques au pixel près (Pyxel 2.9.9, Python 3.12.13 et 3.15.0).
[3]Pourquoi ça marche
Quand chaque fichier a un seul rôle, on sait où chercher : une couleur, c'est dans donnees.py ; un robot qui traverse le mur, c'est dans personnages.py ; une vie mal comptée, c'est dans jeu.py. Et chaque réglage n'existe qu'à un seul endroit : on ne risque plus d'en changer un et d'oublier sa copie. Le jeu, lui, ne voit aucune différence : Python va chercher chaque nom dans son module.
À retenirun module, un rôle. On déplace un morceau, on relance, on vérifie.
[4]Entraînement
Bon réflexe ou piège ?
Je mets toutes les couleurs dans donnees.py.
pour changer l'apparence du jeu, un seul fichier à ouvrir.
Je déplace tout d'un coup, puis je lance une seule fois à la fin.
si ça ne marche plus, impossible de savoir quel déplacement a cassé le jeu.
Je garde une copie de LARGEUR = 160 dans chaque fichier, au cas où.
le jour où tu changes la largeur, une des copies sera oubliée.
Je vérifie que le jeu se joue exactement comme avant le découpage.
découper ne doit rien changer au jeu, seulement au rangement.
J'importe dans personnages.py des noms dont il ne se sert pas.
on ne sait plus ce dont le fichier a vraiment besoin.
[5]Quiz
1. Malik veut un fond violet. Quel fichier ouvre-t-il ?
COULEUR_FOND est réglée dans donnees.py.
2. Dans personnages.py, on a oublié COULEUR_ROBOT dans la ligne from donnees import …. Que se passe-t-il quand le robot se dessine ?
un module ne connaît que les noms qu'il définit ou qu'il importe.
3. Quel fichier lance-t-on pour jouer ?
seul jeu.py fabrique le Jeu et lance la boucle ; les deux autres ne font que définir des choses.
[6]Kit
🎒 Ton kit — Épisode 18
25 min
Exercice : trois fichiers, un seul jeu
Crée donnees.py et déplaces-y les réglages.
Mets à jour les imports de personnages.py, relance.
Mets à jour les imports de jeu.py, relance.
Joue une partie gagnée et une partie perdue : tout doit être comme avant.
Change COULEUR_FOND et ajoute un mot à MOTS, uniquement dans donnees.py, et vérifie.
Code à copier : donnees.py et les nouveaux débuts de personnages.py et de jeu.py ci-dessus.
Checklist
Mon jeu tient en trois fichiers, chacun avec un rôle.
Chaque réglage n'est écrit qu'une seule fois.
J'ai relancé après chaque déplacement.
[7]Journal
✍️ Journal de bord
Qu'est-ce qui a été le plus délicat dans le découpage ? Quel message d'erreur as-tu rencontré, et comment l'as-tu corrigé ?
Un dossier par projet, des noms clairs, un seul fichier à lancer.
⏱ 25 min de lecture · 5 min de quiz
[1]Scénario
Malik · Mardi, 12 h 40
Inès a prêté son projet à Malik. Il ouvre le dossier : jeu.py, jeu_v2.py, jeu_v2_final_VRAI.py, test.py, test2.py, personnages.py, donnees.py, capture1.png, Sans titre.py… Il lance jeu_v2_final_VRAI.py : c'est une vieille version, sans les vies. Puis personnages.py : rien ne s'affiche. « Lequel je lance ? » Inès elle-même hésite.
[2]Concept
Le dossier d'un projet
1. Un dossier par projet, qui ne contient que ce projet :
Le dossier du projet
attrape-lettres/
jeu.py ← le fichier à lancer
personnages.py
donnees.py
LISEZMOI.txt ← le mode d'emploi (épisode 21)
images/
capture-partie.png
2. Un seul fichier à lancer : le point d'entrée. C'est lui qui fabrique le Jeu et lance la boucle. Les autres fichiers ne font que définir des choses : lancer personnages.py tout seul n'affiche rien et n'ouvre aucune fenêtre (testé). On donne au point d'entrée un nom qu'on reconnaît (jeu.py), et on le dit dans le mode d'emploi.
3. Des noms de fichiers clairs : courts, en minuscules, qui disent ce que contient le fichier. Pour un fichier Python, ni espace ni tiret : son nom devient un nom de module, et
Code
import mes-objets
s'arrête avec SyntaxError: invalid syntax (Python lit « mes moins objets »). Écris mes_objets.py. Le dossier, lui, peut s'appeler attrape-lettres : on ne l'importe pas.
4. Pas d'anciennes versions dans le dossier.jeu_v2_final_VRAI.py sème le doute. Les anciennes versions vont dans un dossier à part, à côté du projet (par exemple archives-attrape-lettres/), ou disparaissent.
5. Les ressources dans un sous-dossier : les captures dans images/. Ce qui n'est pas du code ne se mélange pas au code.
Pour aller plus loin (un repère, pas une obligation). Dans des projets écrits par d'autres, tu verras peut-être, à la fin du fichier à lancer :
Code
if __name__ == "__main__":
Jeu()
Cela veut dire : « lance le jeu seulement si ce fichier est le fichier lancé, pas s'il est importé ». Dans ce livre, on n'en a pas besoin : seul jeu.py lance quelque chose.
Auto-diagnostic · mon projet est-il rangé ?
Un dossier qui ne contient que ce projet.
Un seul fichier à lancer, au nom clair.
Aucune ancienne version dans le dossier.
Des noms de fichiers Python en minuscules, sans espace ni tiret.
Aucun fichier au nom d'un module existant (random.py, pyxel.py).
Les images rangées dans un sous-dossier.
[3]Recherche
Ce que disent les sources
PEP 8 — Les modules doivent avoir des noms courts, tout en minuscules ; le tiret bas peut être utilisé s'il rend le nom plus lisible [1].
Tutoriel officiel de Python — Un fichier lancé comme script s'exécute avec le nom spécial __name__ égal à "__main__" ; le test if __name__ == "__main__": permet donc de n'exécuter du code que si le fichier est lancé, pas s'il est importé [2].
Tests de ce livre — import mes-objets donne une SyntaxError sous Python 3.12.13 et 3.15.0 ; lancer personnages.py ou donnees.py seuls n'affiche rien (journal de test).
Pyxel Studio — Un projet y est une liste de fichiers (programmes Python, ressources) ; des boutons permettent de créer un nouveau fichier ou d'en téléverser un [3].
[4]Mythes
« Garder toutes les versions dans le dossier, c'est plus prudent. »
c'est le meilleur moyen de lancer la mauvaise. Les anciennes versions se gardent à part.
« Le nom des fichiers n'a pas d'importance. »
pour Python, le nom d'un fichier est le nom de son module ; un tiret ou une espace empêchent de l'importer.
« Si je lance n'importe quel fichier du projet, le jeu démarre. »
seul le point d'entrée lance le jeu ; les autres fichiers ne font que définir des choses.
[5]Quiz
1. Quel nom convient pour un fichier Python qu'on veut importer ?
ni espace ni tiret dans un nom de module ; import mes-objets donne une SyntaxError (testé).
2. Que se passe-t-il quand on lance personnages.py tout seul ?
définir une classe ne fabrique aucun objet et n'ouvre aucune fenêtre (testé).
3. Où ranger jeu_v1.py, l'ancienne version qui marche encore ?
dans le dossier du projet, quelqu'un risquerait de la lancer.
[6]Kit
🎒 Ton kit — Épisode 19
20 min
Exercice : ranger le dossier du jeu
Fais la liste de tous les fichiers de ton dossier.
Pour chacun, décide : je le garde, je le renomme, je le range à part, ou je le supprime.
Dessine sur papier l'arbre du dossier rangé, comme dans le concept.
Coche l'auto-diagnostic « Mon projet est-il rangé ? ».
Code à copier : aucun.
Checklist
Je sais quel fichier lancer, et il a un nom clair.
Mes noms de fichiers Python n'ont ni espace ni tiret.
J'ai dessiné l'arbre de mon dossier rangé.
Vigilanceavant de supprimer quoi que ce soit, fais une copie de tout le dossier. Et ne supprime jamais un fichier d'un camarade sans son accord.
[7]Journal
✍️ Journal de bord
Si un camarade ouvrait ton dossier aujourd'hui, sans toi, saurait-il quoi lancer ? Qu'est-ce qui le ferait hésiter ?
Utiliser pyxelstudio.net pour créer des jeux en Python avec Pyxel, mathsinfolycee.fr (1er septembre 2023), consulté le 29/10/2026.
20
S10 · JEUDI · Pratiquer
Ranger et relancer
Réorganiser le projet, comprendre les erreurs d'import, et rejouer le plan de test.
⏱ 25 min de pratique · 5 min de quiz
[1]Scénario
Inès · Jeudi, 17 h 30
Inès a rangé son dossier. Elle lance jeu.py… et un message rouge apparaît : ModuleNotFoundError: No module named 'personnages'. Elle avait glissé personnages.py dans le sous-dossier images/ par erreur. Malik rit : « Ranger, ça peut casser ! » Elle sourit : « Justement. Après avoir rangé, on relance, et on rejoue tout le plan de test. »
Relancer : lance jeu.py tout de suite. Si une erreur apparaît, elle vient du dernier changement.
Lire l'erreur d'import : dernière ligne, type d'erreur, nom en cause.
Rejouer le plan de test en entier quand tout est rangé : gagner, perdre, attraper deux fois la même bonne lettre, rester collé à un bord.
Les deux erreurs d'import les plus fréquentes (messages réels) :
Message d'erreur
Traceback (most recent call last):
File "jeu_test.py", line 1, in <module>
from personnages import Robot
ModuleNotFoundError: No module named 'personnages'
Module not found = module introuvable. Python ne trouve pas personnages.py dans le dossier du fichier lancé : il a été déplacé, renommé, ou il manque une lettre au nom.
Message d'erreur
Traceback (most recent call last):
File "jeu_test.py", line 1, in <module>
from personnages import Robot, lettre
ImportError: cannot import name 'lettre' from 'personnages' (…/personnages.py). Did you mean: 'Lettre'?
Cannot import name = impossible d'importer ce nom. Le fichier est trouvé, mais il ne contient rien qui s'appelle lettre : la classe s'appelle Lettre, avec une majuscule. Python propose même la correction. (Dans le vrai message, les … sont remplacés par le chemin complet du fichier sur ton ordinateur.)
Message
Ce qui se passe
Que vérifier
ModuleNotFoundError
le fichier est introuvable
il est dans le même dossier ? son nom est exact ?
ImportError: cannot import name
le fichier est trouvé, pas le nom
majuscules, orthographe, le nom existe-t-il dans le fichier ?
NameError
le nom n'est pas importé
from … import complet ? ou module.nom ?
[3]Pourquoi ça marche
Un rangement change des chemins et des noms, pas la logique du jeu. Les erreurs qu'il provoque sont donc presque toujours des erreurs d'import, et elles apparaissent dès le lancement : en relançant après chaque déplacement, on sait tout de suite lequel a posé problème. Le plan de test, lui, vérifie ce qu'une erreur d'import ne montre pas : que le jeu se joue toujours comme avant.
À retenirun changement à la fois, on relance, puis on rejoue tout le plan de test.
[4]Entraînement
Bon réflexe ou piège ?
Je renomme trois fichiers d'un coup, puis je lance.
en cas d'erreur, tu ne sais pas lequel des trois la provoque.
Je lis la dernière ligne : No module named 'personnages'. Je vérifie que personnages.py est dans le même dossier que jeu.py.
c'est la cause la plus fréquente.
Python propose Did you mean: 'Lettre'?. Je corrige la majuscule.
la proposition vaut la peine d'être lue, puis vérifiée.
Le jeu se lance, donc je n'ai pas besoin de rejouer le plan de test.
se lancer ne veut pas dire bien marcher.
Je mets personnages.py dans le sous-dossier images/ pour faire de la place.
Python cherche les modules dans le dossier du fichier lancé, pas dans ses sous-dossiers.
[5]Quiz
1. ModuleNotFoundError: No module named 'donnees'. Quelle est la cause la plus probable ?
Python ne trouve pas de fichier donnees.py à côté du fichier lancé.
2. ImportError: cannot import name 'robot' from 'personnages'. Que corriger ?
le fichier est trouvé ; c'est le nom robot qui n'existe pas dedans.
3. Le jeu se lance après le rangement. Que reste-t-il à faire ?
le plan de test vérifie que le jeu se joue comme avant.
[6]Kit
🎒 Ton kit — Épisode 20
25 min
Exercice : ranger, relancer, rejouer
Copie ton dossier de projet (sauvegarde).
Applique ton plan de rangement de l'épisode 19, un fichier à la fois, en relançant jeu.py après chaque changement.
Note chaque erreur rencontrée : message, cause, correction.
Rejoue tout le plan de test et coche chaque ligne.
Bonus : provoque exprès une ModuleNotFoundError (renomme donnees.py en donees.py), lis-la, puis remets le bon nom.
Code à copier : aucun.
Checklist
Mon projet est rangé et jeu.py se lance.
Je sais lire une ModuleNotFoundError et une ImportError.
J'ai rejoué tout le plan de test après le rangement.
[7]Journal
✍️ Journal de bord
Quelle erreur as-tu rencontrée en rangeant ? Combien de temps t'a-t-il fallu pour la comprendre ?
Messages d'erreur : exécutions réelles sous Python 3.12.13 et 3.15.0 (journal de test de ce livre), le 29/10/2026.
Semaine 11 · Le mode d'emploi
21
S11 · MARDI · Comprendre
Le mode d'emploi
Écrire la documentation d'un projet pour deux lecteurs : celui qui joue et celui qui code.
⏱ 25 min de lecture · 5 min de quiz
[1]Scénario
Inès · Mardi, 12 h 40
Aux portes ouvertes du collège, le club tiendra un stand. Des élèves de CM2 en visite essaieront Attrape-lettres seuls, pendant qu'Inès et Malik répondent aux parents. Les visiteurs ne liront pas le code. Et le professeur qui installera le jeu sur les ordinateurs du stand voudra savoir quel fichier lancer. Malik : « Le code se suffit à lui-même, non ? » L'animatrice : « Pour toi, oui. Pas pour eux. »
[2]Concept
Deux lecteurs, un mode d'emploi
Un projet se partage avec un mode d'emploi : un fichier texte, à la racine du dossier, qu'on lit avant tout le reste. On l'appelle souvent README (« lis-moi » en anglais) ; en français, LISEZMOI. Il s'adresse à deux lecteurs :
Le joueur
Le codeur
le but du jeu
comment lancer le projet (quel fichier, quel outil)
les touches
ce qu'il faut avoir (Pyxel)
comment on gagne, comment on perd
quel fichier fait quoi
comment faire une modification simple (ajouter un mot)
Exemple : LISEZMOI.txt d'Attrape-lettres
LISEZMOI.txt
ATTRAPE-LETTRES
Un jeu de lettres en Python, fait au club de code du collège.
POUR JOUER
But : retrouver le mot caché en attrapant ses lettres avec le robot.
Touches : flèche gauche et flèche droite.
Attention : une mauvaise lettre attrapée fait perdre une vie (3 vies au départ).
Fin de partie : le mot est complet (gagné) ou il n'y a plus de vie (perdu).
POUR LANCER ET MODIFIER LE JEU
Lancer : ouvrir jeu.py et cliquer sur Exécuter.
Il faut Pyxel (déjà présent dans Capytale ; dans Thonny, installé par un adulte).
Les fichiers :
- jeu.py : la partie (règles, update, draw). C'est le fichier à lancer.
- personnages.py : les classes Robot et Lettre, et la fonction touche.
- donnees.py : la taille de l'écran, les mots, les couleurs.
Ajouter un mot : l'écrire en majuscules dans la liste MOTS, dans donnees.py.
AUTEUR
Pixel, club de code, 2026.
Phrases courtes, une information par ligne, des exemples. Seulement un pseudo : jamais ton nom, ton collège ou ton adresse dans un fichier qu'on partage.
Dans le code lui-même, la documentation, ce sont les docstrings (voir Pro, épisode 13). Une docstring peut aussi se placer tout en haut d'un fichier : elle dit alors à quoi sert le module.
Code
"""Personnages d'Attrape-lettres : le robot, les lettres et la collision."""
import random
La docstring du module vient en premier, avant les imports.
Générateur · mode d'emploi (LISEZMOI.txt)
Texte obtenu
Complète ensuite les lignes en « … ».
[3]Recherche
Ce que disent les sources
Documentation de GitHub — Un README indique en général ce que fait le projet, pourquoi il est utile, comment commencer à l'utiliser, où trouver de l'aide, et qui l'entretient [1].
PEP 257 — Une docstring est une chaîne de caractères placée en première instruction d'un module, d'une fonction, d'une classe ou d'une méthode [2].
PEP 8 — Les imports se placent juste après les commentaires et la docstring du module [3].
[4]Mythes
« Le code se suffit à lui-même. »
le code dit comment le jeu marche, pas comment on y joue ni quel fichier lancer.
« La documentation, c'est à la fin, si on a le temps. »
écrite pendant le projet, elle est plus juste ; écrite à la fin, elle est souvent oubliée.
« Plus un mode d'emploi est long, mieux c'est. »
un visiteur lit quelques lignes ; il faut l'essentiel, au début.
[5]Quiz
1. Où place-t-on la docstring d'un module ?
c'est la première instruction du fichier.
2. Quelle information est destinée au codeur plutôt qu'au joueur ?
le joueur n'a pas besoin de savoir comment le projet est découpé.
3. Que met-on dans la ligne « Auteur » d'un projet qu'on partage ?
aucune donnée personnelle dans un fichier partagé.
[6]Kit
🎒 Ton kit — Épisode 21
25 min
Exercice : le mode d'emploi en deux parties
Remplis le générateur de mode d'emploi avec les informations de ton jeu.
Copie le résultat dans un fichier LISEZMOI.txt, à la racine de ton dossier.
Complète la liste des fichiers et une modification simple qu'un codeur pourrait faire.
Ajoute une docstring en haut de jeu.py, personnages.py et donnees.py.
Code à copier : l'exemple de LISEZMOI.txt ci-dessus, à adapter à ton jeu.
Checklist
Mon LISEZMOI.txt a une partie pour le joueur et une pour le codeur.
Il dit quel fichier lancer.
Chacun de mes modules commence par une docstring.
Vigilanceseulement un pseudo dans le mode d'emploi ; ni nom, ni collège, ni adresse, ni photo.
[7]Journal
✍️ Journal de bord
Quelle est l'information de ton mode d'emploi qui t'a paru la plus évidente… et qui manquerait peut-être le plus à un visiteur ?
Le test du lecteur muet : quelqu'un lance et joue avec ton seul mode d'emploi, et tu observes sans parler.
⏱ 25 min de pratique · 5 min de quiz
[1]Scénario
Malik · Jeudi, 17 h 30
Inès tend une clé avec son dossier et son LISEZMOI.txt à Malik : « Lance-le sans me poser de question. Je n'ai pas le droit de parler. » Malik ouvre le dossier, lit, hésite sur « cliquer sur Exécuter » (il est dans Capytale, le bouton ne s'appelle pas pareil), puis joue. Il perd une vie sans comprendre pourquoi : le mode d'emploi ne dit pas qu'une mauvaise lettre coûte une vie… Inès se mord la langue et note tout.
[2]Méthode
« Le test du lecteur muet »
Rappel : le mode d'emploi en deux parties (voir épisode 21).
Prépare : le dossier rangé, le LISEZMOI.txt, et une feuille d'observation.
Donne seulement le dossier à un camarade qui ne connaît pas ton jeu.
Tais-toi et observe : où il hésite, ce qu'il relit, ce qu'il demande, ce qu'il fait de travers.
Note sans corriger : chaque blocage est une phrase qui manque ou qui est mal dite.
Améliore le mode d'emploi, puis refais le test avec quelqu'un d'autre.
Feuille d'observation
Moment
Ce qu'il fait ou dit
Ce qui manque dans le mode d'emploi
ouvre le dossier
lance le jeu
première partie
fin de partie
[3]Pourquoi ça marche
Toi, tu connais ton jeu par cœur : tu ne vois plus ce qui manque, parce que ton cerveau complète tout seul. Ton camarade, lui, ne peut s'appuyer que sur ce qui est écrit. En te taisant, tu vois exactement ce que vivra un visiteur du stand, quand tu ne seras pas là pour expliquer. C'est la même idée que le plan de test : on joue comme quelqu'un d'autre pour trouver ce qu'on ne voit pas soi-même.
À retenirchaque question posée par ton lecteur est une phrase à ajouter.
[4]Entraînement
Bon réflexe ou piège ?
Mon camarade hésite ; je lui montre le bon fichier.
tu effaces le problème au lieu de le noter ; le visiteur du stand, lui, sera seul.
Je note le moment exact où il bloque.
c'est là qu'il faut compléter le mode d'emploi.
Je choisis quelqu'un qui connaît déjà mon jeu.
il ne lira pas vraiment ; il fera comme d'habitude.
Après les corrections, je refais le test avec une autre personne.
on vérifie que la nouvelle version est claire.
Il a réussi à jouer, donc mon mode d'emploi est parfait.
regarde aussi ce qu'il a deviné ou fait par hasard.
[5]Quiz
1. Pendant le test, ton camarade demande : « Je clique où ? ». Que fais-tu ?
sa question montre une phrase qui manque dans le mode d'emploi.
2. Pourquoi l'auteur d'un jeu voit-il mal ce qui manque dans son propre mode d'emploi ?
le lecteur, lui, n'a que ce qui est écrit.
3. Que fais-tu après avoir corrigé ton mode d'emploi ?
le premier lecteur connaît maintenant le jeu ; il faut un regard neuf.
[6]Kit
🎒 Ton kit — Épisode 22
25 min
Exercice : le test du lecteur muet
Imprime ou recopie la feuille d'observation.
Fais le test avec un camarade qui ne connaît pas ton jeu (10 minutes).
Ajoute ou réécris au moins 3 phrases de ton LISEZMOI.txt.
Refais le test avec une autre personne et compare.
Code à copier : aucun.
Checklist
J'ai observé sans aider.
J'ai noté au moins 3 blocages.
Mon mode d'emploi a été amélioré, puis testé à nouveau.
[7]Journal
✍️ Journal de bord
Quel blocage de ton lecteur t'a le plus surprise ou surpris ? Quelle phrase as-tu ajoutée pour l'éviter ?
Lire de façon critique un code qu'on n'a pas écrit, avant de le lancer.
⏱ 30 min de lecture · 5 min de quiz
[1]Scénario
Inès · Mardi, 12 h 40
La grande sœur de Malik, qui a 20 ans, a demandé à un assistant d'intelligence artificielle une fonction pour afficher le podium des meilleures parties. Elle l'a essayée sur un exemple : « Ça marche ! » Malik arrive au club avec la feuille. Inès la prend, mais ne l'ouvre pas sur l'ordinateur. Elle applique la règle d'or du club : on ne lance pas un code qu'on ne comprend pas. « On le lit d'abord. Ligne par ligne. »
[2]Concept
Lire avant de lancer
Les assistants d'IA ne sont pas faits pour toi, seul. Leurs conditions d'utilisation fixent un âge minimum (vérifiées le 29/10/2026) :
Service
Âge minimum
Avant 18 ans
ChatGPT (OpenAI)
13 ans
accord d'un parent ou d'un tuteur
Claude (Anthropic)
18 ans
non autorisé
Vibe, anciennement Le Chat (Mistral AI)
13 ans
accord d'un parent ou d'un tuteur pour créer un compte
Gemini (Google), compte personnel
13 ans, ou l'âge fixé par le pays
règles particulières pour les comptes d'enfants gérés par un parent
À l'école, le cadre du ministère de l'Éducation nationale (juin 2025) prévoit : pas de manipulation d'IA générative par les élèves avant la 4e ; à partir de la 4e, une utilisation encadrée par l'enseignant, en classe ; et aucun élève ne doit avoir à créer un compte personnel sur un service d'IA grand public.
Dans ce livre, tu n'utilises aucune IA. Tu fais ce qui sert à tout le monde, à tout âge : lire un code qu'on n'a pas écrit soi-même, qu'il vienne d'une IA, d'un site ou d'un camarade.
Le code de la feuille (écrit pour ce livre, à la manière de ce qu'un assistant peut proposer) :
Code
import os
def podium(parties):
"""Renvoie les 3 meilleures parties, de la meilleure à la moins bonne."""
os.system("cls")
parties.sort()
return [parties[-1], parties[-2], parties[-3]]
Une partie est un tuple (score, pseudo), comme à l'arc 1.
La grille de lecture, en 4 questions :
Est-ce que je comprends chaque ligne ? Si une ligne m'est inconnue, je cherche ce qu'elle fait avant de lancer. Ici : os.system("cls"). Le module os permet à Python d'agir sur l'ordinateur ; os.systemexécute une commande du système (ici cls, qui efface l'écran sous Windows). Tu n'as pas à savoir tout cela : tu dois remarquer que tu ne le comprends pas. Une ligne inconnue qui agit sur l'ordinateur, sur des fichiers ou sur Internet → on ne lance pas ; on la montre à un adulte. Ici, elle n'a rien à faire dans un podium : on la retire, avec import os.
Que fait le code aux données qu'on lui donne ?parties.sort()modifie la liste de la personne qui appelle la fonction (voir épisode 7). Après l'appel, l'ordre des parties jouées est perdu.
Et dans les cas limites ? Avec moins de 3 parties, parties[-3] n'existe pas (voir Pro, épisode 6).
Mes propres tests confirment-ils ce que j'ai lu ? Sans la ligne os.system, on teste avec une liste de 5 parties, puis de 2 :
[(12, 'Pixel'), (11, 'Lynx'), (9, 'Nova')]
[(5, 'Comete'), (7, 'Lynx'), (9, 'Nova'), (11, 'Lynx'), (12, 'Pixel')]
Traceback (most recent call last):
…
return [parties[-1], parties[-2], parties[-3]]
IndexError: list index out of range
Le podium est juste sur l'exemple : c'est pour cela que « ça marche ». Mais la liste d'origine a été triée, et avec 2 parties le programme s'arrête.
La version corrigée, avec ce que tu connais :
Code
def podium(parties):
"""Renvoie les 3 meilleures parties (ou moins), de la meilleure à la moins bonne."""
classement = sorted(parties, reverse=True)
resultat = []
for partie in classement:
if len(resultat) < 3:
resultat.append(partie)
return resultat
Avec les mêmes tests : le même podium, la liste d'origine intacte, [(8, 'Pixel'), (6, 'Nova')] pour 2 parties, et [] pour une liste vide (sorties vérifiées). À égalité de score, sorted(…, reverse=True) range les pseudos dans l'ordre alphabétique inverse : (9, 'Pixel') avant (9, 'Nova'). Est-ce ce que tu veux pour ton podium ? C'est à toi de décider, et de le tester.
Dernière règle : dire d'où vient le code. Si tu gardes un code que tu n'as pas écrit, tu l'écris dans un commentaire ou dans le mode d'emploi (« fonction podium : idée proposée par un assistant d'IA à un adulte, relue et corrigée par Pixel »).
[3]Recherche
Ce que disent les sources
OpenAI — Il faut avoir au moins 13 ans, ou l'âge minimum fixé dans son pays ; avant 18 ans, il faut la permission d'un parent ou d'un tuteur légal [1].
Anthropic — Il faut avoir au moins 18 ans, ou l'âge minimum fixé dans son pays s'il est plus élevé [2].
Mistral AI — Il faut avoir au moins 13 ans ; un mineur qui crée un compte doit avoir la permission d'un parent ou d'un tuteur [3]. L'assistant Le Chat s'appelle désormais Vibe [4].
Google — Il faut avoir au moins 13 ans (ou l'âge autorisé dans son pays) pour utiliser Gemini avec un compte Google personnel ; les comptes d'enfants gérés avec Family Link ont des règles à part [5].
Ministère de l'Éducation nationale — Le cadre d'usage de l'IA en éducation (juin 2025) déconseille de faire manipuler des IA génératives aux élèves avant la 4e, prévoit une utilisation encadrée à partir de la 4e, et précise que les élèves ne doivent pas avoir à créer de compte personnel sur un service d'IA grand public [6].
Documentation officielle de Python — os.system exécute une commande dans un interpréteur de commandes du système [7].
[4]Mythes
« Si l'IA l'a écrit, c'est juste. »
un assistant peut proposer un code faux, incomplet ou inutilement risqué ; c'est la personne qui l'utilise qui en est responsable.
« Si ça marche sur un exemple, ça marche toujours. »
le podium était juste sur 5 parties, et faux avec 2.
« Lire du code, c'est moins utile que d'en écrire. »
chaque programmeur passe beaucoup de temps à lire du code écrit par d'autres ; c'est ce qui permet de l'utiliser sans danger.
[5]Quiz
1. Après podium(parties) (version de la feuille, sans os.system), que contient parties ?
parties.sort() a modifié la liste d'origine (sortie vérifiée).
2. Que fait la version de la feuille avec 2 parties seulement ?
parties[-3] n'existe pas dans une liste de 2 éléments (sortie vérifiée).
3. Tu trouves une ligne que tu ne comprends pas et qui agit sur l'ordinateur. Que fais-tu ?
on ne lance jamais un code qu'on ne comprend pas, surtout s'il agit sur l'ordinateur, des fichiers ou Internet.
[6]Kit
🎒 Ton kit — Épisode 23
25 min
Exercice : les 3 problèmes du podium
Lis le code de la feuille avec la grille, sans le lancer. Note les 3 problèmes.
Retire import os et la ligne os.system("cls").
Lance les tests du concept et compare avec la sortie du livre.
Écris la version corrigée et teste-la avec : 5 parties, 2 parties, une liste vide, deux scores égaux.
Ajoute un commentaire qui dit d'où vient la fonction.
Code à copier : la version corrigée et les tests ci-dessus.
Checklist
J'ai trouvé les 3 problèmes avant de lancer.
Ma version corrigée ne modifie pas la liste d'origine et accepte moins de 3 parties.
Je sais pourquoi on ne lance pas une ligne inconnue qui agit sur l'ordinateur.
Vigilancen'utilise pas d'assistant d'IA seul. Si un adulte t'en montre un, lis avec lui le code proposé, avec la grille.
[7]Journal
✍️ Journal de bord
Avant cet épisode, aurais-tu lancé le code de la feuille ? Qu'est-ce qui t'aurait fait douter ?
Ton outil de synthèse, le récapitulatif de l'arc et ton badge.
⏱ 30 min · arbre de décision · carrousel · quiz final
[1]Scénario
Inès · Jeudi, 12 h 40
Le professeur de technologie a copié le dossier d'Attrape-lettres sur les ordinateurs du stand. Il n'a posé qu'une question : « C'est bien jeu.py qu'on lance ? » Tout le reste était dans le LISEZMOI.txt. Malik, lui, a ajouté trois mots au jeu sans demander d'aide : il savait dans quel fichier aller. Il y a un mois, le jeu tenait dans un seul fichier de 150 lignes que personne d'autre n'osait toucher.
[2]Outil
« Avant de lancer un code que je n'ai pas écrit »
Aide à la décision interactive
[3]Carrousel
🎨 Carrousel récapitulatif — Arc 3
MASTER · ARC 3 · 1/5
Un projet bien rangé
Quatre semaines pour qu'un autre puisse lire, lancer et améliorer ton jeu.
2/5
Les modules
chaque fichier .py est un module
import module puis module.nom, ou from module import nom
même dossier
un module, un rôle
3/5
Le dossier
un dossier par projet
un seul fichier à lancer
des noms en minuscules, sans espace ni tiret
les anciennes versions à part
4/5
Le mode d'emploi
deux lecteurs, le joueur et le codeur
un LISEZMOI.txt testé par un lecteur muet
une docstring en haut de chaque module
5/5
Lire avant de lancer
comprendre chaque ligne, regarder ce que le code fait aux données, tester les cas limites, dire d'où vient le code. Arc suivant : apprendre seule et transmettre.
[4]Quiz final
1. Dans jeu.py, on écrit import donnees. Comment lire la liste des mots ?
avec import donnees, on écrit le nom du module, un point, puis le nom.
2. Quel nom de fichier pose problème pour un module ?
import mes-mots donne une SyntaxError (testé).
3. ImportError: cannot import name 'touches' from 'personnages'. Que vérifier ?
le fichier est trouvé ; c'est le nom importé qui n'existe pas.
4. Ton lecteur muet ne trouve pas quel fichier lancer. Que fais-tu ?
chaque blocage est une phrase à ajouter au mode d'emploi.
5. Une fonction trouvée ailleurs marche sur ton exemple. Que manque-t-il avant de la garder ?
marcher sur un exemple ne veut pas dire marcher toujours (épisode 23).
[5]Kit
🎒 Ton kit de fin d'arc
30 min
Le projet complet, relu et documenté
Synthèse : Attrape-lettres en trois modules, chacun avec sa docstring, et son mode d'emploi.
"""Données d'Attrape-lettres : taille de l'écran, lettres, mots et couleurs."""
import pyxel
LARGEUR = 160
HAUTEUR = 120
ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
MOTS = ["CHAT", "LUNE", "ROBOT", "PIRATE"]
COULEUR_FOND = pyxel.COLOR_NAVY
COULEUR_ROBOT = pyxel.COLOR_LIME
COULEUR_LETTRE = pyxel.COLOR_YELLOW
Code à copier — personnages.py
Code à copier
"""Personnages d'Attrape-lettres : le robot, les lettres et la collision."""
import random
import pyxel
from donnees import LARGEUR, HAUTEUR, COULEUR_ROBOT, COULEUR_LETTRE
class Robot:
def __init__(self, x):
self.x = x
self.y = 108
self.largeur = 16
self.hauteur = 8
self.vies = 3
self.score = 0
def deplacer(self, dx):
"""Déplace le robot de dx pixels, sans sortir de l'écran."""
self.x = self.x + dx
if self.x < 0:
self.x = 0
if self.x > LARGEUR - self.largeur:
self.x = LARGEUR - self.largeur
def dessiner(self):
"""Dessine le robot à sa position."""
pyxel.rect(self.x, self.y, self.largeur, self.hauteur, COULEUR_ROBOT)
class Lettre:
def __init__(self, caractere, x, vitesse):
self.caractere = caractere
self.x = x
self.y = 0
self.largeur = 4
self.hauteur = 6
self.vitesse = vitesse
def tomber(self):
"""Fait descendre la lettre de sa vitesse."""
self.y = self.y + self.vitesse
def est_tombee(self):
"""Renvoie True si la lettre est sortie par le bas de l'écran."""
return self.y > HAUTEUR
def repartir(self, caractere):
"""Remet la lettre en haut, à une place au hasard, avec un nouveau caractère."""
self.caractere = caractere
self.x = random.randint(0, LARGEUR - self.largeur)
self.y = 0
def dessiner(self):
"""Dessine la lettre à sa position."""
pyxel.text(self.x, self.y, self.caractere, COULEUR_LETTRE)
def touche(a, b):
"""Renvoie True si les rectangles des objets a et b se chevauchent."""
return (a.x < b.x + b.largeur and b.x < a.x + a.largeur
and a.y < b.y + b.hauteur and b.y < a.y + a.hauteur)
Code à copier — jeu.py (le fichier à lancer)
Code à copier
"""Attrape-lettres : la partie (règles, update, draw). C'est le fichier à lancer."""
import random
import pyxel
from donnees import LARGEUR, HAUTEUR, ALPHABET, MOTS, COULEUR_FOND
from personnages import Robot, Lettre, touche
def afficher_mot(mot, trouvees):
"""Renvoie le mot avec un tiret à la place de chaque lettre pas encore trouvée."""
affichage = ""
for lettre in mot:
if lettre in trouvees:
affichage = affichage + lettre + " "
else:
affichage = affichage + "_ "
return affichage.strip()
def mot_trouve(mot, trouvees):
"""Renvoie True si toutes les lettres du mot ont été trouvées."""
for lettre in mot:
if lettre not in trouvees:
return False
return True
class Jeu:
def __init__(self):
pyxel.init(LARGEUR, HAUTEUR, title="Attrape-lettres")
self.mot = random.choice(MOTS)
self.trouvees = []
self.robot = Robot(72)
self.lettres = []
for i in range(3):
lettre = Lettre(self.nouveau_caractere(), 0, random.randint(1, 2))
lettre.repartir(lettre.caractere)
lettre.y = -30 * i
self.lettres.append(lettre)
self.etat = "jeu"
pyxel.run(self.update, self.draw)
def nouveau_caractere(self):
"""Une fois sur deux, une lettre utile du mot ; sinon, une lettre au hasard."""
manquantes = []
for lettre in self.mot:
if lettre not in self.trouvees:
manquantes.append(lettre)
if len(manquantes) > 0 and random.randint(1, 2) == 1:
return random.choice(manquantes)
return random.choice(ALPHABET)
def update(self):
if self.etat != "jeu":
return
if pyxel.btn(pyxel.KEY_LEFT):
self.robot.deplacer(-2)
if pyxel.btn(pyxel.KEY_RIGHT):
self.robot.deplacer(2)
for lettre in self.lettres:
lettre.tomber()
if touche(self.robot, lettre):
if lettre.caractere in self.mot:
if lettre.caractere not in self.trouvees:
self.trouvees.append(lettre.caractere)
self.robot.score = self.robot.score + 1
else:
self.robot.vies = self.robot.vies - 1
lettre.repartir(self.nouveau_caractere())
elif lettre.est_tombee():
lettre.repartir(self.nouveau_caractere())
if mot_trouve(self.mot, self.trouvees):
self.etat = "gagné"
elif self.robot.vies == 0:
self.etat = "perdu"
def draw(self):
pyxel.cls(COULEUR_FOND)
pyxel.text(5, 5, afficher_mot(self.mot, self.trouvees), pyxel.COLOR_WHITE)
pyxel.text(110, 5, f"Vies : {self.robot.vies}", pyxel.COLOR_PINK)
for lettre in self.lettres:
lettre.dessiner()
self.robot.dessiner()
if self.etat == "gagné":
pyxel.text(55, 55, "GAGNE !", pyxel.COLOR_LIME)
elif self.etat == "perdu":
pyxel.text(40, 55, f"PERDU ! C'etait {self.mot}", pyxel.COLOR_RED)
Jeu()
Le LISEZMOI.txt est celui de l'épisode 21, avec les améliorations de ton test du lecteur muet.
Vérifié : ces trois fichiers ont joué les mêmes 9 parties que la première version de l'arc 2 (même tirage au hasard), avec Pyxel 2.9.9, sous Python 3.12.13 et 3.15.0 : état final identique pour chaque partie (positions, lettres, vies, score, fin gagnée ou perdue), et écran identique au pixel près.
Consigne : vérifie ton propre projet avec l'auto-diagnostic « Mon projet est-il rangé ? », rejoue le plan de test, puis fais lire ton LISEZMOI.txt à une personne nouvelle. Exporte ensuite ton carnet de bord.
Checklist
J'ai exporté mon carnet (bouton dans le menu).
Mon projet tient en trois modules documentés, avec un seul fichier à lancer.
Mon mode d'emploi a passé le test du lecteur muet.
[6]Journal
✍️ Journal de bord — bilan
Qu'est-ce qui a le plus changé dans ta façon de travailler sur ton projet pendant cet arc ? Que referais-tu dès le début, la prochaine fois ?
✦ ARCHITECTE DE PROJET · ARC 3 ✦
Bravo ! Tu as terminé l'arc 3. Tu sais découper un projet en modules, ranger son dossier, écrire son mode d'emploi et lire un code avant de le lancer.
ARC 4 · SEMAINES 13 À 16
Apprendre seule et transmettre
Le livre va bientôt se refermer, mais ton projet continue. En quatre semaines, tu apprends à trouver seule ou seul tes réponses, à demander de l'aide quand il le faut, puis à expliquer ton jeu et à faire coder les plus jeunes.
Semaine 13 · La documentation
25
S13 · MARDI · Comprendre
Lire la documentation officielle
Trouver soi-même une réponse dans la documentation de Python et de Pyxel, et lire une fiche de fonction.
⏱ 25 min de lecture · 5 min de quiz
[1]Scénario
Inès · Mardi, 12 h 40
Inès veut qu'Attrape-lettres joue une petite musique quand on attrape une bonne lettre. L'animatrice est absente cette semaine. Elle a laissé un mot sur le tableau : « La réponse est dans la documentation. » Malik grimace : « La documentation, c'est pour les experts. » Inès ouvre quand même la page. Elle a déjà lu des docstrings (Pro, épisode 13) : une documentation, c'est la même chose, en plus grand.
[2]Concept
La documentation, mode d'emploi des outils
1. Où la trouver. Chaque outil sérieux a une documentation officielle, écrite par ceux qui le fabriquent :
Python : docs.python.org, avec une version en français (traduite en partie seulement : certains titres restent en anglais). En haut de la page, un menu permet de choisir la version de Python : prends celle que tu utilises.
Pyxel : la page du projet (github.com/kitao/pyxel) renvoie vers un guide en ligne (User Guide) ; Pyxel est aussi livré avec des exemples officiels, de vrais programmes à lancer (par exemple 04_sound_api.py pour le son).
2. Comment elle est rangée. La page d'accueil de la documentation de Python propose notamment :
Rubrique
Pour quoi faire
Tutoriel
apprendre pas à pas (tu y es déjà allée pour les modules et les classes)
Référence des fonctions natives (Built-ins reference)
print, len, sorted…
Référence de la bibliothèque
les modules fournis avec Python : random, math…
Glossaire, FAQ, recherche
un mot inconnu, une question fréquente
3. Lire une fiche de fonction. Voici la fiche de random.choice, dans la documentation en français :
random.choice(seq) — Renvoie un élément aléatoire de la séquence non vide seq. Si seq est vide, lève IndexError.
Dans la fiche
Ce que ça veut dire
random.choice
le nom : la fonction choice du module random
(seq)
le paramètre : une séquence (une liste, une chaîne…)
« Renvoie un élément aléatoire »
ce qu'elle renvoie
« non vide », « lève IndexError »
le cas limite : avec une liste vide, le programme s'arrête
4. Tester l'exemple tel quel, puis adapter.
Code
import random
print(random.choice(["CHAT", "LUNE", "ROBOT"]))
print(random.choice([]))
La première ligne affiche un des trois mots (ici LUNE) ; la deuxième s'arrête avec IndexError: Cannot choose from an empty sequence, exactement comme la fiche l'annonce.
5. La documentation est aussi dans Python. Dans la console, help(random.choice) affiche la docstring de la fonction (en anglais) : Choose a random element from a non-empty sequence. C'est le même help que pour tes propres fonctions (voir Pro, épisode 13).
6. Se méfier des copies. Beaucoup de sites recopient ou résument la documentation, parfois pour une ancienne version, parfois avec des erreurs ou de la publicité. Vérifie l'adresse : docs.python.org pour Python, la page du projet pour Pyxel.
Pour la fiche de Pyxel, la même méthode marche en anglais : play(ch, snd) — Play the sound snd on channel ch (0-3) : « joue le son snd sur le canal ch (de 0 à 3) ». Les mots à connaître : play (jouer), sound (son), channel (canal), returns (renvoie), default (valeur par défaut).
[3]Recherche
Ce que disent les sources
Documentation officielle de Python — La page d'accueil (version 3.15, en français) donne accès au tutoriel, à la référence des fonctions natives, à la référence de la bibliothèque et du langage, aux guides pratiques (HOWTO), aux FAQ et au glossaire ; plusieurs titres restent en anglais [1].
Documentation officielle de Python — random.choice(seq) « renvoie un élément aléatoire de la séquence non vide seq ; si seq est vide, lève IndexError » [2].
Pyxel 2.9.9 — La présentation du projet renvoie vers un guide utilisateur en ligne et vers des exemples d'utilisateurs ; le paquet contient des exemples officiels numérotés, dont 04_sound_api.py ; la fonction play(ch, snd) joue le son snd sur le canal ch (0 à 3) [3].
Tests de ce livre — L'exemple de random.choice et help(random.choice) ont été exécutés sous Python 3.12.13 et 3.15.0 : mêmes sorties (journal de test).
[4]Mythes
« La documentation, c'est pour les experts. »
les fiches suivent toutes le même plan (nom, paramètres, ce qui est renvoyé, cas limites) ; une fois ce plan connu, tu peux en lire n'importe laquelle.
« Une vidéo trouvée au hasard vaut la documentation. »
une vidéo peut être ancienne ou fausse ; la documentation officielle correspond à la version que tu utilises.
« Si c'est en anglais, je ne peux pas comprendre. »
une fiche utilise toujours les mêmes quelques mots (returns, default…) et, surtout, du code que tu sais lire.
[5]Quiz
1. D'après sa fiche, que fait random.choice([]) ?
la fiche le dit, et le test le confirme (sortie vérifiée).
2. Où trouver la fiche de len dans la documentation de Python ?
len est une fonction native, toujours disponible sans import.
3. Tu trouves la réponse sur un site inconnu qui recopie la documentation. Que fais-tu ?
la source officielle correspond à ta version et n'a pas d'erreurs de copie.
[6]Kit
🎒 Ton kit — Épisode 25
20 min
Exercice : trois réponses dans la documentation
Python : dans la documentation en français, trouve la fiche de random.randint. Les deux bornes sont-elles comprises ? Écris un test qui le vérifie.
Pyxel : trouve ce que fait pyxel.btnp, et en quoi il diffère de pyxel.btn (épisode 14).
Un exemple : dans les exemples officiels de Pyxel, trouve celui qui joue des sons. Note les deux fonctions qu'il utilise pour préparer puis jouer un son.
Code à copier : l'exemple de random.choice ci-dessus.
Checklist
J'ai trouvé les 3 réponses dans des documentations officielles.
J'ai testé l'exemple d'une fiche tel quel avant de l'adapter.
Je sais lire le nom, les paramètres, ce qui est renvoyé et le cas limite d'une fiche.
Vigilancen'installe rien et ne télécharge rien depuis un site qui « explique » Python. La documentation se lit, elle ne s'installe pas.
[7]Journal
✍️ Journal de bord
Qu'as-tu ressenti en trouvant une réponse seule ou seul ? Qu'est-ce qui a été le plus difficile dans la fiche ?
T. Kitao, Pyxel 2.9.9 (pypi.org/project/pyxel, 12/08/2026), présentation, documentation des fonctions et exemples livrés avec le paquet, consulté le 29/10/2026.
26
S13 · JEUDI · Pratiquer
Ajouter une fonction grâce à la documentation
Ajouter des sons à Attrape-lettres en lisant uniquement la documentation de Pyxel.
⏱ 25 min de pratique · 5 min de quiz
[1]Scénario
Inès · Jeudi, 17 h 30
Inès a trouvé l'exemple officiel 04_sound_api.py. Il joue toute une musique, avec quatre canaux, des boutons et des notes qui défilent. « Je ne veux pas tout ça. Je veux juste un petit ding. » Elle cherche dans l'exemple les deux lignes qui comptent : celle qui prépare le son, et celle qui le joue.
[2]Méthode
« Chercher, essayer l'exemple, adapter, tester »
Rappel : lire une fiche de fonction (voir épisode 25).
Chercher : dans la documentation et l'exemple, deux outils : pyxel.sounds[0].set(…) prépare le son n° 0 ; pyxel.play(0, 0) le joue sur le canal 0.
Essayer l'exemple à part, dans un petit programme, avant de toucher au jeu.
Adapter : garder seulement ce qu'il faut, et le mettre au bon endroit (épisode 16 : préparer dans __init__, réagir dans update).
Tester : le jeu doit se jouer exactement comme avant, avec du son en plus.
Lire set dans la documentation : set(notes, tones, volumes, effects, speed).
Paramètre
Notre choix
Ce que dit la documentation
notes
"c3e3g3c4"
les notes : un nom (C, D, E, F, G, A, B, c'est-à-dire do, ré, mi, fa, sol, la, si) suivi d'une octave
tones
"p"
le timbre : T (triangle), S (carré), P (pulsation), N (bruit)
volumes
"7"
le volume, de 0 à 7
effects
"n"
l'effet : N (aucun), F (fondu)…
speed
5
la vitesse : 1 est le plus rapide ; à 120, une note dure une seconde
Si les timbres, volumes ou effets sont plus courts que les notes, ils se répètent : "7" vaut pour les quatre notes.
Le jeu avec deux sons (dans jeu.py, trois ajouts) :
Code
def __init__(self):
pyxel.init(LARGEUR, HAUTEUR, title="Attrape-lettres")
pyxel.sounds[0].set("c3e3g3c4", "p", "7", "n", 5) # bonne lettre
pyxel.sounds[1].set("f2c2", "n", "7", "f", 10) # mauvaise lettre
# … la suite de __init__ ne change pas
et, dans update :
Code
if touche(self.robot, lettre):
if lettre.caractere in self.mot:
if lettre.caractere not in self.trouvees:
self.trouvees.append(lettre.caractere)
self.robot.score = self.robot.score + 1
pyxel.play(0, 0)
else:
self.robot.vies = self.robot.vies - 1
pyxel.play(0, 1)
Vérifié :
les notes enregistrées sont [36, 40, 43, 48] (do, mi, sol, do) ; chaque son dure 0,167 seconde ;
le son n° 0, enregistré dans un fichier audio et analysé, contient bien quatre notes montantes (environ 523, 659, 784 et 1 045 Hz) ;
sur 9 parties, le jeu avec sons a exactement le même état final que la version de l'arc 3 ; sur une partie gagnée, pyxel.play(0, 0) a été appelé 4 fois (une par lettre du mot) ; sur une partie perdue, pyxel.play(0, 1) a été appelé 3 fois (une par vie perdue).
Remets les lignes dans l'ordre · clique les lignes une par une
Ton programme
Lignes à placer
[3]Pourquoi ça marche
Un exemple officiel est un programme qui marche, mais il en fait souvent beaucoup plus que ce que tu cherches. En l'essayant à part, tu vois ce que fait chaque ligne ; en n'en gardant que deux, tu sais exactement ce que tu ajoutes à ton jeu. Et comme les sons sont préparés une seule fois dans __init__ puis joués dans update, ils suivent la même règle que tout le reste du jeu : préparer d'abord, réagir ensuite.
À reteniron essaie l'exemple à part, on garde le minimum, on le range au bon endroit, et on rejoue le plan de test.
[4]Entraînement
Bon réflexe ou piège ?
Je copie tout l'exemple officiel dans mon jeu.
tu ajoutes du code que tu ne comprends pas et dont tu n'as pas besoin.
J'essaie set et play dans un petit programme à part.
si ça ne marche pas, le problème n'est pas dans ton jeu.
Je prépare le son dans update, à chaque image.
il suffit de le préparer une fois, dans __init__.
Je vérifie dans la documentation ce que veut dire chaque paramètre.
tu sais ce que tu changes quand tu changes un nombre.
Après avoir ajouté les sons, je rejoue tout le plan de test.
un ajout ne doit rien casser.
[5]Quiz
1. Que fait pyxel.play(0, 1) ?
d'après la documentation, play(ch, snd) joue le son snd sur le canal ch.
2. Le son doit être plus lent. Quel paramètre de set changes-tu ?
1 est le plus rapide ; plus le nombre est grand, plus le son est lent.
3. Où préparer les sons avec set ?
on les prépare une fois, au démarrage, comme dans l'exemple officiel.
[6]Kit
🎒 Ton kit — Épisode 26
25 min
Exercice : un jeu qui chante
Dans un petit programme à part, prépare et joue un son de quatre notes. Écoute-le.
Ajoute les deux sons à jeu.py (trois ajouts ci-dessus).
Joue une partie gagnée et une partie perdue : chaque bonne lettre fait ding, chaque mauvaise fait bzz.
Change les notes ou la vitesse en t'aidant seulement de la documentation.
Bonus : un deuxième niveau. Quand le mot est trouvé, au lieu de finir, tire un nouveau mot et fais tomber les lettres plus vite. Cherche dans ton propre code ce qu'il faut changer (self.mot, self.trouvees, la vitesse des lettres).
Code à copier : les trois ajouts ci-dessus.
Checklist
J'ai essayé les sons à part avant de les mettre dans le jeu.
Je sais ce que veut dire chaque paramètre de set.
Mon jeu se joue comme avant, avec des sons en plus.
Vigilanceau club ou en classe, baisse le volume ou utilise un casque.
[7]Journal
✍️ Journal de bord
Quelle information as-tu trouvée seule ou seul dans la documentation ? Où as-tu hésité ?
[8]Sources
T. Kitao, Pyxel 2.9.9, documentation de play, sounds et Sound.set, exemple 04_sound_api.py, consulté le 29/10/2026. (pypi.org/project/pyxel)
Semaine 14 · Demander et donner de l'aide
27
S14 · MARDI · Comprendre
Poser une bonne question
Avant de demander, chercher ; puis réduire le problème à un exemple minimal et poser une question qu'on peut aider.
⏱ 25 min de lecture · 5 min de quiz
[1]Scénario
Malik · Mardi, 12 h 40
Mardi soir, Inès reçoit un message de Malik : « mon jeu marche pas, aide ». Elle répond : « Qu'est-ce qui ne marche pas ? » Pas de réponse. Le lendemain, au club, elle découvre le problème : Malik a ajouté le mot « lune » à sa liste, et il ne peut jamais le gagner. Aucune erreur, aucun message rouge. Avec une bonne question, elle aurait pu l'aider dès la veille.
[2]Concept
Chercher, réduire, demander
1. Avant de demander, chercher. Relis le message d'erreur s'il y en a un (voir Boost, épisode 2) ; s'il n'y en a pas, c'est un bug silencieux : reproduis-le et affiche les valeurs (voir Pro, épisode 16). Souvent, la réponse apparaît à ce moment-là.
2. Réduire à un exemple minimal. Un exemple minimal est un programme le plus court possible qui montre encore le problème. On enlève tout ce qui n'y est pour rien : Pyxel, le robot, les vies… Pour le bug de Malik :
Code
mot = "lune"
trouvees = []
caractere = "L"
if caractere in mot:
trouvees.append(caractere)
print(trouvees)
Affiche [] : la lettre « L » n'est jamais trouvée. En réduisant, on voit la cause : "L" (majuscule) n'est pas dans "lune" (minuscules). Les lettres qui tombent sont tirées dans ALPHABET, en majuscules ; le mot doit donc être écrit en majuscules dans donnees.py, comme le dit le mode d'emploi (épisode 21). Six lignes suffisent, et souvent, en écrivant l'exemple minimal, on trouve soi-même la réponse.
3. Poser la question en 4 parties.
Partie
Pour Malik
Ce que je voulais
ajouter le mot « lune » et pouvoir le gagner
Ce que j'ai fait
j'ai ajouté "lune" à MOTS ; voici mon exemple minimal (6 lignes)
Ce qui se passe
aucune erreur, mais la lettre L n'est jamais comptée : print(trouvees) affiche []
Ce que j'ai déjà essayé
j'ai rejoué trois parties et vérifié que le robot touche bien la lettre
Le message d'erreur, quand il y en a un, se copie en entier, sans le résumer.
4. À qui demander. À ton professeur, à l'animatrice ou à l'animateur du club, à un camarade, à un adulte. Ne publie pas ta question sur un forum ou un réseau sans un adulte, et ne mets jamais dans une question ton nom, ton collège ou une photo.
Générateur · ma question en 4 parties
Texte obtenu
Ajoute ton exemple minimal sous le message. Aucun nom, aucun collège, aucune photo.
[3]Recherche
Ce que disent les sources
Communauté Python Discord — Une bonne question donne un exemple de code qui montre le problème, de préférence minimal plutôt que tout le programme ; le message d'erreur complet ; ce qu'on a déjà essayé ; les symptômes dans l'ordre où ils apparaissent, plutôt que ses suppositions sur la cause ; et le but recherché, pas seulement l'étape qui bloque [1].
Communauté Python Discord — Il ne faut pas raccourcir le message d'erreur : on risque d'enlever l'information qui permet de résoudre le problème [1].
Tests de ce livre — L'exemple minimal de Malik affiche [] sous Python 3.12.13 et 3.15.0 (journal de test).
[4]Mythes
« Demander de l'aide, c'est avouer qu'on est nul. »
tous les programmeurs demandent de l'aide ; ce qui compte, c'est de poser une question qu'on peut aider.
« Plus j'envoie de code, mieux on pourra m'aider. »
150 lignes, personne ne les lira ; 6 lignes qui montrent le problème, oui.
« Je résume le message d'erreur, c'est plus clair. »
on le copie en entier : le détail utile est souvent dans la partie qu'on aurait coupée.
[5]Quiz
1. Qu'est-ce qu'un exemple minimal ?
on enlève tout ce qui n'y est pour rien, et on garde le problème.
2. Pourquoi "L" in "lune" vaut-il False ?
pour Python, une majuscule et une minuscule ne sont pas le même caractère (sortie vérifiée).
3. Que mets-tu dans ta question, en plus de ton exemple minimal ?
ce sont les 4 parties d'une bonne question, sans donnée personnelle.
[6]Kit
🎒 Ton kit — Épisode 27
25 min
Exercice : de 150 lignes à 6
Prends un bug de ton jeu (ou celui de Malik).
Copie ton projet dans un dossier d'essai, puis enlève morceau par morceau tout ce qui n'y est pour rien, en vérifiant à chaque fois que le problème est encore là.
Arrête-toi quand tu ne peux plus rien enlever : c'est ton exemple minimal.
Remplis le générateur de question avec tes 4 parties.
As-tu trouvé la réponse en chemin ? Note-le dans ton journal.
Code à copier : l'exemple minimal de Malik.
Checklist
Mon exemple minimal tient en moins de 10 lignes et montre encore le problème.
Ma question a ses 4 parties.
Elle ne contient aucune donnée personnelle.
[7]Journal
✍️ Journal de bord
En réduisant ton bug, as-tu trouvé la réponse avant même de poser la question ? À quel moment ?
Aider sur un bug avec des questions, sans donner la réponse ni prendre le clavier.
⏱ 25 min de pratique · 5 min de quiz
[1]Scénario
Inès · Jeudi, 17 h 30
Nova, qui vient d'arriver au club, est bloquée : dans son jeu, les lettres disparaissent en bas de l'écran, puis plus rien pendant un moment, avant qu'elles réapparaissent en haut. Inès voit tout de suite la ligne fautive. Elle a envie de prendre le clavier. Elle garde les mains dans les poches : « Je vais te poser des questions. C'est toi qui vas trouver. »
[2]Méthode
« Aider sans faire à la place »
Rappels : la chasse aux bugs (voir Pro, épisode 16) ; la bonne question (voir épisode 27).
Faire décrire : « Qu'est-ce que tu attendais ? Qu'est-ce qui se passe ? »
Faire reproduire : « Peux-tu me le montrer ? Ça arrive à chaque fois ? »
Faire afficher : « Que vaut y à ce moment-là ? Comment le savoir ? »
Faire chercher l'endroit : « Quelle ligne décide que la lettre est tombée ? Que compare-t-elle ? »
Laisser corriger : la personne aidée tape la correction elle-même, et la teste.
Le bug de Nova, réduit à un test en console :
Code
from personnages import Lettre
lettre = Lettre("A", 50, 40)
for tour in range(1, 6):
lettre.tomber()
print(tour, lettre.y, lettre.est_tombee())
Avec le bon fichier, la ligne 4 affiche 4 160 True. La lettre de Nova repart un tour trop tard, parce que sa méthode est_tombee compare y à la largeur de l'écran (160) au lieu de sa hauteur (120) : return self.y > LARGEUR. Avec une vitesse plus lente, ce tour de trop devient un long moment sans lettre.
Au lieu de dire…
… demande
« C'est la ligne 47. »
« Quelle méthode décide que la lettre est tombée ? »
« Remplace LARGEUR par HAUTEUR. »
« À quoi compares-tu y ? Combien mesure l'écran en hauteur ? »
« Pousse-toi, je vais le faire. »
« Tu veux essayer de changer cette ligne et relancer ? »
[3]Pourquoi ça marche
Quand quelqu'un trouve lui-même la ligne fautive, il comprend pourquoi elle était fausse, et il saura chercher la prochaine fois. Si tu donnes la réponse, le bug est corrigé, mais la méthode n'est pas apprise. Les questions suivent les étapes de la chasse aux bugs : décrire, reproduire, afficher, isoler, corriger. En les posant, tu montres la méthode sans la réciter.
À retenircelui qui tape la correction, c'est celui qui apprend.
[4]Entraînement
Bon réflexe ou piège ?
Je prends le clavier, ça ira plus vite.
le bug est corrigé, mais ton camarade n'a rien appris.
Je lui demande ce qu'il attendait et ce qui se passe.
c'est la première étape pour comprendre le problème.
Je lui demande d'afficher la valeur de y à chaque tour.
il voit lui-même où le programme s'écarte de ce qu'il attend.
Je lui dis : « C'est facile, pourtant ! »
ça décourage, et ça n'aide pas à trouver.
Quand il a trouvé, je lui demande de rejouer le plan de test.
une correction se vérifie toujours.
[5]Quiz
1. Dans le bug de Nova, à quel tour la lettre est-elle considérée comme tombée ?
y doit dépasser 160 (la largeur) au lieu de 120 : c'est le cas au tour 5, à y = 200 (sortie vérifiée).
2. Quelle question aide le mieux sans donner la réponse ?
la question guide vers la ligne, sans faire la correction à sa place.
3. Qui tape la correction ?
celui qui tape la correction est celui qui apprend.
[6]Kit
🎒 Ton kit — Épisode 28
25 min
Exercice : jeu de rôle à deux
Par deux : l'un reçoit le personnages.py de Nova (avec return self.y > LARGEUR), l'autre ne le regarde pas.
Celui qui aide n'a droit qu'aux questions de la méthode ; il ne touche pas le clavier.
Quand le bug est trouvé et corrigé, échangez les rôles avec un autre bug : dans deplacer, remplacez self.x = self.x + dx par self.x = self.x - dx (le robot part à l'envers : Robot(72) puis deplacer(2) donne x = 70).
Notez ensemble les questions qui ont le plus aidé.
Code à copier : le test en console ci-dessus.
Checklist
J'ai aidé sans toucher le clavier.
La personne aidée a trouvé et tapé la correction.
J'ai noté les 3 questions qui ont le mieux marché.
[7]Journal
✍️ Journal de bord
Était-ce plus difficile d'aider sans donner la réponse, ou d'être aidé sans la recevoir ? Pourquoi ?
Sortie du test : exécution réelle sous Python 3.12.13 et 3.15.0 (journal de test de ce livre), le 29/10/2026.
Semaine 15 · Expliquer son code
29
S15 · MARDI · Comprendre
Expliquer son code
Présenter un programme à quelqu'un qui ne l'a pas écrit : du « quoi » au « comment », avec un schéma.
⏱ 25 min de lecture · 5 min de quiz
[1]Scénario
Inès · Mardi, 12 h 40
Le principal passe au club : pour les portes ouvertes, chaque élève du stand expliquera son jeu en 3 minutes, aux parents comme aux élèves de CM2. Malik se lance pour essayer : « Alors, il y a une classe Robot avec un __init__ et un attribut self.x… » Au bout d'une minute, le principal a décroché. Il n'a toujours pas vu le jeu.
[2]Concept
Expliquer, du quoi au comment
1. Montrer avant d'expliquer. Commence par jouer 20 secondes. Ton public comprend le but sans un mot.
2. Le « quoi » : ce que fait le jeu, en une phrase, sans aucun mot de code : « Un robot attrape les lettres d'un mot caché ; une mauvaise lettre fait perdre une vie. »
3. Le « comment » : les grandes pièces, avec un schéma :
Schéma du projet
jeu.py ← le chef d'orchestre : les règles, 30 images par seconde
/ \
personnages.py donnees.py
le robot, les mots,
les lettres, les couleurs,
la collision la taille de l'écran
« Le robot et les lettres sont des objets : chacun sait se déplacer et se dessiner. Trente fois par seconde, le jeu les fait bouger, vérifie s'ils se touchent, puis redessine l'écran. »
4. Un détail choisi, pas tous : par exemple la collision (deux rectangles qui se chevauchent, quatre comparaisons). Un seul détail bien expliqué vaut mieux que dix survolés.
5. Adapter les mots au public.
Public
Ce qu'il veut savoir
Exemple de mots
élève de CM2
comment on joue, est-ce difficile à faire ?
« le robot », « les lettres tombent », « on l'a programmé en tapant du texte »
parent
qu'est-ce que mon enfant apprendrait ?
« des objets », « découper un projet », « tester »
Je dis ce que fait le jeu en une phrase, sans mot de code.
J'ai un schéma des grandes pièces.
Je n'explique en détail qu'une seule chose.
Mes mots sont adaptés à mon public.
Ma présentation tient en 3 minutes, chronométrées.
[3]Recherche
Ce que disent les sources
Documentation de GitHub — Un README commence par ce que fait le projet et pourquoi il est utile, avant d'expliquer comment s'en servir : le même ordre que le « quoi » puis le « comment » [1].
Brevet 2027 — L'épreuve orale de soutenance est maintenue pour la session 2027 ; chaque collège l'organise [2]. Savoir présenter un projet en quelques minutes te servira donc aussi en 3e.
[4]Mythes
« Pour bien expliquer, il faut tout dire. »
en 3 minutes, on choisit ; le public retient une idée claire, pas dix.
« Les mots techniques font plus sérieux. »
un mot que le public ne connaît pas l'arrête net ; on l'explique ou on l'évite.
« Si je connais mon code, je saurai l'expliquer sans m'entraîner. »
expliquer s'apprend comme coder : en répétant (épisode 30).
[5]Quiz
1. Par quoi commencer une présentation de ton jeu ?
montrer d'abord donne le but sans un mot.
2. Un élève de CM2 demande comment marche le jeu. Quelle réponse lui convient ?
la même idée, avec des mots qu'il connaît.
3. Combien de détails techniques expliquer en 3 minutes ?
un détail bien expliqué montre comment le jeu est construit, sans perdre le public.
[6]Kit
🎒 Ton kit — Épisode 29
25 min
Exercice : ta présentation de 3 minutes
Écris la phrase du « quoi » (sans aucun mot de code).
Dessine le schéma de ton projet (fichiers et objets).
Choisis ton détail, et prépare 2 phrases pour l'expliquer.
Remplis le plan des 3 minutes, puis chronomètre-toi seule ou seul.
Digischool, Brevet 2027 : ce qui change, d'après le calendrier publié au Bulletin officiel spécial n° 2 du 25 août 2026, consulté le 29/10/2026.
30
S15 · JEUDI · Pratiquer
Répéter sa présentation
Deux essais, deux retours : présenter à des camarades et tenir compte de ce qu'ils disent.
⏱ 25 min de pratique · 5 min de quiz
[1]Scénario
Inès · Jeudi, 17 h 30
Inès présente Attrape-lettres à Malik et à Nova. Chronomètre : 4 minutes 30. Nova : « J'ai adoré le schéma. Mais je n'ai pas compris ce que c'était, un objet. » Malik : « Tu as parlé du son, de la collision et des modules : c'était trop. » Inès note tout, coupe le son et les modules, garde la collision. Deuxième essai : 2 minutes 55.
Deux retours par personne, toujours dans cet ordre : une chose qui marche (« J'ai compris quand… ») et une chose à améliorer (« Je me suis perdu quand… »).
Choisir : tu n'es pas obligé de tout changer ; garde les retours qui reviennent deux fois et ceux qui touchent au temps.
Deuxième essai, chronométré, avec les changements.
Comparer : temps, retours, ce qui a changé.
Grille de retour
Camarade 1
Camarade 2
Une chose qui marche
Une chose à améliorer
Temps
[3]Pourquoi ça marche
Pendant qu'on parle, on ne peut pas s'écouter soi-même : on ne voit pas le moment où le public décroche. Les camarades, eux, le voient. Commencer par ce qui marche dit ce qu'il faut garder, et rend plus facile d'entendre ce qui est à améliorer. Et le deuxième essai montre si le changement a vraiment aidé : c'est un plan de test, appliqué à une présentation.
À retenirune chose qui marche, une chose à améliorer ; puis on recommence.
[4]Entraînement
Bon réflexe ou piège ?
Je donne d'abord une chose qui marche, puis une chose à améliorer.
la personne sait ce qu'elle doit garder.
Je dis seulement « c'était bien ».
on ne sait pas quoi garder, ni quoi changer.
Je me défends à chaque retour.
tu n'écoutes plus ; note, et décide après.
Je chronomètre les deux essais.
le temps est un résultat qu'on peut comparer.
Je change tout après le premier essai.
garde ce qui marchait ; change ce qui revient le plus.
[5]Quiz
1. Dans quel ordre donner un retour ?
on sait d'abord quoi garder, puis quoi changer.
2. Inès a dépassé le temps de 1 minute 30. Que fait-elle ?
c'est ce que ses deux camarades lui ont conseillé, et le deuxième essai tient en 2 minutes 55.
3. À quoi sert le deuxième essai ?
comme un plan de test, on vérifie après avoir corrigé.
[6]Kit
🎒 Ton kit — Épisode 30
25 min
Exercice : deux essais, deux retours
Présente ton jeu à deux camarades (chronomètre).
Remplis la grille de retour avec eux.
Choisis 2 changements, puis refais ta présentation.
Note les deux temps et ce qui a changé.
Code à copier : aucun.
Checklist
J'ai fait deux essais chronométrés.
J'ai noté deux retours par camarade.
Mon deuxième essai tient en 3 minutes.
[7]Journal
✍️ Journal de bord
Quel retour t'a le plus aidée ou aidé ? En as-tu laissé un de côté, et pourquoi ?
[8]Sources
Méthode du livre (plan des 3 minutes, épisode 29) ; aucune donnée datée dans cet épisode.
Semaine 16 · Transmettre
31
S16 · MARDI · Comprendre
Animer un mini-atelier
Préparer et animer 30 minutes de code pour des plus jeunes : faire faire, aider sans prendre le clavier.
⏱ 25 min de lecture · 5 min de quiz
[1]Scénario
Inès · Mardi, 12 h 40
Aux portes ouvertes, Inès animera un atelier de 30 minutes, toutes les heures, pour 4 élèves de CM2. Certains ont déjà fait des blocs en classe, d'autres jamais. Aucun n'a vu Python. Elle se souvient de ses débuts : regarder quelqu'un taper ne lui avait presque rien appris ; c'est en tapant elle-même, et en se trompant, qu'elle avait compris.
[2]Concept
Faire faire, pas montrer
1. Un objectif simple et visible. À la fin de l'atelier, chaque enfant a changé quelque chose dans le jeu et vu le résultat : un mot à lui dans la liste, une couleur, une vitesse. Un objectif qu'on peut montrer à ses parents en sortant.
2. Un déroulé en 4 temps (30 minutes).
Temps
Quoi
Qui a la souris ?
Accueil (3 min)
prénoms, « Qui a déjà fait des blocs ? »
personne
Démonstration (5 min)
une partie d'Attrape-lettres ; « Et si on changeait le jeu ? »
toi, puis eux
Défi (17 min)
dans donnees.py : ajouter un mot en majuscules, changer COULEUR_FOND, puis la vitesse
les enfants, tout le temps
Partage (5 min)
chacun montre son jeu modifié
les enfants
3. Aider sans prendre le clavier (la méthode de l'épisode 28) : montrer du doigt, poser une question, laisser taper. Les mains restent dans tes poches.
4. Prévoir les blocages.
Blocage probable
Ta réponse préparée
un mot en minuscules ne se gagne pas
« Regarde comment sont écrits les autres mots. »
un guillemet ou une virgule oublié
« Lis la dernière ligne du message rouge. Quelle ligne ? »
« J'ai tout cassé ! »
une copie propre du dossier, prête à recopier
un enfant a fini en 5 minutes
un défi bonus : un nom de couleur dans la documentation de Pyxel
5. Blocs ou Python ? Pour les CM2, le défi se fait dans donnees.py : quelques lignes de données, pas de logique. Pour des plus jeunes ou pour un enfant bloqué, un détour par les blocs (Scratch) suffit à expliquer l'idée : « une liste de mots », « une couleur », c'est la même chose.
Générateur · déroulé de mon atelier
Texte obtenu
[3]Recherche
Ce que disent les sources
Programme du cycle 3 — Le programme de mathématiques du cycle 3 (CM1, CM2, 6e) en vigueur depuis 2025 comporte une initiation à la pensée informatique [1].
Nuit du Code — L'édition 2027 propose des catégories Scratch pour les élèves du CM1 à la 6e et de la 5e à la 3e, et des catégories Python, avec Pyxel, pour la spécialité NSI au lycée et après le bac [2].
Les élèves de CM2 ont donc souvent rencontré la programmation, le plus souvent par blocs, mais pas Python : d'où un défi sur des données plutôt que sur la logique.
[4]Mythes
« Pour apprendre, il faut d'abord regarder quelqu'un faire. »
une courte démonstration suffit ; on retient en faisant soi-même.
« Si l'enfant est bloqué, le plus gentil, c'est de le faire à sa place. »
le plus utile, c'est une question qui le débloque ; il repartira fier de ce qu'il a fait.
« Les CM2 sont trop jeunes pour Python. »
changer un mot ou une couleur dans un fichier de données est à leur portée, à condition que le défi soit petit et que le résultat se voie.
[5]Quiz
1. Pendant le défi, qui tient la souris ?
l'atelier sert à faire faire, pas à montrer.
2. Pourquoi le défi se fait-il dans donnees.py ?
un petit changement, un résultat visible, sans risque de casser la logique.
3. Un enfant a « tout cassé ». Que fais-tu ?
c'est un blocage prévu, avec une réponse préparée.
[6]Kit
🎒 Ton kit — Épisode 31
25 min
Exercice : la fiche de ton atelier
Choisis l'objectif visible de ton atelier.
Remplis le générateur de déroulé.
Prépare le tableau des blocages : au moins 4 blocages et tes réponses.
Prépare une copie propre du dossier du jeu (sur une clé ou dans un dossier à part).
Fais un essai de l'atelier avec un camarade qui joue le rôle d'un enfant de CM2.
Code à copier : aucun.
Checklist
Mon atelier a un objectif visible et un déroulé en 4 temps.
J'ai prévu au moins 4 blocages, avec mes réponses.
J'ai une copie propre du jeu, prête.
Vigilancel'atelier se fait avec un adulte présent, sur les ordinateurs du collège ; on ne demande aux enfants ni leur nom de famille, ni de créer un compte.
[7]Journal
✍️ Journal de bord
Repense à ta première séance de code. Qu'est-ce qui t'aurait aidée ou aidé ce jour-là ? L'as-tu mis dans ton atelier ?
[8]Sources
Ministère de l'Éducation nationale, Livret d'accompagnement 2026 — Mathématiques, CM1 (eduscol.education.gouv.fr, publié au BOENJS du 17 avril 2025), consulté le 29/10/2026.
Nuit du Code, Édition 2027, consulté le 29/10/2026.
32
S16 · JEUDI · Pratiquer · Final
Ton projet, ta boîte à outils et ton certificat
Le stand des portes ouvertes, ta boîte à outils du Master, et la suite après le collège.
⏱ 30 min · boîte à outils · carrousel · certificat
[1]Scénario
Inès · Jeudi, 18 h
Les portes ouvertes. Sur le stand du club, Attrape-lettres tourne sur deux ordinateurs ; le mode d'emploi est imprimé à côté. Inès explique son jeu aux parents en 3 minutes, schéma à l'appui. À 18 h, quatre élèves de CM2 s'installent pour l'atelier. L'un d'eux ajoute le mot « DRAGON » dans donnees.py, lance le jeu… et attrape son premier mot. Ding, ding, ding. Il appelle sa mère pour lui montrer. Malik, à côté, regarde Inès : « Tu te souviens de ton premier SyntaxError ? »
[2]Outil
Mon carnet de code
Consigne : ton projet final, c'est Attrape-lettres tel que tu l'as construit : les trois modules de l'arc 3 (épisode 24), les sons de l'épisode 26 et ton mode d'emploi. Joue une dernière fois tout le plan de test, puis range tes outils du Master dans ton carnet.
Boîte à outils interactive · Enregistrée dans ce navigateur
[3]Carrousel final
🎨 Carrousel final — Master
MASTER · 1/4
Mon projet de jeu de A à Z
En seize semaines, tu es passée ou passé d'une liste de scores à un vrai jeu en images, rangé, documenté, et que tu sais faire découvrir aux autres.
2/4
CE QUE TU SAIS CODER
ranger des données dans des dictionnaires et des tuples
chercher et trier
créer des classes, des objets et des méthodes
programmer un jeu avec Pyxel : boucle de jeu, collisions, sons
3/4
CE QUE TU SAIS FAIRE D'UN PROJET
le découper en modules
ranger son dossier
écrire son mode d'emploi
lire un code avant de le lancer
trouver tes réponses dans la documentation
poser une bonne question
expliquer ton jeu
animer un atelier
4/4
ET APRÈS LE COLLÈGE ?
Au lycée, l'algorithmique et la programmation font partie du programme de mathématiques de seconde, et la spécialité NSI (numérique et sciences informatiques), en première et en terminale, travaille en Python. La Nuit du Code réunit chaque printemps des équipes d'élèves pour créer un jeu en 6 heures : en Scratch au collège, en Python avec Pyxel en NSI ; ton établissement peut s'y inscrire. Et dans les clubs de code, ton tour est venu d'aider les nouveaux.
[4]Journal
✍️ Journal de bord — mot de la fin
Relis ton journal de la toute première semaine. Qu'est-ce qui a le plus changé, dans ton code et dans ta façon de travailler ? Quel sera ton prochain projet ?
Bravo ! Tu as terminé l'arc 4 et tout le Master. Tu sais apprendre seule ou seul avec la documentation, demander et donner de l'aide, expliquer ton projet et transmettre ce que tu sais.
[5]Certificat
🎓 Ton certificat
Le certificat s'affiche lorsque les 32 épisodes sont marqués comme terminés.
COLLECTION « CHALLENGES » · APPRENDRE À CODER EN PYTHON
Certificat de réussite
Ce certificat atteste que
—
a terminé les épisodes du Master — Mon projet de jeu de A à Z et atteint le niveau Développeuse · Développeur et passeuse · passeur.
Ce que ce parcours couvre : dictionnaires et tuples, recherche et tri, classes et objets, jeu en 2D avec Pyxel (boucle de jeu, collisions, sons), modules et organisation d'un projet, mode d'emploi, lecture critique d'un code, documentation officielle, demande d'aide, présentation orale et animation d'un atelier.
Nuit du Code, Édition 2027, consulté le 29/10/2026.
Annexe · Kit de rattrapage et glossaire
ARattrapage
Tu démarres le Master sans avoir suivi le Boost et le Pro ? Voici, en une ligne chacune, les notions supposées acquises.
Des blocs au texte — un programme est une suite d'instructions ; « dire » devient print, « demander » devient input, l'emboîtement devient les deux-points et 4 espaces (Boost, épisode 1).
Lancer et lire une erreur — console ou script ; une erreur se lit en 3 questions : quelle ligne, quel type (dernière ligne), qu'est-ce qui manque (Boost, épisode 2).
Variables, types et conditions — = range une valeur ; int(input(...)) pour un nombre ; if / elif / else (Boost, épisode 3).
Une question, un test — ajouter peu de code à la fois et tester une bonne et une mauvaise réponse (Boost, épisode 4).
Boucles — for i in range(n): pour un nombre de tours connu, while condition: tant que… (Pro, épisode 1).