Code, résultats et notes dans un seul document
Un notebook Jupyter est un document composé de cellules. Une cellule de code contient du Python que l'on peut exécuter ; sa sortie (nombres, tableaux, graphiques) s'affiche juste dessous. Une cellule markdown contient du texte mis en forme pour les explications, les équations et les titres. Un processus d'arrière-plan appelé noyau (kernel) exécute le code et garde en mémoire chaque variable d'une cellule à l'autre. Les notebooks sont idéaux pour explorer des données et expliquer une analyse, d'où leur omniprésence en recherche quantitative.
# Inside your project's virtual environment
python -m pip install jupyterlab
# Start it; a browser tab opens
jupyter lab
# Keyboard shortcuts you will use all day
# Shift+Enter run the cell and move on
# Esc then A/B insert a cell above/below
# Esc then M/Y turn a cell into markdown/codeLe noyau se souvient, et c'est le danger
Les cellules peuvent être exécutées dans n'importe quel ordre et autant de fois qu'on veut, et le noyau conserve la dernière valeur de chaque variable. Un notebook peut donc sembler correct à l'écran tout en dépendant d'une cellule supprimée ou d'une exécution dans le désordre, et personne d'autre (ni vous demain) ne peut le reproduire. Le compteur d'exécution à côté de chaque cellule de code ([3], [7]) montre l'ordre réel. Avant de faire confiance à un notebook ou de le partager, utilisez Redémarrer le noyau et tout exécuter : s'il échoue ou si les chiffres changent, le notebook n'était pas reproductible.
# Cell [1]
fee = 0.001
# Cell [2]
cost = 10000 * fee
print(cost) # 10.0
# Cell [3]: you edit this to fee = 0.002 but never re-run cell [2]
fee = 0.002
print(cost) # still 10.0: the notebook now says fee=0.002 but shows the old costUn notebook n'est que du JSON
Un fichier .ipynb est un document JSON avec une liste cells. Chaque cellule a un cell_type ("code", "markdown" ou "raw") et une source (une liste de lignes ou une chaîne) ; les cellules de code stockent aussi leurs outputs et leur execution_count. Comme c'est du JSON ordinaire, on peut lire et modifier un notebook avec le module json, c'est ainsi que des outils les convertissent en scripts ou en effacent les sorties. Cela explique aussi pourquoi les notebooks produisent des différences Git bruyantes : sorties et compteurs changent à chaque exécution.
import json
notebook = {
"nbformat": 4, "nbformat_minor": 5, "metadata": {},
"cells": [
{"cell_type": "markdown", "metadata": {}, "source": ["# Fee study\n", "Does the fee matter?"]},
{"cell_type": "code", "metadata": {}, "execution_count": 2,
"source": ["fee = 0.001\n", "print(10000 * fee)"],
"outputs": [{"output_type": "stream", "name": "stdout", "text": ["10.0\n"]}]},
],
}
# What the file looks like, and how to walk it
print(len(json.dumps(notebook, indent=1).splitlines()) > 10) # True
for cell in notebook["cells"]:
print(cell["cell_type"], "".join(cell["source"]).splitlines()[0])
# markdown # Fee study
# code fee = 0.001Habitudes pour des notebooks propres et fiables
Gardez les notebooks courts et linéaires : de haut en bas, imports et réglages dans la première cellule, une idée par section avec un titre markdown. Déplacez la logique réutilisable dans des fonctions d'un module .py ordinaire (voir les paquets) et importez-la, pour pouvoir la tester ; le notebook se contente alors d'appeler et de tracer. Redémarrez et exécutez tout avant chaque commit. Sous Git, effacez d'abord les sorties (un outil comme nbstripout peut le faire automatiquement) sinon vous validerez des mégaoctets de graphiques et des différences illisibles. Ne laissez jamais de clés d'API dans une cellule ou une sortie.
# Keep notebooks tidy under Git
python -m pip install nbstripout
nbstripout --install # strips outputs automatically on every commit
# Run a notebook top to bottom from the terminal (a reproducibility check)
jupyter nbconvert --to notebook --execute study.ipynb --output checked.ipynb
# Turn a notebook into a plain script
jupyter nbconvert --to script study.ipynb.py avec un test. Les notebooks servent à poser des questions ; les modules, aux réponses sur lesquelles on compte. Le lab traite le JSON d'un notebook comme de simples dictionnaires, ce qui est exactement la façon d'écrire ce genre d'outils.- Les cellules s'exécutent dans n'importe quel ordre et le noyau se souvient : redémarrez et exécutez tout avant de vous y fier ou de partager.
- Un
.ipynbest du JSON :cells, chacune aveccell_type,sourceet, pour le code,outputsetexecution_count. - Gardez la logique dans des modules, effacez les sorties avant de valider, gardez les secrets dehors.
À suivre : les flux de recherche reproductibles, qui réunissent graines, environnements, versions et contrôles de données pour que n'importe qui puisse reconstruire un résultat.
Lab : ce qui est noté
- Extraire le code d'un notebook avec
code_cells25 pts - Compter les types de cellules avec
count_cells25 pts - Effacer les sorties avant de valider avec
clear_outputs25 pts - Transformer un notebook en script avec
to_script25 pts