Retour à la leçon·Leçon 4 sur 8·La même réponse deux fois
Quatre choses qui changent la réponse alors que rien n'a changé
Le même diaporama que les téléchargements, rendu sous forme de page. Lancez le diaporama pour le présenter en plein écran — les flèches ou un clic avancent d'une diapositive, Échap quitte.
Ce que couvre cette leçon
- Un : l'horloge
- Deux : la graine
- Trois : l'ordre dans lequel les fichiers reviennent
- Quatre : la locale
- Le test qui attrape les quatre
- L'habitude de la sortie déterministe
- Rapportez-le en entier
- La suite
Notes du présentateur
L'horloge, la graine, l'ordre des fichiers et la locale. Chacune produit un résultat différent depuis un code identique et des données identiques, chacune est invisible dans un diff, et cette plateforme en a rencontré trois sur quatre en production.Un : l'horloge — En Python
from datetime import date report_date = date.today() # different every day, by designUn : l'horloge
- Tout ce qui lit l'heure courante fait différer chaque exécution — Un pied de page « produit le », un nom de fichier…
- Le remède est de prendre la date des données ou d'un paramètre
Notes du présentateur
Tout ce qui lit l'heure courante fait différer chaque exécution. Un pied de page « produit le », un nom de fichier avec la date du jour, un filtre sur « les 30 derniers jours », une graine aléatoire dérivée du temps. Le remède est de prendre la date des données ou d'un paramètre.Un : l'horloge — En Python
import pandas as pd survey = pd.read_csv("data/raw/household-survey-2025.v1.csv") as_of = pd.to_datetime(survey["interview_date"]).max() # from the dataUn : l'horloge
- Cette plateforme s'est trompée là-dessus et l'échec est instructif — Les documents de cours et les diaporamas de leçon…
- La date est désormais rattachée à l'artefact — Celle d'un document vient de son propre cours et de ses leçons, celle…
Notes du présentateur
Cette plateforme s'est trompée là-dessus et l'échec est instructif. Les documents de cours et les diaporamas de leçon prenaient à l'origine leur date de production du champupdatedle plus récent de toute la bibliothèque de contenu. Déterministe — et faux quand même, parce que publier un nouveau cours réhorodatait chaque document existant et réécrivait les quatre-vingt-seize binaires de diaporama. La date est désormais rattachée à l'artefact. Celle d'un document vient de son propre cours et de ses leçons, celle d'un diaporama de sa propre leçon, celle d'un rapport de son propre projet. Une réponse fausse déterministe reste une réponse fausse, et « le diff est énorme mais correct » est la façon dont personne ne le relit.Deux : la graine — En Python
import numpy as np rng = np.random.default_rng(20260729) # stated, committed, reproducible sample = rng.choice(households, size=200, replace=False)Deux : la graine
- Tout ce qui est aléatoire exige une graine et la graine a sa place dans le code — Intervalles bootstrap,…
- Fixez-la une fois, en tête, visiblement — Une graine enfouie trois fonctions plus bas est une graine que quelqu'un…
- Et dites-le dans la sortie — L'intervalle bootstrap du cours de régression est rapporté avec « 400 rééchantillonnages,…
- Chaque jeu de données de cette plateforme est produit par un script à graine fixe — ce qui fait de `pnpm…
Notes du présentateur
Tout ce qui est aléatoire exige une graine et la graine a sa place dans le code. Intervalles bootstrap, échantillonnage aléatoire pour vérification, simulation, partitions d'apprentissage et de test, points de nuage déplacés aléatoirement. Fixez-la une fois, en tête, visiblement. Une graine enfouie trois fonctions plus bas est une graine que quelqu'un déplacera. Et dites-le dans la sortie. L'intervalle bootstrap du cours de régression est rapporté avec « 400 rééchantillonnages, graine 20260729 » exactement pour cette raison — un intervalle que personne ne peut reproduire n'est pas un intervalle. Chaque jeu de données de cette plateforme est produit par un script à graine fixe, ce qui fait depnpm datasets:generateune étape de vérification : il réécrit les vingt CSV etgit statusne signale aucun changement.Trois : l'ordre dans lequel les fichiers reviennent — En Python
import glob for path in glob.glob("data/raw/*.csv"): # order is filesystem-dependent ...Trois : l'ordre dans lequel les fichiers reviennent
globetos.listdirrenvoient les fichiers dans un ordre qui diffère selon les systèmes et parfois d'une exécution à…
Notes du présentateur
globetos.listdirrenvoient les fichiers dans un ordre qui diffère selon les systèmes et parfois d'une exécution à l'autre. Si quoi que ce soit en aval dépend de l'ordre — une concaténation, une déduplication au premier arrivé, un index de ligne — le résultat diffère.Trois : l'ordre dans lequel les fichiers reviennent — En Python
for path in sorted(glob.glob("data/raw/*.csv")): ...Trois : l'ordre dans lequel les fichiers reviennent — En R
for (path in sort(list.files("data/raw", full.names = TRUE))) { }Trois : l'ordre dans lequel les fichiers reviennent
- Triez. Toujours. Cela coûte six caractères
- La même chose vaut pour l'ordre des dictionnaires et des groupes —
groupbydans pandas trie par défaut et…
Notes du présentateur
Triez. Toujours. Cela coûte six caractères. La même chose vaut pour l'ordre des dictionnaires et des groupes.groupbydans pandas trie par défaut etdplyr::group_bynon ; un graphique dont l'ordre des barres vient d'un groupement non trié est un graphique dont l'ordre peut changer sans que les données changent.Quatre : la locale — En Python
float("1,234") # ValueError, or 1.234, depending on where you areQuatre : la locale
- Le séparateur décimal, le séparateur de milliers, le format de date et l'ordre de tri des caractères accentués…
Notes du présentateur
Le séparateur décimal, le séparateur de milliers, le format de date et l'ordre de tri des caractères accentués dépendent tous de la locale, et le public de cette plateforme travaille dans les deux conventions par définition.Quatre : la locale — En Python
survey = pd.read_csv(path, decimal=".", thousands=None) # stated, not inferred dates = pd.to_datetime(survey["date"], format="%Y-%m-%d") # explicitQuatre : la locale — En R
readr::read_csv(path, locale = locale(decimal_mark = ".", date_format = "%Y-%m-%d"))Quatre : la locale
- Énoncez le format plutôt que de laisser le lecteur l'inférer —
pd.to_datetimesans format est une fonction qui… - Le tri est le plus subtil —
sorted()sur des noms de communes français placeÉtroitaprèsZonesous une locale et…
Notes du présentateur
Énoncez le format plutôt que de laisser le lecteur l'inférer.pd.to_datetimesans format est une fonction qui devine, et elle devine différemment sur03/04/2025selon ce qu'il y a d'autre dans la colonne. Le tri est le plus subtil.sorted()sur des noms de communes français placeÉtroitaprèsZonesous une locale et avantFondsous une autre, si bien que l'ordre des catégories d'un graphique devient dépendant de la machine.- Énoncez le format plutôt que de laisser le lecteur l'inférer —
Le test qui attrape les quatre — Shell
python run.py && cp -r outputs outputs-first python run.py && diff -r outputs outputs-firstLe test qui attrape les quatre
- Exécutez deux fois et comparez — Tout ce qui diffère est l'une des quatre, et le diff nomme le fichier
- Exécutez deux fois sur des machines différentes — et vous attrapez en plus la locale et l'ordre des fichiers, ce qu'une…
- Mettez-le dans l'intégration continue — qui est une machine propre à chaque fois, et la vérification s'exécute que…
Notes du présentateur
Exécutez deux fois et comparez. Tout ce qui diffère est l'une des quatre, et le diff nomme le fichier. Exécutez deux fois sur des machines différentes et vous attrapez en plus la locale et l'ordre des fichiers, ce qu'une seule machine ne peut pas faire. Mettez-le dans l'intégration continue, qui est une machine propre à chaque fois, et la vérification s'exécute que quiconque y pense ou non.L'habitude de la sortie déterministe
Source de bruit Remède Horodatages dans les métadonnées de fichier SOURCE_DATE_EPOCH, ou les retirerUne date de production dans un pied de page La prendre du contenu Une compression avec horodatage Une archive dont les dates d'entrée sont fixées L'ordre de sommation en virgule flottante Trier avant de réduire là où cela compte Un identifiant aléatoire incorporé Le dériver d'une empreinte du contenu Notes du présentateur
Pour tout ce qu'une compilation produit, une sortie identique octet pour octet sur entrée inchangée est l'objectif, et il est atteignable plus souvent qu'on ne le suppose.L'habitude de la sortie déterministe
- Cette plateforme fixe
SOURCE_DATE_EPOCHpour pdfTeX et pour pandoc — parce qu'un.pptxest une archive dont les… - Le bénéfice est qu'un diff signifie quelque chose — Quand reconstruire ne produit aucun changement, un changement dans…
Notes du présentateur
Cette plateforme fixeSOURCE_DATE_EPOCHpour pdfTeX et pour pandoc, parce qu'un.pptxest une archive dont les dates d'entrée et les propriétés de document bougeraient sinon à chaque reconstruction de chaque diaporama. Le bénéfice est qu'un diff signifie quelque chose. Quand reconstruire ne produit aucun changement, un changement dans le diff est un vrai changement — et la relecture devient possible.- Cette plateforme fixe
Rapportez-le en entier — Exemple
Determinism All randomness is seeded: seed 20260729, set in src/config.py and reported with every bootstrap interval in this report. Dates are taken from the data (the latest interview date) rather than from the clock. No output contains a generation timestamp. File iteration is sorted. Group order is stated explicitly rather than inherited from the grouping library's default. CSV reading states the decimal mark and the date format rather than inferring them. Verified: running the pipeline twice produces byte-identical outputs, and CI runs it on a clean machine on every push.Rapportez-le en entier
- La dernière ligne est l'affirmation et les quatre au-dessus sont la façon dont elle a été obtenue — Un rapport qui…
Notes du présentateur
La dernière ligne est l'affirmation et les quatre au-dessus sont la façon dont elle a été obtenue. Un rapport qui affirme le déterminisme sans dire laquelle des quatre il a traitée a probablement traité la graine et aucune autre.La suite
- Une chaîne reproductible qui produit un rapport vaut la peine d'exister.
Notes du présentateur
Une chaîne reproductible qui produit un rapport vaut la peine d'exister. La leçon suivante lui en fait produire douze, depuis un seul modèle, sans une seule copie.