diff --git a/journal.md b/journal.md new file mode 100644 index 0000000000000000000000000000000000000000..f0b205ffdac51b918f0345a9d6343b73c7b565c1 --- /dev/null +++ b/journal.md @@ -0,0 +1,10 @@ +# Journal de bord – MOOC Recherche Reproductible + +## Jour 1 +- Découverte de R Markdown +- Différence entre Jupyter, RStudio et Org-mode + +### Données +- Date : 19/12/2025 +- Temps : nuageux +- Temps de travail : 1h30 diff --git a/module1/exo2/fichiermarkdown.md b/module1/exo2/fichiermarkdown.md new file mode 100644 index 0000000000000000000000000000000000000000..2f6008c32477c0f5174b15470cded643b3bf8453 --- /dev/null +++ b/module1/exo2/fichiermarkdown.md @@ -0,0 +1,19 @@ +# Partie 1 + +## Ce que j’apprends +- Utilisation de GitLab +- Écriture en Markdown + +*texte en italique* +**texte en gras** + +Lien vers le MOOC : +https://app-learninglab.inria.fr/moocrr/ + +1. premier point +2. second point + +```python +print("Bonjour le monde") + + diff --git a/module2/exo1/toy_document_fr.Rmd b/module2/exo1/toy_document_fr.Rmd index 7eece5e296bb586e88166aa8a263ca75b44c2b9e..e646ce241ad38c90bd3fd84903beb4ddb5652111 100644 --- a/module2/exo1/toy_document_fr.Rmd +++ b/module2/exo1/toy_document_fr.Rmd @@ -1,33 +1,31 @@ --- -title: "Votre titre" -author: "Votre nom" -date: "La date du jour" +title: "À propos du calcul de pi" +author: "Arnaud Legrand" +date: "25 juin 2018" output: html_document --- - - -```{r setup, include=FALSE} -knitr::opts_chunk$set(echo = TRUE) +En demandant à la lib maths +Mon ordidnateur m'indique que π vaut approximativement +```{r} +pi ``` - -## Quelques explications - -Ceci est un document R markdown que vous pouvez aisément exporter au format HTML, PDF, et MS Word. Pour plus de détails sur R Markdown consultez . - -Lorsque vous cliquerez sur le bouton **Knit** ce document sera compilé afin de ré-exécuter le code R et d'inclure les résultats dans un document final. Comme nous vous l'avons montré dans la vidéo, on inclue du code R de la façon suivante: - -```{r cars} -summary(cars) +## En utilisant la méthode des aiguillesde Buffon +Mais calculé avec la méthode dess aiguiles de Buffon , on obtienrait comme approximation: +```{r} +set.seed(42) +N = 100000 +x = runif(N) +theta = pi/2*runif(N) +2/(mean(x+sin(theta)>1)) ``` - -Et on peut aussi aisément inclure des figures. Par exemple: - -```{r pressure, echo=FALSE} -plot(pressure) -``` - -Vous remarquerez le paramètre `echo = FALSE` qui indique que le code ne doit pas apparaître dans la version finale du document. Nous vous recommandons dans le cadre de ce MOOC de ne pas utiliser ce paramètre car l'objectif est que vos analyses de données soient parfaitement transparentes pour être reproductibles. - -Comme les résultats ne sont pas stockés dans les fichiers Rmd, pour faciliter la relecture de vos analyses par d'autres personnes, vous aurez donc intérêt à générer un HTML ou un PDF et à le commiter. - -Maintenant, à vous de jouer! Vous pouvez effacer toutes ces informations et les remplacer par votre document computationnel. +## Avec un argument “fréquentiel” de surface +Sinon, une méthode plus simple à comprendre et ne faisant pas intervenir d’appel à la fonction sinus se base sur le fait que si $X\sim U(0,1)$ et $Y\sim U(0,1)$ alors $P[X^2+Y^2\le 1]=\pi/4$ (voir méthode de Monte Carlo sur Wikipedia). Le code suivant illustre ce fait: +```{r} +set.seed(42) +N = 1000 +df = data.frame(X = runif(N), Y = runif(N)) +df$Accept = (df$X**2 + df$Y**2 <=1) +library(ggplot2) +ggplot(df, aes(x=X,y=Y,color=Accept)) + geom_point(alpha=.2) + + coord_fixed() + theme_bw() +--- \ No newline at end of file diff --git a/module2/exo2/exercice_fr.Rmd b/module2/exo2/exercice_fr.Rmd index 7eece5e296bb586e88166aa8a263ca75b44c2b9e..f24fcb25fde6be6606773294ca1855460ebbc6be 100644 --- a/module2/exo2/exercice_fr.Rmd +++ b/module2/exo2/exercice_fr.Rmd @@ -1,33 +1,26 @@ --- -title: "Votre titre" +title: "Statistiques descriptives" author: "Votre nom" -date: "La date du jour" +date: "19 décembre 2025" output: html_document --- - - -```{r setup, include=FALSE} -knitr::opts_chunk$set(echo = TRUE) -``` - -## Quelques explications - -Ceci est un document R markdown que vous pouvez aisément exporter au format HTML, PDF, et MS Word. Pour plus de détails sur R Markdown consultez . - -Lorsque vous cliquerez sur le bouton **Knit** ce document sera compilé afin de ré-exécuter le code R et d'inclure les résultats dans un document final. Comme nous vous l'avons montré dans la vidéo, on inclue du code R de la façon suivante: - -```{r cars} -summary(cars) +```{r} +data <- c( +14.0, 7.6, 11.2, 12.8, 12.5, 9.9, 14.9, 9.4, 16.9, 10.2, +14.9, 18.1, 7.3, 9.8, 10.9, 12.2, 9.9, 2.9, 2.8, 15.4, +15.7, 9.7, 13.1, 13.2, 12.3, 11.7, 16.0, 12.4, 17.9, 12.2, +16.2, 18.7, 8.9, 11.9, 12.1, 14.6, 12.1, 4.7, 3.9, 16.9, +16.8, 11.3, 14.4, 15.7, 14.0, 13.6, 18.0, 13.6, 19.9, 13.7, +17.0, 20.5, 9.9, 12.5, 13.2, 16.1, 13.5, 6.3, 6.4, 17.6, +19.1, 12.8, 15.5, 16.3, 15.2, 14.6, 19.1, 14.4, 21.4, 15.1, +19.6, 21.7, 11.3, 15.0, 14.3, 16.8, 14.0, 6.8, 8.2, 19.9, +20.4, 14.6, 16.4, 18.7, 16.8, 15.8, 20.4, 15.8, 22.4, 16.2, +20.3, 23.4, 12.1, 15.5, 15.4, 18.4, 15.7, 10.2, 8.9, 21.0 +) + +mean(data) +sd(data) # écart-type corrigé (par défaut en R) +min(data) +median(data) +max(data) ``` - -Et on peut aussi aisément inclure des figures. Par exemple: - -```{r pressure, echo=FALSE} -plot(pressure) -``` - -Vous remarquerez le paramètre `echo = FALSE` qui indique que le code ne doit pas apparaître dans la version finale du document. Nous vous recommandons dans le cadre de ce MOOC de ne pas utiliser ce paramètre car l'objectif est que vos analyses de données soient parfaitement transparentes pour être reproductibles. - -Comme les résultats ne sont pas stockés dans les fichiers Rmd, pour faciliter la relecture de vos analyses par d'autres personnes, vous aurez donc intérêt à générer un HTML ou un PDF et à le commiter. - -Maintenant, à vous de jouer! Vous pouvez effacer toutes ces informations et les remplacer par votre document computationnel. diff --git a/module2/exo3/exercice_fr.Rmd b/module2/exo3/exercice_fr.Rmd index 7eece5e296bb586e88166aa8a263ca75b44c2b9e..4af771d4954f91c3e0bfe75efccfcea833cf79d2 100644 --- a/module2/exo3/exercice_fr.Rmd +++ b/module2/exo3/exercice_fr.Rmd @@ -1,33 +1,32 @@ --- -title: "Votre titre" +title: "Affichage graphique des données" author: "Votre nom" -date: "La date du jour" +date: "19 décembre 2025" output: html_document --- - - -```{r setup, include=FALSE} -knitr::opts_chunk$set(echo = TRUE) -``` - -## Quelques explications - -Ceci est un document R markdown que vous pouvez aisément exporter au format HTML, PDF, et MS Word. Pour plus de détails sur R Markdown consultez . - -Lorsque vous cliquerez sur le bouton **Knit** ce document sera compilé afin de ré-exécuter le code R et d'inclure les résultats dans un document final. Comme nous vous l'avons montré dans la vidéo, on inclue du code R de la façon suivante: - -```{r cars} -summary(cars) -``` - -Et on peut aussi aisément inclure des figures. Par exemple: - -```{r pressure, echo=FALSE} -plot(pressure) -``` - -Vous remarquerez le paramètre `echo = FALSE` qui indique que le code ne doit pas apparaître dans la version finale du document. Nous vous recommandons dans le cadre de ce MOOC de ne pas utiliser ce paramètre car l'objectif est que vos analyses de données soient parfaitement transparentes pour être reproductibles. - -Comme les résultats ne sont pas stockés dans les fichiers Rmd, pour faciliter la relecture de vos analyses par d'autres personnes, vous aurez donc intérêt à générer un HTML ou un PDF et à le commiter. - -Maintenant, à vous de jouer! Vous pouvez effacer toutes ces informations et les remplacer par votre document computationnel. +```{r} +data <- c( +14.0, 7.6, 11.2, 12.8, 12.5, 9.9, 14.9, 9.4, 16.9, 10.2, +14.9, 18.1, 7.3, 9.8, 10.9, 12.2, 9.9, 2.9, 2.8, 15.4, +15.7, 9.7, 13.1, 13.2, 12.3, 11.7, 16.0, 12.4, 17.9, 12.2, +16.2, 18.7, 8.9, 11.9, 12.1, 14.6, 12.1, 4.7, 3.9, 16.9, +16.8, 11.3, 14.4, 15.7, 14.0, 13.6, 18.0, 13.6, 19.9, 13.7, +17.0, 20.5, 9.9, 12.5, 13.2, 16.1, 13.5, 6.3, 6.4, 17.6, +19.1, 12.8, 15.5, 16.3, 15.2, 14.6, 19.1, 14.4, 21.4, 15.1, +19.6, 21.7, 11.3, 15.0, 14.3, 16.8, 14.0, 6.8, 8.2, 19.9, +20.4, 14.6, 16.4, 18.7, 16.8, 15.8, 20.4, 15.8, 22.4, 16.2, +20.3, 23.4, 12.1, 15.5, 15.4, 18.4, 15.7, 10.2, 8.9, 21.0 +) + +# 1. Sequence plot +plot(data, type = "b", + xlab = "Index", + ylab = "Valeur", + main = "Sequence plot des données") + +# 2. Histogramme +hist(data, + breaks = 10, + col = "lightgray", + main = "Histogramme des données", + xlab = "Valeur") diff --git a/module2/exo4/daily_data.csv b/module2/exo4/daily_data.csv new file mode 100644 index 0000000000000000000000000000000000000000..c9637459662ac9b4cf9c02577be50a55ae0d0d54 --- /dev/null +++ b/module2/exo4/daily_data.csv @@ -0,0 +1,4 @@ +date,study_minutes,mood,weather,notes +2025-12-19,60,7,cloudy,"Started module 2 exo4" +2025-12-20,45,6,rain,"Worked on markdown and Rmd" +2025-12-21,90,8,sunny,"Did plots and stats" diff --git a/module2/exo4/exercice_fr.Rmd b/module2/exo4/exercice_fr.Rmd index 7eece5e296bb586e88166aa8a263ca75b44c2b9e..dd10f2a2ee8bdb7d8f1e9952cb66aea31edb6b4b 100644 --- a/module2/exo4/exercice_fr.Rmd +++ b/module2/exo4/exercice_fr.Rmd @@ -1,33 +1,21 @@ --- -title: "Votre titre" +title: "Journal de bord — analyse" author: "Votre nom" -date: "La date du jour" +date: "19 décembre 2025" output: html_document --- +```{r} +df <- read.csv("daily_data.csv", stringsAsFactors = FALSE) +df$date <- as.Date(df$date) +# Statistiques de base +summary(df) -```{r setup, include=FALSE} -knitr::opts_chunk$set(echo = TRUE) -``` +# Exemple : moyenne du temps d'étude +mean(df$study_minutes) -## Quelques explications - -Ceci est un document R markdown que vous pouvez aisément exporter au format HTML, PDF, et MS Word. Pour plus de détails sur R Markdown consultez . - -Lorsque vous cliquerez sur le bouton **Knit** ce document sera compilé afin de ré-exécuter le code R et d'inclure les résultats dans un document final. Comme nous vous l'avons montré dans la vidéo, on inclue du code R de la façon suivante: - -```{r cars} -summary(cars) -``` - -Et on peut aussi aisément inclure des figures. Par exemple: - -```{r pressure, echo=FALSE} -plot(pressure) -``` - -Vous remarquerez le paramètre `echo = FALSE` qui indique que le code ne doit pas apparaître dans la version finale du document. Nous vous recommandons dans le cadre de ce MOOC de ne pas utiliser ce paramètre car l'objectif est que vos analyses de données soient parfaitement transparentes pour être reproductibles. - -Comme les résultats ne sont pas stockés dans les fichiers Rmd, pour faciliter la relecture de vos analyses par d'autres personnes, vous aurez donc intérêt à générer un HTML ou un PDF et à le commiter. - -Maintenant, à vous de jouer! Vous pouvez effacer toutes ces informations et les remplacer par votre document computationnel. +# Graphique : évolution du temps d'étude +plot(df$date, df$study_minutes, type="b", + xlab="Date", ylab="Minutes d'étude", + main="Temps d'étude par jour") +``` \ No newline at end of file diff --git a/module2/exo5/exo5_fr.Rmd b/module2/exo5/exo5_fr.Rmd index 479d7823321976e2d925d00ea599e205bfbd8cc7..43b281b781b848c2367c4ab9537fcaa9f5d3f76f 100644 --- a/module2/exo5/exo5_fr.Rmd +++ b/module2/exo5/exo5_fr.Rmd @@ -29,22 +29,55 @@ Nous commençons donc par charger ces données: data = read.csv("shuttle.csv",header=T) data ``` - +```{r} +# ========================= +# Correction de l'analyse +# ========================= + +# ERREUR HISTORIQUE : +# Les analyses initiales filtraient les vols avec Malfunction > 0, +# supprimant ainsi les vols sans incident (zéros), ce qui biaise +# totalement l'estimation d'une probabilité. +# On conserve donc TOUS les vols. + +# Création d'une variable binaire correcte : +# 1 = au moins un joint défaillant, 0 = aucun incident +data$incident <- as.integer(data$Malfunction > 0) + +# Visualisation correcte : tous les vols +plot(data$Temperature, data$incident, pch = 19, + xlab = "Température (°F)", + ylab = "Incident (0/1)", + main = "Risque de défaillance vs température (tous les vols)") + +# Régression logistique correcte +fit_incident <- glm(incident ~ Temperature, data = data, family = binomial()) +summary(fit_incident) + +# Courbe de probabilité estimée +tgrid <- data.frame(Temperature = seq(min(data$Temperature), + max(data$Temperature), + length.out = 200)) +tgrid$p <- predict(fit_incident, newdata = tgrid, type = "response") + +plot(data$Temperature, data$incident, pch = 19, + xlab = "Température (°F)", + ylab = "Incident (0/1)", + main = "Probabilité estimée d'incident selon la température") +lines(tgrid$Temperature, tgrid$p, lwd = 2) + + Le jeu de données nous indique la date de l'essai, le nombre de joints toriques mesurés (il y en a 6 sur le lançeur principal), la température (en Farenheit) et la pression (en psi), et enfin le nombre de dysfonctionnements relevés. # Inspection graphique des données -Les vols où aucun incident n'est relevé n'apportant aucun information -sur l'influence de la température ou de la pression sur les -dysfonctionnements, nous nous concentrons sur les expériences où au -moins un joint a été défectueux. +Les sans incident (Malfunction = 0) sont essentiels : ils indiquent à quelles +températures *aucun* problème n’est observé. Les exclure biaise l’analyse et +conduit à sous-estimer le risque aux basses températures. + -```{r} -data = data[data$Malfunction>0,] -data -``` Très bien, nous avons une variabilité de température importante mais la pression est quasiment toujours égale à 200, ce qui devrait diff --git a/module3/exo1/analyse-syndrome-grippal.Rmd b/module3/exo1/analyse-syndrome-grippal.Rmd index 771e78faac371f23c921f7f7aecc87f2100e9059..984367de0407af2ae09e1ceb501c9bed24a21d96 100644 --- a/module3/exo1/analyse-syndrome-grippal.Rmd +++ b/module3/exo1/analyse-syndrome-grippal.Rmd @@ -43,8 +43,13 @@ Voici l'explication des colonnes donnée sur le [sur le site d'origine](https:// La première ligne du fichier CSV est un commentaire, que nous ignorons en précisant `skip=1`. ### Téléchargement +```r ```{r} -data = read.csv(data_url, skip=1) +local_file <- "incidence-PAY-3.csv" +if (!file.exists(local_file)) { + download.file(data_url, destfile = local_file, mode = "wb") +} +data <- read.csv(local_file, skip = 1) ``` Regardons ce que nous avons obtenu: diff --git a/module3/exo2/exercice_fr.Rmd b/module3/exo2/exercice_fr.Rmd index 7eece5e296bb586e88166aa8a263ca75b44c2b9e..ce272df6deffa309585702145ed018dc2b877137 100644 --- a/module3/exo2/exercice_fr.Rmd +++ b/module3/exo2/exercice_fr.Rmd @@ -1,33 +1,185 @@ ---- -title: "Votre titre" -author: "Votre nom" -date: "La date du jour" -output: html_document ---- +import os +import re +import csv +from datetime import date +import pandas as pd +DATA_PATH = r"C:\Users\nargi\Downloads\inc-25-PAY.csv" -```{r setup, include=FALSE} -knitr::opts_chunk$set(echo = TRUE) -``` +if not os.path.exists(DATA_PATH): + raise FileNotFoundError(f"File not found: {DATA_PATH}") -## Quelques explications +# ------------------------------------------------------------ +# 1) Load Sentinelles CSV robustly (skip broken metadata / find real header) +# ------------------------------------------------------------ +with open(DATA_PATH, "r", encoding="utf-8", errors="replace") as f: + lines = f.read().splitlines() -Ceci est un document R markdown que vous pouvez aisément exporter au format HTML, PDF, et MS Word. Pour plus de détails sur R Markdown consultez . +# Find header line: contains letters + separators and NOT just the metadata blob +header_idx = None +for i, ln in enumerate(lines): + if not ln.strip(): + continue + if ln.lstrip().startswith("#"): + continue + low = ln.lower() + if ((";" in ln) or ("," in ln) or ("\t" in ln) or ("|" in ln)) and re.search(r"[A-Za-z_]", ln): + header_idx = i + break -Lorsque vous cliquerez sur le bouton **Knit** ce document sera compilé afin de ré-exécuter le code R et d'inclure les résultats dans un document final. Comme nous vous l'avons montré dans la vidéo, on inclue du code R de la façon suivante: +if header_idx is None: + raise ValueError("Could not find a header row (CSV table) in the file.") -```{r cars} -summary(cars) -``` +# detect delimiter from that header line +header_line = lines[header_idx] +try: + dialect = csv.Sniffer().sniff(header_line, delimiters=[",", ";", "\t", "|"]) + sep = dialect.delimiter +except Exception: + sep = ";" # common in FR exports -Et on peut aussi aisément inclure des figures. Par exemple: +content = "\n".join(lines[header_idx:]) +df = pd.read_csv(pd.io.common.StringIO(content), sep=sep, engine="python", on_bad_lines="skip") -```{r pressure, echo=FALSE} -plot(pressure) -``` +df = df.loc[:, ~df.columns.astype(str).str.match(r"^Unnamed")] +if df.empty: + raise ValueError("Parsed dataframe is empty. The file may not contain tabular data.") -Vous remarquerez le paramètre `echo = FALSE` qui indique que le code ne doit pas apparaître dans la version finale du document. Nous vous recommandons dans le cadre de ce MOOC de ne pas utiliser ce paramètre car l'objectif est que vos analyses de données soient parfaitement transparentes pour être reproductibles. +# ------------------------------------------------------------ +# 2) Identify week column and incidence column +# ------------------------------------------------------------ +def score_week_col(s: pd.Series) -> float: + x = s.dropna().astype(str).str.strip().head(200) + if x.empty: + return 0.0 + patterns = [ + r"^\d{6}$", # YYYYWW + r"^\d{4}-?W\d{1,2}$", # YYYY-WW or YYYYWww + r"^\d{4}s\d{1,2}$", # YYYYsWW + ] + return max(x.str.match(p, case=False).mean() for p in patterns) -Comme les résultats ne sont pas stockés dans les fichiers Rmd, pour faciliter la relecture de vos analyses par d'autres personnes, vous aurez donc intérêt à générer un HTML ou un PDF et à le commiter. +week_col = max(df.columns, key=lambda c: score_week_col(df[c])) +if score_week_col(df[week_col]) < 0.3: + raise ValueError(f"Could not detect week column. Columns: {list(df.columns)}") -Maintenant, à vous de jouer! Vous pouvez effacer toutes ces informations et les remplacer par votre document computationnel. +# incidence column: prefer inc100 like in your R code, else pick best numeric column containing 'inc' +lower_to_orig = {str(c).strip().lower(): c for c in df.columns} +inc_col = None +for k in ["inc100", "inc_100", "incidence100", "incidence_100"]: + if k in lower_to_orig: + inc_col = lower_to_orig[k] + break + +def to_num(s: pd.Series) -> pd.Series: + return pd.to_numeric(s.astype(str).str.replace(",", ".", regex=False), errors="coerce") + +if inc_col is None: + cands = [] + for c in df.columns: + if c == week_col: + continue + if "inc" in str(c).lower(): + coerced = to_num(df[c]) + if coerced.notna().sum() > 0: + df[c] = coerced + cands.append(c) + if not cands: + # fallback: any numeric column + for c in df.columns: + if c == week_col: + continue + coerced = to_num(df[c]) + if coerced.notna().sum() > 0: + df[c] = coerced + cands.append(c) + if not cands: + raise ValueError("Could not find any numeric incidence column.") + inc_col = max(cands, key=lambda c: df[c].var(skipna=True)) + +df[inc_col] = to_num(df[inc_col]) + +# ------------------------------------------------------------ +# 3) Convert ISO week -> Monday date (like your R parse_iso_8601 approach) +# ------------------------------------------------------------ +def week_to_monday(w) -> pd.Timestamp: + w = str(w).strip() + + m = re.match(r"^(?P\d{4})(?P\d{2})$", w) # YYYYWW + if m: + y = int(m.group("y")); ww = int(m.group("w")) + return pd.Timestamp(date.fromisocalendar(y, ww, 1)) + + m = re.match(r"^(?P\d{4})-?W(?P\d{1,2})$", w, flags=re.IGNORECASE) # YYYYWww + if m: + y = int(m.group("y")); ww = int(m.group("w")) + return pd.Timestamp(date.fromisocalendar(y, ww, 1)) + + m = re.match(r"^(?P\d{4})s(?P\d{1,2})$", w, flags=re.IGNORECASE) # YYYYsww + if m: + y = int(m.group("y")); ww = int(m.group("w")) + return pd.Timestamp(date.fromisocalendar(y, ww, 1)) + + ts = pd.to_datetime(w, errors="coerce") + if pd.isna(ts): + raise ValueError(f"Unrecognized week format: {w}") + return ts + +df["date"] = df[week_col].apply(week_to_monday) +df = df.sort_values("date").reset_index(drop=True) + +# ------------------------------------------------------------ +# 4) Define epidemic year EXACTLY as: (Sep 1 N-1, Sep 1 N] +# We label it by the END year N (like your R variable 'annee') +# ------------------------------------------------------------ +def season_end_year(d: pd.Timestamp) -> int: + # If date is strictly after Sep 1 of its calendar year => belongs to season ending next year + sep1 = pd.Timestamp(f"{d.year}-09-01") + return d.year + 1 if d > sep1 else d.year + +df["annee"] = df["date"].apply(season_end_year) + +# Keep reasonable years (at least one full season) +valid_years = sorted(df["annee"].unique()) +# ------------------------------------------------------------ +# 5) Compute BOTH metrics per epidemic year: +# - cumulative = sum(inc100) +# - peak = max(inc100) +# ------------------------------------------------------------ +annual = ( + df.groupby("annee", as_index=False) + .agg( + incidence_sum=(inc_col, "sum"), + incidence_peak=(inc_col, "max"), + n_weeks=(inc_col, "count"), + first_date=("date", "min"), + last_date=("date", "max"), + ) + .sort_values("annee") +) + +# strongest/weakest by SUM +strong_sum = annual.loc[annual["incidence_sum"].idxmax(), ["annee", "incidence_sum"]] +weak_sum = annual.loc[annual["incidence_sum"].idxmin(), ["annee", "incidence_sum"]] + +# strongest/weakest by PEAK +strong_peak = annual.loc[annual["incidence_peak"].idxmax(), ["annee", "incidence_peak"]] +weak_peak = annual.loc[annual["incidence_peak"].idxmin(), ["annee", "incidence_peak"]] + +print(f"✅ Loaded: {DATA_PATH}") +print(f"✅ Separator: {repr(sep)}") +print(f"✅ Week column: {week_col}") +print(f"✅ Incidence column: {inc_col}") +print(f"✅ Date range: {df['date'].min().date()} -> {df['date'].max().date()}") +print("\n--- Epidemic year definition: (Sep 1 N-1, Sep 1 N] labeled by N ---\n") + +print("RESULTS using CUMULATIVE incidence (SUM over the epidemic year):") +print(f" Strongest: year {int(strong_sum['annee'])} | sum = {strong_sum['incidence_sum']:.3f}") +print(f" Weakest: year {int(weak_sum['annee'])} | sum = {weak_sum['incidence_sum']:.3f}") + +print("\nRESULTS using PEAK incidence (MAX weekly over the epidemic year):") +print(f" Strongest: year {int(strong_peak['annee'])} | peak = {strong_peak['incidence_peak']:.3f}") +print(f" Weakest: year {int(weak_peak['annee'])} | peak = {weak_peak['incidence_peak']:.3f}") + +print("\n--- Sanity check (first 12 epidemic years) ---") +print(annual.head(12).to_string(index=False))