import seaborn as sns
iris = sns.load_dataset("iris")
mean_sepal = iris["sepal_length"].mean()
round(mean_sepal, 2)np.float64(5.84)
Transformez un travail exploratoire dans un carnet en un document propre et partageable qui s’exécute de bout en bout à chaque fois.
Passez des carnets Jupyter aux rapports reproductibles avec Quarto. Découvrez les forces et les faiblesses d’un carnet, pourquoi l’état caché et l’exécution dans le désordre brisent la reproductibilité, l’idée de la programmation lettrée, et comment quarto render exécute votre code de bout en bout pour produire un rapport HTML ou PDF propre.
26 juin 2026
7 juillet 2026
.ipynb enregistré non reproductible..qmd de bout en bout dans un noyau neuf — quarto render report.qmd — produisant un HTML ou un PDF propre où chaque résultat vient d’être recalculé. Si ça s’affiche, ça s’exécute.Un carnet Jupyter est l’endroit où le travail de données en Python commence généralement. Vous chargez des données, exécutez une cellule, regardez la sortie, ajustez la cellule suivante, l’exécutez de nouveau — une boucle rapide et tactile, parfaite pour comprendre ce que sont vos données et ce que vous voulez en dire. Personne ne fait mieux qu’un carnet pour l’exploration.
Les ennuis commencent quand vous voulez partager le résultat. Un carnet est l’enregistrement d’une séance exploratoire, pas un document — et un .ipynb enregistré peut afficher des sorties qui ne correspondent plus au code, parce que vous avez exécuté les cellules dans le désordre ou modifié l’une après en avoir exécuté une autre. Confiez-le à un collègue (ou à votre futur vous) et l’analyse risque de ne pas se reproduire. Pour une plateforme dont toute la promesse est si ça s’affiche, ça s’exécute, cet écart est le problème à résoudre.
Cette leçon traite de la résolution de cet écart. Nous verrons les forces et les faiblesses des carnets, pourquoi l’état caché et l’exécution dans le désordre posent problème, l’idée de la programmation lettrée, et comment Quarto prend un carnet ou un fichier .qmd et rend un rapport propre où le code s’exécute de bout en bout dans une session neuve — reproductible par construction. L’essentiel de ce qui suit relève du flux de travail et de la structure ; quelques petits fragments calculent une vraie valeur pour que vous voyiez la programmation lettrée à l’œuvre.
Chaque résultat exécuté ici est réel — et vous pouvez l’exécuter vous-même sans rien installer : cliquez sur Try ▸ sous n’importe quel bloc exécutable pour le lancer en direct dans votre navigateur (Python démarre au premier Run, puis c’est instantané). Si ça s’affiche, ça s’exécute.
Un carnet est un fichier JSON (.ipynb) contenant une liste ordonnée de cellules. Chaque cellule est soit du Markdown (prose) soit du code, et une cellule de code stocke à la fois sa source et la sortie de la dernière fois où vous l’avez exécutée. Un processus Python de longue durée — le noyau — se trouve derrière le carnet et conserve chaque variable que vous avez définie, de sorte que lorsque vous exécutez une cellule, elle s’exécute contre tout ce qui l’a précédée.
Cette conception rend les carnets excellents pour quelques choses :
Pour l’exploration, c’est exactement ce qu’il faut. Les problèmes ci-dessous ne sont pas des arguments contre les carnets — ce sont des raisons de ne pas traiter un carnet comme un rapport fini et partageable.
Voici le hic. Les sorties d’un carnet reflètent l’ordre dans lequel vous avez réellement exécuté les cellules, pas l’ordre dans lequel elles apparaissent dans le fichier. Le noyau se souvient de chaque variable de chaque cellule que vous avez exécutée, même les cellules que vous avez ensuite modifiées ou supprimées. Ainsi le document à l’écran et le code tel qu’il est écrit peuvent diverger — et vous ne le verrez pas.
Une version classique, montrée comme un simple listing (ceci n’est pas exécuté — c’est une illustration de l’ordre des cellules) :
Le nombre affiché pourrait provenir de l’exécution sales alors même que le code dit désormais revenue. La sortie a l’air faisant autorité ; elle est périmée. C’est l’état caché : la vérité réside dans la mémoire du noyau, pas dans le fichier. Des variables définies dans des cellules que vous avez depuis supprimées peuvent encore être dans la portée. Un nom peut être défini sous l’endroit où il est utilisé et fonctionner quand même, parce que vous avez exécuté la cellule du bas en premier.
Rien de tout cela n’est un bug de Jupyter — c’est le prix d’un noyau interactif. Mais cela signifie qu’un .ipynb enregistré n’est pas un enregistrement fiable de « exécutez ce code, obtenez ces sorties ».
Deux autres limites pratiques découlent du format :
Le contrôle de version est bruyant. Comme .ipynb est du JSON qui intègre des compteurs d’exécution, des blobs de sortie et des images encodées en base64, un changement de code d’une seule ligne peut produire un diff tentaculaire et illisible — et les conflits de fusion à l’intérieur des sorties encodées sont quasi impossibles à résoudre à la main. Les carnets se battent contre Git.
Ce n’est pas une expérience de lecture propre. Les carnets bruts portent des crochets de compteur d’exécution (In [7]:), du code de configuration et des cellules exploratoires mortes. Un lecteur veut un document soigné — titres, prose, figures, aucune plomberie — pas la transcription de votre séance.
Le remède à tout cela est le même : gardez la source lisible et rendez le rapport à partir d’elle, en recalculant au fur et à mesure.
L’idée est plus ancienne que les carnets. La programmation lettrée (Donald Knuth, 1984) dit qu’un programme devrait être écrit pour qu’un humain le lise, avec le code et l’explication de ce code entrelacés — puis un outil extrait et exécute le code. Appliquée à l’analyse : un seul document source contient votre prose et votre code, et un moteur de rendu exécute le code et insère sa vraie sortie en ligne.
L’avantage est que le récit et le calcul ne peuvent pas se désynchroniser, parce qu’ils sont produits à partir de la même source en une seule passe. Quand vous dites « la moyenne est de 5.84 », ce nombre vient d’être calculé — pas collé d’une exécution faite la semaine dernière. Voici une petite démonstration en direct :
np.float64(5.84)
Cette valeur — 5.84 — a été calculée au moment où cette page a été rendue. Nous pouvons même l’intégrer dans une phrase pour que la prose reste honnête :
The mean sepal length across 150 iris flowers is 5.84 cm.
Si les données changeaient, cette phrase changerait avec elles au prochain rendu. C’est ça, la programmation lettrée : le document est le calcul. Quarto est l’outil qui effectue le rendu.
Quarto est un système de publication open source qui prend un document source, exécute son code dans une session neuve de bout en bout, capture la vraie sortie, et rend un rapport HTML, PDF ou Word propre. Crucialement, Quarto lit deux sortes de source : un fichier .qmd en texte brut, ou directement un carnet Jupyter .ipynb. Dans les deux cas, rendre signifie réexécuter à partir de zéro — ce qui est précisément ce qui élimine le problème de l’état caché.
Un .qmd n’est que du Markdown avec un en-tête YAML et des cellules de code exécutables. Voici un rapport minimal complet, montré comme un listing non exécuté pour que vous puissiez en lire la structure (notez les balises de langage — yaml, puis python — celles-ci ne s’exécutent pas ; seules les cellules {python} s’exécutent) :
Enregistrez cela sous report.qmd et rendez-le depuis le terminal :
Quarto démarre un noyau Python neuf, exécute la cellule, capture 5.84, et écrit report.html — un document autonome et partageable, sans encombrement de compteurs d’exécution et sans sortie périmée, parce que rien n’a été reporté d’une session précédente. Vous préférez un PDF ? Changez une ligne dans l’en-tête (format: pdf) et refaites le rendu. Une source, plusieurs sorties.
Le mot clé est neuf : chaque rendu est une exécution depuis la première cellule dans un noyau flambant neuf. Il n’y a aucun état caché à hériter, donc le rapport que vous livrez est, par définition, reproductible.
Vous n’avez pas à abandonner vos carnets. Si votre exploration vit déjà dans analysis.ipynb, Quarto peut l’exécuter et le rendre tel quel :
Ceci exécute les cellules du carnet de bout en bout dans un noyau neuf et produit le même rapport HTML propre. (Quarto lit les options au niveau du carnet depuis une cellule raw en haut, où vous pouvez ajouter title, format, et le reste du YAML que vous avez vu plus haut.)
Si vous voulez seulement exécuter un carnet sans interface — rafraîchir toutes ses sorties en l’exécutant du début à la fin sans ouvrir Jupyter — l’outil classique est nbconvert :
C’est une vérification de reproductibilité utile en soi, et c’est en effet ce que Quarto fait avant de rendre. La différence : Quarto va un pas plus loin et transforme le carnet exécuté en un document publiable.
Voici la seule habitude qui attrape le bug d’état caché avant que quiconque d’autre ne le voie. Dans Jupyter, utilisez Kernel → Restart & Run All (ou, en ligne de commande, le nbconvert --execute ci-dessus). Ceci jette la mémoire du noyau et exécute chaque cellule depuis le haut, dans l’ordre du fichier, en une seule fois.
Si le carnet se termine proprement, il est reproductible — et il se rendra. S’il échoue (une NameError sur une variable que vous aviez définie dans une cellule depuis supprimée, un résultat qui change soudainement), vous venez de trouver un bug qui se cachait dans l’historique de votre noyau. Dans les deux cas, vous apprenez la vérité avant de partager.
Faites-en votre garde-fou : ne transmettez ni ne rendez jamais un carnet que vous n’avez pas redémarré-et-tout-exécuté depuis la dernière modification. C’est l’assurance reproductibilité la moins chère que vous achèterez jamais, et c’est exactement le contrat que quarto render impose automatiquement — c’est pourquoi un rapport Quarto qui se rend est un rapport qui s’exécute.
Deux fonctionnalités permettent à un seul document d’en faire plus sans copier-coller.
Les paramètres transforment un rapport en modèle. Vous déclarez des paramètres dans l’en-tête et les remplacez au moment du rendu, de sorte que le même .qmd produit un rapport par région, par mois ou par client. Comme un listing non exécuté :
Le code lit params["region"] (Python) ou params$region (R) et le document se rend de nouveau pour la valeur que vous passez — une source, plusieurs sorties sur mesure.
La mise en cache garde les rendus rapides quand seule une partie du document a changé. Avec execute: cache: true dans l’en-tête (ou freeze pour tout un projet), Quarto stocke le résultat de chaque cellule et ne réexécute une cellule que lorsque son code change. L’étape lente de chargement de données ou d’ajustement de modèle s’exécute une fois ; modifier un paragraphe en dessous ne coûte rien. Vous obtenez la reproductibilité d’un rendu complet de bout en bout sans payer la facture de calcul entière chaque fois que vous corrigez une coquille.
Les deux sont survolés ici — l’idée est que le modèle de document lettré évolue : il ne vous force pas à choisir entre reproductible et pratique.
Les blocs ci-dessus ont été exécutés au moment de la génération, dans un noyau neuf, de bout en bout — la même discipline qu’impose quarto render. Modifiez celui-ci et appuyez sur Run pour voir la programmation lettrée par vous-même : il calcule une valeur, puis l’insère dans une phrase-rapport d’une ligne. Il s’exécute dans votre navigateur via Pyodide (sans installation). Ou cliquez sur Try ▸ sous n’importe quel bloc exécutable ci-dessus pour y déposer son code.
L’exécution des cellules dans le désordre donne des résultats que vous ne pouvez pas reproduire. Si vous avez exécuté la cellule 5 avant la cellule 3, les sorties enregistrées reflètent cet ordre, pas celui du fichier. Dès que quelqu’un exécute le carnet de bout en bout — y compris Quarto au moment du rendu — les nombres peuvent changer ou il peut échouer purement et simplement. Le remède est la discipline ci-dessus : redémarrer-et-tout-exécuter avant de faire confiance, de partager ou de rendre. Traitez toute sortie produite dans le désordre comme provisoire.
L’état du noyau ne concorde pas avec l’état du fichier. Une variable encore en mémoire depuis une cellule supprimée ou modifiée fait paraître fonctionnel un code cassé. Symptôme : le carnet fonctionne très bien pour vous mais lève une NameError pour tous les autres (ou dans un rendu neuf). Cause : vous vous appuyez sur une valeur qui n’existe plus dans le fichier. Remède : redémarrez le noyau et confirmez que le fichier tient debout tout seul.
Le rendu échoue parce que le noyau ou l’environnement n’est pas installé. quarto render a besoin d’un noyau Jupyter enregistré et de chaque paquet que votre code importe. Un simple quarto: kernel not found ou ModuleNotFoundError au moment du rendu signifie généralement que vous rendez dans un environnement différent de celui que votre carnet utilisait en interactif. Installez Jupyter dans l’environnement du projet (pip install jupyter) et rendez depuis cet environnement activé, pour que le rendu utilise les mêmes paquets que votre exploration.
Mélanger une cellule {python} exécutable avec un simple listing python. Un bloc balisé ```{python} s’exécute ; un bloc balisé ```python est affiché tel quel et ne s’exécute pas. Si un exemple de code que vous vouliez seulement afficher essaie sans cesse de s’exécuter (et échoue sur, disons, une fonction fictive), vérifiez la balise — vous voulez l’étiquette python simple pour les illustrations et {python} seulement pour le code que vous voulez réellement que Quarto exécute.
Installez Quarto et lancez quarto render your-notebook.ipynb depuis le terminal. Quarto exécute les cellules du carnet de bout en bout dans un noyau neuf et produit un your-notebook.html propre (utilisez --to pdf pour un PDF). Ajoutez les options du document — title, author, format — dans une cellule raw tout en haut du carnet, écrites comme le même YAML que vous mettriez dans un en-tête .qmd. Parce que le rendu réexécute tout à partir de zéro, le rapport reflète le code tel qu’il est écrit, pas l’historique de votre séance interactive.
Un carnet Jupyter (.ipynb) est un fichier JSON stockant des cellules ainsi que les sorties de la dernière fois où vous les avez exécutées, modifié interactivement contre un noyau persistant — formidable pour explorer, mais ses sorties enregistrées peuvent être dans le désordre ou périmées. Un document Quarto (.qmd) est du Markdown en texte brut avec un en-tête YAML et des cellules de code, conçu pour être rendu : quarto render exécute le code de bout en bout dans une session neuve et écrit un rapport HTML/PDF propre. Le carnet est votre établi ; le document Quarto rendu est le résultat partageable et reproductible. (Quarto peut aussi rendre un .ipynb directement, donc vous n’avez pas à convertir.)
Trois habitudes. (1) Lancez Kernel → Restart & Run All (ou jupyter nbconvert --execute) avant de faire confiance à un résultat — s’il ne survit pas à une exécution propre de bout en bout, il n’est pas reproductible. (2) Rendez le rapport à partir de la source avec quarto render, qui impose cette exécution neuve automatiquement et produit un document dont les sorties viennent toutes d’être recalculées. (3) Figez votre environnement — consignez vos paquets (par ex. un requirements.txt) pour que le même code retrouve les mêmes versions plus tard. Ensemble, elles garantissent que « exécutez ceci et vous obtenez ces sorties » est réellement vrai.
Presque toujours l’état caché. Vos sorties enregistrées reflètent l’ordre dans lequel vous avez exécuté les cellules et les variables encore détenues dans la mémoire de votre noyau — y compris celles de cellules que vous avez depuis modifiées ou supprimées. Une exécution neuve (la sienne, ou un quarto render) exécute le fichier tel qu’il est écrit, de bout en bout, sans mémoire héritée, de sorte que tout recours à l’exécution dans le désordre fait surface sous la forme d’un nombre différent ou d’une NameError. Redémarrer-et-tout-exécuter de votre côté reproduit ce qu’il verra et vous permet de le corriger d’abord.
Oui — la même source se rend en plusieurs formats. Réglez format: html ou format: pdf (ou listez les deux) dans l’en-tête YAML et lancez quarto render. Le HTML est autonome et interactif ; le PDF a besoin d’un moteur LaTeX, que Quarto peut installer pour vous avec quarto install tinytex. Ce modèle source unique, sorties multiples est la raison pour laquelle le même .qmd peut devenir un rapport à l’écran et un document téléchargeable sans maintenir deux copies.
Raisonnez sur chaque tâche, puis essayez n’importe quel calcul dans la cellule Essayez en direct ci-dessus — modifiez et exécutez.
Tâche 1. Un collègue vous envoie analysis.ipynb. Avant de construire quoi que ce soit dessus, quelle action unique confirme que ses résultats sont reproductibles — et que vous dirait un échec ?
Pensez à la différence entre la mémoire du noyau et le fichier tel qu’il est écrit. Quelle action de menu jette la mémoire ?
Lancez Kernel → Restart & Run All (ou jupyter nbconvert --to notebook --execute analysis.ipynb). Ceci efface tout l’état du noyau et exécute chaque cellule de bout en bout dans l’ordre du fichier. S’il se termine proprement, le carnet est reproductible. S’il échoue — une NameError, ou un résultat qui change — les sorties d’origine dépendaient d’une exécution dans le désordre ou d’une cellule depuis supprimée, c’est-à-dire de l’état caché. Vous avez trouvé le bug avant de vous y fier.
Tâche 2. Vous voulez partager l’analyse sous forme de rapport HTML propre auquel tout le monde peut se fier. Esquissez les étapes minimales avec Quarto, en partant du carnet.
Vous n’avez pas besoin de réécrire le carnet. Une seule commande le rend — mais elle doit s’exécuter dans un environnement où le noyau et les paquets sont installés.
pip install jupyter). (2) Ajoutez en haut du carnet une cellule raw avec title et format: html. (3) Lancez quarto render analysis.ipynb. Quarto exécute le carnet dans un noyau neuf de bout en bout et écrit analysis.html — un rapport propre sans encombrement de compteurs d’exécution et sans sortie périmée, reproductible parce que chaque résultat vient d’être recalculé.Vérification rapide. Un bloc de code dans votre .qmd est balisé ```python (simple) plutôt que ```{python}. Quand vous rendez, le code s’exécute-t-il ?
Non. Une balise simple ```python est affichée telle quelle — Quarto la traite comme un listing de code et ne l’exécute pas. Seule une cellule ```{python} s’exécute au moment du rendu. C’est exactement ainsi que vous montrez du code d’exemple ou d’échafaudage (en-têtes YAML, extraits illustratifs) sans que Quarto essaie de l’exécuter.
:::
Les carnets sont le bon endroit pour explorer, mais un .ipynb enregistré porte un état caché qui en fait une chose fragile à partager. Quarto comble cet écart : il rend un carnet ou un .qmd en réexécutant le code de bout en bout dans un noyau neuf, de sorte que le rapport que vous publiez est reproductible par construction — et « redémarrer le noyau et tout exécuter » est le même test que vous pouvez appliquer vous-même en quelques secondes. Adoptez cette seule habitude et la différence entre « ça marchait sur ma machine » et « ça se rend, donc ça s’exécute » disparaît.
À lire aussi : DataFrames pandas — l’analyse qui entre dans le rapport · Installer des paquets — préparez l’environnement R/Python dont votre rapport a besoin.
@online{2026,
author = {},
title = {Des carnets Jupyter aux rapports reproductibles avec Quarto},
date = {2026-06-26},
url = {https://www.datanovia.com/learn/programming/python-foundations/notebooks-to-reports},
langid = {fr}
}