Retour à la leçon·Leçon 8 sur 8·Produire une réponse
Faire en sorte que cela tourne encore au trimestre suivant
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
- Le test
- Découpez l'analyse en étapes qui se passent des fichiers
- Rassemblez les paramètres en un seul endroit
- Faites échouer la chaîne bruyamment
- Paramétrez au lieu de copier
- Ce qui ne va jamais dans le dépôt
- Le README de passation
- Pour aller plus loin
Notes du présentateur
Transformer une analyse qui fonctionne en une analyse qui se relance sur un nouvel export sans modification, échoue bruyamment quand l'entrée change, et se transmet à quelqu'un qui n'a rien de votre contexte.Le test
- L'export du trimestre suivant arrive.
Notes du présentateur
L'export du trimestre suivant arrive. Combien d'éléments devez-vous modifier avant que le rapport ne se régénère ? Si la réponse dépasse un — le chemin du fichier d'entrée — l'analyse n'est pas reproductible : c'est le compte rendu d'un après-midi. Cette leçon ramène la réponse à un.Découpez l'analyse en étapes qui se passent des fichiers — Exemple
scripts/ 01-lecture.py export brut -> data/interim/muac-type.parquet 02-nettoyage.py typé -> data/processed/muac-propre.parquet output/tables/journal-nettoyage.csv 03-indicateurs.py propre -> output/tables/mag-par-commune.csvNotes du présentateur
Trois scripts, chacun avec une seule mission, chacun écrivant un fichier que le suivant lit.Découpez l'analyse en étapes qui se passent des fichiers — En Python
muac.to_parquet("data/interim/muac-type.parquet", index=False)Notes du présentateur
L'intérêt n'est pas le rangement. C'est que, lorsque le tableau d'indicateurs paraît faux, vous puissiez relancer la troisième étape en deux secondes au lieu de réexécuter un notebook de quinze minutes, et qu'un collègue qui débogue la deuxième n'ait pas à comprendre la troisième. Utilisez Parquet plutôt que CSV entre les étapes. Ce format préserve les types — autrement dit, le travail fait en leçon 3 pour quechild_idsoit lu comme du texte n'est pas défait à la première écriture-relecture.Découpez l'analyse en étapes qui se passent des fichiers — En R
arrow::write_parquet(muac, "data/interim/muac-type.parquet")Rassemblez les paramètres en un seul endroit — En Python
# config.py from pathlib import Path BRUT = Path("data/raw/muac-screening-artibonite-2024.v1.csv") INTERMEDIAIRE = Path("data/interim/muac-type.parquet") TRAITE = Path("data/processed/muac-propre.parquet") TABLEAUX = Path("output/tables") MAS_MM = 115 MAG_MM = 125 PB_PLAUSIBLE = (80, 220) AGE_MOIS = (6, 59) CODE_MANQUANT = "-99"Notes du présentateur
Chaque seuil, chemin et valeur de coupure figure en tête de fichier ou dans une configuration, jamais enfoui au milieu d'une expression.Rassemblez les paramètres en un seul endroit — En R
# config.R BRUT <- "data/raw/muac-screening-artibonite-2024.v1.csv" INTERMEDIAIRE <- "data/interim/muac-type.parquet" TRAITE <- "data/processed/muac-propre.parquet" TABLEAUX <- "output/tables" MAS_MM <- 115 MAG_MM <- 125 PB_PLAUSIBLE <- c(80, 220) AGE_MOIS <- c(6, 59) CODE_MANQUANT <- "-99"Notes du présentateur
Un relecteur qui veut connaître les seuils employés lit un seul fichier. Un successeur qui adapte ce travail à un autre pays modifie un seul fichier. Et quand l'OMS révise une valeur de coupure, vous changez un nombre au lieu de chercher125dans quatre scripts en manquant celui qui s'écrit12.5 * 10.Faites échouer la chaîne bruyamment — En Python (suite)
def controler_entree(df): attendues = { "child_id", "commune", "screening_date", "age_months", "sex", "muac_mm", "oedema", "outcome", } absentes = attendues - set(df.columns) if absentes: raise ValueError(f"colonnes absentes de l'export : {sorted(absentes)}") if df["child_id"].isna().any(): raise ValueError("lignes sans identifiant") mesures = df["muac_mm"].dropna() if len(mesures) == 0: raise ValueError("aucune mesure de PB — mauvais fichier ?")Notes du présentateur
Une analyse qui produit silencieusement un chiffre faux est pire qu'une analyse qui plante. Affirmez ce qui doit être vrai, à chaque frontière d'étape.Faites échouer la chaîne bruyamment — En Python (suite)
part_manquante = df["muac_mm"].isna().mean() if part_manquante > 0.20: raise ValueError( f"{part_manquante:.1%} de PB manquants — au-dessus de la tolérance de 20 %. " "À investiguer avant tout rapportage." )Faites échouer la chaîne bruyamment — En R (suite)
controler_entree <- function(df) { attendues <- c("child_id", "commune", "screening_date", "age_months", "sex", "muac_mm", "oedema", "outcome") absentes <- setdiff(attendues, names(df)) if (length(absentes) > 0) { stop("colonnes absentes de l'export : ", paste(absentes, collapse = ", ")) } if (any(is.na(df$child_id))) stop("lignes sans identifiant") part_manquante <- mean(is.na(df$muac_mm)) if (part_manquante > 0.20) { stop(sprintf( "%.1f%% de PB manquants - au-dessus de la tolerance de 20%%. A investiguer avant tout rapportage.", part_manquante * 100 ))Faites échouer la chaîne bruyamment
Écrivez l'assertion correspondant à la défaillance qui vous embarrasserait, pas à celle que vous jugez probable. Les probables, vous les remarquerez.
Notes du présentateur
Le contrôle de seuil est le plus intéressant. Il encode un jugement éditorial — au-delà de 20 % de manquants, le taux ne mérite pas d'être publié — et l'applique automatiquement à chaque export futur, y compris à ceux traités par quelqu'un qui n'a jamais lu cette leçon.Paramétrez au lieu de copier — En Python (suite)
import sys from pathlib import Path def produire_rapport(commune: str | None = None): df = pd.read_parquet(TRAITE) if commune: df = df[df["commune"] == commune] if df.empty: raise ValueError(f"aucune ligne pour la commune {commune!r}") tableau = tableau_indicateurs(df, "tranche_age") nom = commune.lower().replace(" ", "-") if commune else "toutes" tableau.to_csv(TABLEAUX / f"mag-{nom}.csv", index=False) return tableauNotes du présentateur
Douze communes, douze rapports communaux. Ne copiez pas le script douze fois.Paramétrez au lieu de copier — En Python (suite)
if __name__ == "__main__": cible = sys.argv[1] if len(sys.argv) > 1 else None produire_rapport(cible)Paramétrez au lieu de copier — En R
produire_rapport <- function(commune = NULL) { df <- arrow::read_parquet(TRAITE) if (!is.null(commune)) { df <- filter(df, commune == !!commune) if (nrow(df) == 0) stop("aucune ligne pour la commune ", commune) } tableau <- tableau_indicateurs(df, "tranche_age") nom <- if (is.null(commune)) "toutes" else tolower(gsub(" ", "-", commune)) readr::write_csv(tableau, file.path(TABLEAUX, paste0("mag-", nom, ".csv"))) tableau } args <- commandArgs(trailingOnly = TRUE) produire_rapport(if (length(args) > 0) args[1] else NULL)Notes du présentateur
Le même schéma s'étend au rapport narratif complet. Quarto compose un modèle unique avec un paramètre, douze fois, produisant douze documents qui ne peuvent pas diverger puisqu'il n'existe qu'un seul document.Ce qui ne va jamais dans le dépôt
- Ne versionnez jamais de données brutes de bénéficiaires. Ni identifiées, ni pseudonymisées. Git conserve chaque…
- Ne versionnez jamais d'identifiants de connexion. Jetons DHIS2, clés d'API KoboToolbox, mots de passe de base de…
- Ajoutez
data/raw/au.gitignoreet documentez dans le README où se trouve le vrai fichier — un disque partagé,…
Notes du présentateur
Ce point compte davantage dans ce secteur qu'ailleurs. Un dépôt contenant des données de programme peut contenir des noms de bénéficiaires, des points GPS qui identifient un ménage, ou une liste de cas de protection.Ce qui ne va jamais dans le dépôt — Exemple
data/raw/ data/interim/ data/processed/ .env *.Rhistory __pycache__/ .Rproj.user/Notes du présentateur
Le code d'analyse est ce qui a sa place sous gestion de versions. Les données ont la leur là où la politique de protection des données de votre organisation le prescrit, et le README doit indiquer où.Le README de passation — Exemple (suite)
# Analyse du dépistage PB, Artibonite ## Ce que cela produit Taux trimestriels de MAG et de MAS par commune, sexe et tranche d'âge, avec intervalles à 95 %. Alimente la décision d'implantation des sites PCIMA et le rapport bailleur trimestriel. ## D'où viennent les données Export CommCare, projet `artibonite-nutrition`, formulaire `Dépistage communautaire`. Exporté chaque mois par l'assistant suivi-évaluation vers le disque partagé à <chemin>. Absent de ce dépôt. ## Comment l'exécuter uv sync uv run python scripts/01-lecture.py uv run python scripts/02-nettoyage.pyNotes du présentateur
Rédigé pour quelqu'un qui aura votre intitulé de poste et rien de votre contexte. Cinq rubriques.Le README de passation — Exemple (suite)
uv run python scripts/03-indicateurs.py ## Décisions à connaître Voir output/tables/journal-nettoyage.csv. Celle qui compte : les lignes sans âge sont conservées, car 60 % de la semaine du 10 au 14 juin à Gros-Morne est sans âge et leur suppression modifie le classement des communes. ## Qui contacter Définitions d'indicateurs : <nom>, responsable suivi-évaluation. Problèmes de collecte : <nom>, coordinateur terrain.Notes du présentateur
Ce README fait la différence entre un successeur qui poursuit votre travail et un successeur qui le reconstruit sur tableur faute d'avoir pu deviner ce que vos scripts supposaient.Pour aller plus loin
- Nettoyage et validation des données approfondit le profilage et les corrections des leçons 5 et 6, avec…
- Conception d'indicateurs et cadre logique part de la fiche de référence de la leçon 7 et remonte jusqu'à la théorie…
- Analyse d'enquêtes, échantillonnage et pondération couvre ce que cette formation n'a pas abordé : ce qui change…
Notes du présentateur
Vous savez désormais mener un export de programme de son arrivée à un tableau d'indicateurs défendable, dans l'un ou l'autre langage, avec le raisonnement consigné. C'est le socle sur lequel s'appuie le reste du programme : Entraînez-vous sur un autre jeu de données avant de poursuivre. L'enquête ménage EAH et le registre de couverture vaccinale de routine de cette plateforme portent un tout autre assortiment de défauts, et en traiter un de bout en bout sans la leçon sous les yeux est le véritable test de ce qui est resté.