Leçon 10-P — Le projet final : de bout en bout
1. Objectif
À la fin de cette leçon — qui dure trois à quatre semaines — tu auras livré un projet complet en autonomie : ton sujet, cadré par toi (10-1), découpé en issues, développé en branches (10-2) par incréments toujours testés (pytest), documenté par un vrai README, publié sur GitHub avec un tag v1.0, et clos par un bilan rétrospectif dans le journal. Autrement dit : tu sauras mener un projet du besoin flou au logiciel fini, sans que personne ne balise le chemin.
2. Pourquoi c'est important
C'est le livrable qui clôt la méthode — et le seul qui compte vraiment. Toutes les notions des niveaux 00–09 sont des moyens ; la capacité à les assembler en un outil fini est LA compétence terminale. C'est aussi ta première pièce de portfolio : un repo public avec un historique propre, des tests et un README sérieux dit plus qu'un CV. Et surtout, ce projet t'apprend quelque chose qu'aucune leçon ne peut enseigner : ce que ça fait de décider seul — quoi couper, quand c'est fini, par quoi continuer. Après lui, tu n'as plus besoin de la méthode ; c'est le but depuis le niveau 00.
3. Explication simple
Le projet final n'introduit aucune notion nouvelle. C'est un assemblage, dans l'ordre, de choses que tu sais déjà faire :
cadrer (10-1) → SPECS.md, roadmap, issues
squelette → un programme minuscule qui tourne + 1 test + 1er commit
boucle → UNE issue à la fois : branche → tests → code → merge (10-2)
mi-parcours → utiliser l'outil pour de vrai, ajuster le cap
finition → chasse aux tracebacks, README, tag v1.0
bilan → la page de journal qui clôt le parcours
La règle qui tient tout : le projet est TOUJOURS en état de marche. On ne quitte jamais une session avec un programme cassé sur main — c'est exactement ce que les branches permettent. Ta référence de travail quotidienne est la fiche projects/mini-projects/12-projet-final-cli.md : elle détaille les huit phases, les exigences non négociables et la checklist « projet fini ». Cette leçon-ci est le mode d'emploi de la TRAVERSÉE — ce qui se passe dans ta tête et dans ton Git pendant les trois semaines.
4. Explication approfondie
a) Le rythme : une session = une issue. Chaque session de travail commence par choisir UNE issue (elles sont déjà écrites — merci le cadrage), et vise à la finir : branche, test(s), code jusqu'à vert, merge, issue fermée. Si l'issue déborde systématiquement, tes issues sont trop grosses — redécoupe-les, ce n'est pas un échec, c'est de la maintenance de cadrage. Ce rythme produit un effet psychologique décisif : chaque session se termine par une victoire complète et mergée, pas par un chantier ouvert.
b) Les tests d'abord — ou au pire, en même temps. La discipline du niveau 08 devient vitale ici : une issue n'est finie que testée. La méthode la plus simple : écrire le test de l'issue AVANT le code (le test échoue, puis tu codes jusqu'à ce qu'il passe). Au minimum : jamais de merge sans test de la fonctionnalité mergée. Les tests « qu'on écrira à la fin » ne seront jamais écrits — et sans eux, chaque merge devient un acte de foi.
c) Le flottement est prévu au programme. Il y aura des moments « par quoi je continue ? », des impasses techniques, une fonctionnalité qui résiste. Réponses, dans l'ordre : (1) la liste d'issues — c'est sa raison d'être ; (2) le journal — écrire trois phrases sur le blocage le dissout souvent (effet canard, 10-3) ; (3) la doc officielle, puis une question au gabarit 10-3 ; (4) couper — voir (d). Le flottement n'est pas un signal d'échec, c'est la sensation normale de l'autonomie. Tous les projets réels la contiennent.
d) Couper est une décision de pro. À mi-parcours, tu constateras que la v1.0 prévue est trop grosse (règle ×2, elle ne pardonne jamais). La bonne réponse n'est PAS de rallonger : c'est de couper une fonctionnalité — la déplacer dans hors-périmètre avec une ligne datée, et livrer le reste. Un projet fini à périmètre réduit vaut infiniment plus qu'un projet complet inachevé : l'un existe, l'autre non.
e) La revue de mi-parcours. À la fin de v0.1, arrête de coder deux ou trois jours et utilise ton outil pour de vrai. Note ce qui agace, ce qui manque vraiment (souvent différent de ce qui était prévu), ce qui ne sert pas. Puis mets à jour SPECS et roadmap en fonction. C'est le moment le plus rentable du projet : trois jours d'usage réel valent mieux que toutes les spéculations du cadrage.
f) « Publié » veut dire : utilisable par un inconnu. Le test final du README : clone ton repo dans un dossier vierge et suis TON README à la lettre, rien que lui. Chaque commande doit marcher telle quelle. Le tag git tag v1.0 + git push --tags marque la fin — après lui, tu as le droit (le devoir) de t'arrêter.
Difficulté honnête : c'est le plus long effort du parcours, et sa difficulté n'est pas technique — elle est morale : tenir trois semaines, traverser le creux de la semaine 2 (l'enthousiasme est retombé, la fin est loin), résister au périmètre qui gonfle, et déclarer fini. Prévois-le explicitement : des sessions courtes mais régulières battent les marathons du dimanche, et le journal est ton outil de moral autant que de mémoire. Si tu dois retenir une seule chose : petit, fini, mergé — puis suivant.
5. Exemples commentés
Fil rouge : spendlog, le suivi de dépenses CLI cadré dans les solutions de la leçon 10-1. Ces extraits montrent la MÉCANIQUE ; ton projet a son propre contenu.
Exemple 1 — le squelette qui tourne (jour 1 du code)
projects/final-projects/spendlog/
SPECS.md ← copiés depuis ton cadrage 10-1
ROADMAP.md
ISSUES.md
README.md ← trois lignes pour l'instant, c'est normal
spendlog/
__init__.py
cli.py ← argparse + une sous-commande qui répond
storage.py ← vide ou presque
tests/
test_smoke.py ← UN test trivial qui passe
git switch -c feat/project-skeleton
git add projects/final-projects/spendlog/
git commit -m "project: add spendlog skeleton with argparse and first test"
git switch main
git merge feat/project-skeleton
À partir d'ici et jusqu'au tag, python -m spendlog --help répond et pytest est vert sur main, sans exception.
Exemple 2 — une session type (l'issue #1 : add écrit dans le CSV)
git switch -c feat/add-command # 1. la branche porte le nom de l'issue
# 2. écrire tests/test_add.py : le test échoue (rouge)
# 3. coder storage.append() + le branchement argparse : le test passe (vert)
# 4. lancer l'outil POUR DE VRAI une fois (pas seulement pytest)
git add ...
git commit -m "project: add expense recording via add command"
git switch main
git merge feat/add-command
git branch -d feat/add-command
# 5. cocher l'issue #1 dans ISSUES.md, commit, et FIN DE SESSION
Remarque le point 4 : pytest vérifie la logique, pas l'expérience. Chaque session inclut au moins un vrai lancement de l'outil.
Exemple 3 — l'historique qui raconte le projet. Au bout de dix jours, git log --oneline --graph doit ressembler à ceci (une bosse par feature — compare avec l'exemple 4 de la leçon 10-2) :
* merge feat/report-command
|\
| * project: add monthly report with per-category totals
|/
* merge fix/negative-amount
|\
| * fix: reject negative amounts in add command
|/
* merge feat/list-command
...
Si ton historique est une ligne droite de commits directs sur main, le vieux réflexe a gagné — relis la section 6 de la leçon 10-2 (et pardonne-toi : la discipline se rattrape à la prochaine session, pas rétroactivement).
Exemple 4 — couper proprement, trace écrite. Extrait de SPECS.md après la revue de mi-parcours :
## Hors périmètre v1
- Interface graphique (V2 ? probablement jamais)
- Modification d'une dépense (V2 — noté le 2026-07-05)
- [COUPÉ le 2026-07-19] budgets par catégorie avec alertes : prévu en v1.0,
déplacé en V2 — trois sessions estimées, et l'usage réel montre que
`report` me suffit. Décision notée au journal du 19.
C'est ça, un cadrage vivant : la coupe est datée, motivée, et le projet reste livrable. Aucune honte nulle part.
Exemple 5 — le bilan rétrospectif (extrait). Dernière entrée de journal du parcours, trois questions minimum :
# Journal — 2026-07-26 — bilan spendlog v1.0
CE QUI A PRIS PLUS DE TEMPS QUE PRÉVU : le parsing des dates (2 sessions au
lieu de 0,5) — je n'avais pas imaginé les dates partielles. La règle ×2
était en fait optimiste.
CE QUE JE REFERAIS AUTREMENT : écrire les tests de storage.py AVANT cli.py ;
j'ai déboggé à travers argparse des bugs qui étaient dans le stockage.
CE QUE J'AI APPRIS SUR MA FAÇON DE TRAVAILLER : je code mieux en sessions de
45 min le matin ; les sessions du soir produisent les bugs du lendemain.
Le journal de blocage m'a débloqué deux fois sur trois.
C'est cette page-là qui clôt la méthode — pas le tag.
6. Erreurs fréquentes
Ce sont les six façons classiques de rater un projet final — toutes déjà croisées dans le parcours, toutes mortelles ici. (La fiche 12 en donne la version courte ; voici comment elles se VIVENT.)
1) Commencer à coder avant la fin du cadrage. Symptôme au jour 4 : « je ne sais plus quoi faire ensuite », et le projet s'arrête là. Le cadrage n'était pas de la bureaucratie — c'était la réserve de « prochaines tâches ». Correction : stop code, une session de rattrapage cadrage (10-1), reprise.
2) Le périmètre qui gonfle en douce. Chaque session ajoute « un petit truc en plus » non prévu ; en semaine 3, la v1.0 s'est éloignée au lieu de se rapprocher. Correction : toute idée nouvelle va dans hors-périmètre avec sa date (exemple 4) — le code de la V1 n'accueille QUE des issues du cadrage.
3) Le tunnel sans commit. Une semaine de travail, rien de commité, programme cassé — impossible de savoir où on en est ni de revenir en arrière. Correction préventive : une branche vit 2-3 jours MAXIMUM (10-2) ; si elle est plus vieille, elle est trop grosse — merger ce qui marche, redécouper le reste.
4) Les tests « pour la fin ». À la fin, il y a le README, la chasse aux tracebacks, la fatigue — jamais les tests. Et sans tests, le refactoring de la semaine 3 casse la feature de la semaine 1 sans bruit. Correction : une issue n'est finie que testée (section 4b) — c'est binaire.
5) Polir sans fin au lieu de livrer. « Encore un petit refactor et c'est bon » — depuis dix jours. C'est la peur du verdict déguisée en perfectionnisme. Correction : la définition de « fini » de SPECS.md est le juge, pas ton confort. Elle est atteinte ? Tag, push, bilan, fini.
6) Le README écrit pour soi. « Lancer le script avec les bons arguments » — inutilisable par quiconque, y compris toi dans six mois. Correction : le test du dossier vierge (section 4f), sans indulgence.
7. Lire les messages d'erreur
Pendant trois semaines, tu vas rencontrer tous les tracebacks du parcours — c'est normal et c'est révisé. Deux lectures spécifiques au projet long :
Le test qui casse « tout seul » après un merge. pytest passait sur ta branche, passe sur main avant merge, échoue après :
FAILED tests/test_report.py::test_monthly_total - AssertionError:
assert 15.5 == 12.5
Ce n'est pas un mystère : les DEUX lignées étaient correctes séparément et fausses ensemble (ta feature suppose un format de CSV que l'autre branche a changé, par exemple). C'est précisément pour attraper ça que les tests tournent APRÈS chaque merge — Git garantit la fusion du texte, jamais celle de la logique (leçon 10-2, exemple 3). Lecture : le nom du test dit QUELLE exigence est cassée ; git log --oneline -5 dit ce qui vient d'entrer ; le coupable est dans cette intersection.
Le traceback de l'utilisateur maltraiteur. En phase de finition, tu bombardes ton outil d'entrées absurdes (exigence : aucun traceback). Chaque traceback trouvé se lit comme d'habitude (dernière ligne d'abord), puis se transforme en DEUX artefacts : un test pytest qui reproduit l'entrée absurde, et le correctif — dans cet ordre. Un traceback trouvé = un test gagné ; c'est la version industrialisée du réflexe appris au niveau 01.
8. Exercices — faciles
Ici, les « exercices » sont les jalons réels du projet. Pas de fichiers
ex-10-P-*: les livrables vont dansprojects/final-projects/<ton-projet>/, et les traces dans le journal. La ficheprojects/mini-projects/12-projet-final-cli.mdreste ta référence de travail quotidienne — relis ses phases avant de commencer.
a) Installer le cadrage. Copie ton dossier de cadrage 10-1 (SPECS, ROADMAP, ISSUES) dans projects/final-projects/<ton-projet>/, relis-le une dernière fois avec la grille de la leçon 10-1, et fige la définition de « fini ». Commit.
b) Le squelette qui tourne. Reproduis l'exemple 1 pour TON projet : structure en modules, argparse avec une sous-commande qui répond, un test pytest trivial vert, le tout développé sur une branche feat/project-skeleton mergée dans main. Durée cible : une session.
c) La première vraie issue. Déroule la session type de l'exemple 2 sur l'issue #1 de ta liste, de la branche au merge, test compris. C'est la session que tu vas répéter vingt fois — soigne le rituel maintenant.
9. Exercices — moyens
a) Livrer v0.1. Enchaîne les issues du premier jalon, une par session, jusqu'à ce que v0.1 soit utilisable pour de vrai. Contrainte de discipline : zéro commit direct sur main (vérifie ton git log --graph : que des bosses), et pytest vert à chaque fin de session. Pièges des sections 6-2 et 6-3 en embuscade permanente.
b) La revue de mi-parcours. Utilise ton outil quotidiennement pendant 2-3 jours SANS coder. Puis : mets à jour SPECS/ROADMAP d'après l'usage réel, coupe au moins ce qui doit l'être (avec la trace écrite de l'exemple 4), et consigne l'arbitrage au journal. Cette pause fait partie du projet — la sauter est une erreur de débutant, pas un gain de temps.
c) La passe « aucun traceback ». Une session entière à maltraiter ton outil : arguments manquants, montants négatifs, fichiers absents ou corrompus, entrées vides, dates absurdes. Chaque traceback devient un test
- un correctif (section 7), sur une branche
fix/....
10. Exercices — difficiles
a) La traversée complète jusqu'au tag. Finis v0.2 puis v1.0 : dernières issues, README au niveau du test du dossier vierge, checklist « projet fini » de la fiche 12 cochée SANS indulgence, publication du repo sur GitHub, git tag v1.0 + git push --tags. C'est un exercice de plusieurs semaines — les indices ci-dessous sont pour les moments de creux, pas pour la technique.
- Indice 1 (semaine 2, le creux) : relis ta liste d'issues cochées et ton
git log— le chemin parcouru est toujours plus long qu'il ne semble. Puis UNE petite issue, pour remettre la machine en route. Le moral suit l'action, pas l'inverse. - Indice 2 (« je ne finirai jamais ») : ce n'est pas un problème de vitesse, c'est un problème de périmètre. Ouvre SPECS.md et coupe — la section 4d t'y autorise explicitement.
- Indice 3 (« encore un refactor et je tague ») : relis la définition de « fini » que TU as écrite au jour 0. Si elle est atteinte, le refactor de plus est de la peur, pas de la qualité. Tag maintenant, V2 plus tard — ou jamais, et c'est très bien aussi.
b) Le bilan rétrospectif. La dernière page du parcours (exemple 5) : ce qui a pris plus de temps que prévu et pourquoi ; ce que tu referais autrement ; ce que le projet t'a appris sur TA façon de travailler ; et ton plan de progression post-méthode (10-3) mis à jour à la lumière du projet. Une page minimum, sincère. Commit journal:, push — et le parcours est clos.
11. Mini-projet lié — c'est LE projet
Pas de mini-projet séparé : le projet final EST le projet du niveau, et la fiche projects/mini-projects/12-projet-final-cli.md en est la carte d'ensemble (phases, exigences, extensions, checklist finale). Si tu veux un échauffement avant de te lancer, refais la « répétition générale Git » de la leçon 10-2 sur un projet du niveau 07 — c'est le seul galop d'essai utile. Extension naturelle après le tag : les quatre pistes de la fiche 12 (portfolio public, pyproject.toml + pip install -e ., GitHub Actions, deuxième projet) — mais APRÈS le bilan, jamais à la place.
12. Correction / méthode de correction
Il n'existe pas de correction d'un projet personnel — c'est le principe. Trois instruments de vérité la remplacent : la checklist « projet fini » de la fiche 12 (cochée sans indulgence, elle est ton correcteur), le test du dossier vierge pour le README, et le bilan rétrospectif pour la méthode elle-même. solutions/serie-10-P-solutions.md fournit des exemples de référence pour se comparer : un squelette commenté, un extrait d'historique Git sain, une coupe de périmètre bien tracée et un bilan rétrospectif complet. Compare la STRUCTURE (rythme des merges, taille des issues, honnêteté du bilan), jamais le contenu — ton projet ne ressemble à aucun autre, c'est le but.
13. À retenir
- Le projet final n'introduit rien de neuf : c'est l'assemblage de 10-1, 10-2 et des niveaux 00–09, dans l'ordre.
- Petit, fini, mergé — puis suivant. Une session = une issue = une branche.
- Le projet est TOUJOURS en état de marche sur
main;pytestvert à chaque fin de session. - Une issue n'est finie que testée ; un traceback trouvé = un test gagné.
- Le flottement est normal ; ses antidotes : la liste d'issues, le journal, la doc, couper.
- Couper est une décision de pro — tracée, datée, sans honte.
- « Fini » = la définition écrite au jour 0, pas ton perfectionnisme du jour 20. Tag
v1.0et arrêt. - Le parcours se clôt par le bilan écrit, pas par le code.
14. Questions de révision
- Pourquoi le squelette (programme minimal + un test + commit) doit-il exister dès le premier jour de code ?
- Que contient une session type, du début à la fin ? Dans quel ordre ?
- Que fais-tu, dans l'ordre, quand tu ne sais plus par quoi continuer ?
- À quoi sert la revue de mi-parcours, et pourquoi est-elle plus rentable que trois sessions de code ?
- Comment coupe-t-on une fonctionnalité proprement ? Quelle trace écrite ?
- Pourquoi un test peut-il casser après un merge alors que les deux branches passaient séparément ?
- Quel est le test final d'un README, concrètement ?
- Qu'est-ce qui clôt officiellement le parcours — le tag ou autre chose ?
15. Checklist de compréhension
Ici, la checklist est celle du niveau entier — elle recouvre les critères de sortie du README :
- Mon cadrage (SPECS, roadmap, issues) existait avant mon code, et il a été mis à jour quand la réalité l'a contredit.
- Chaque fonctionnalité a vécu sur sa branche ; mon
git log --graphmontre des merges, pas une ligne droite. - J'ai résolu au moins un conflit de merge sans paniquer.
-
pytestest vert, et chaque exigence livrée a son test. - Aucune entrée utilisateur essayée ne produit de traceback.
- Le README passe le test du dossier vierge ; le repo est publié et tagué
v1.0. - J'ai coupé au moins une chose pour finir — et c'est tracé.
- Le bilan rétrospectif est écrit, et mon plan post-méthode avec lui.
Si une case reste vide : ce n'est pas une leçon à relire, c'est une phase du projet à terminer. La checklist détaillée est dans la fiche 12.
16. Commit conseillé
Pendant le projet : une branche + des commits par issue, un merge par feature (leçon 10-2), git tag v1.0 à la fin. Puis le tout dernier commit du parcours :
git add lessons/level-10-autonomie journal
git commit -m "project: complete level 10 and finish the learning method"
git push
C'est le commit de fin de niveau annoncé par le README — tu viens de terminer la méthode. Le prochain commit sera sur un projet à toi, cadré par toi, sans filet. C'était le but.