Upload vacances_scolaires.py
Browse files- vacances_scolaires.py +159 -0
vacances_scolaires.py
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Calendrier des vacances scolaires françaises par zone (A, B, C)
|
| 3 |
+
Sources : Ministère de l'Éducation Nationale
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
import pandas as pd
|
| 7 |
+
from datetime import date
|
| 8 |
+
from typing import Dict, List, Tuple
|
| 9 |
+
|
| 10 |
+
# ============================================================
|
| 11 |
+
# VACANCES SCOLAIRES 2023-2024
|
| 12 |
+
# ============================================================
|
| 13 |
+
VACANCES_2023_2024: Dict[str, List[Tuple[date, date]]] = {
|
| 14 |
+
"A": [
|
| 15 |
+
(date(2023, 10, 21), date(2023, 11, 5)),
|
| 16 |
+
(date(2023, 12, 23), date(2024, 1, 7)),
|
| 17 |
+
(date(2024, 2, 17), date(2024, 3, 3)),
|
| 18 |
+
(date(2024, 4, 13), date(2024, 4, 28)),
|
| 19 |
+
(date(2024, 7, 6), date(2024, 9, 1)),
|
| 20 |
+
],
|
| 21 |
+
"B": [
|
| 22 |
+
(date(2023, 10, 21), date(2023, 11, 5)),
|
| 23 |
+
(date(2023, 12, 23), date(2024, 1, 7)),
|
| 24 |
+
(date(2024, 2, 24), date(2024, 3, 10)),
|
| 25 |
+
(date(2024, 4, 20), date(2024, 5, 5)),
|
| 26 |
+
(date(2024, 7, 6), date(2024, 9, 1)),
|
| 27 |
+
],
|
| 28 |
+
"C": [
|
| 29 |
+
(date(2023, 10, 21), date(2023, 11, 5)),
|
| 30 |
+
(date(2023, 12, 23), date(2024, 1, 7)),
|
| 31 |
+
(date(2024, 2, 10), date(2024, 2, 25)),
|
| 32 |
+
(date(2024, 4, 6), date(2024, 4, 21)),
|
| 33 |
+
(date(2024, 7, 6), date(2024, 9, 1)),
|
| 34 |
+
],
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
# ============================================================
|
| 38 |
+
# VACANCES SCOLAIRES 2024-2025
|
| 39 |
+
# ============================================================
|
| 40 |
+
VACANCES_2024_2025: Dict[str, List[Tuple[date, date]]] = {
|
| 41 |
+
"A": [
|
| 42 |
+
(date(2024, 10, 19), date(2024, 11, 3)),
|
| 43 |
+
(date(2024, 12, 21), date(2025, 1, 5)),
|
| 44 |
+
(date(2025, 2, 8), date(2025, 2, 23)),
|
| 45 |
+
(date(2025, 4, 5), date(2025, 4, 20)),
|
| 46 |
+
(date(2025, 7, 5), date(2025, 8, 31)),
|
| 47 |
+
],
|
| 48 |
+
"B": [
|
| 49 |
+
(date(2024, 10, 19), date(2024, 11, 3)),
|
| 50 |
+
(date(2024, 12, 21), date(2025, 1, 5)),
|
| 51 |
+
(date(2025, 2, 22), date(2025, 3, 9)),
|
| 52 |
+
(date(2025, 4, 19), date(2025, 5, 4)),
|
| 53 |
+
(date(2025, 7, 5), date(2025, 8, 31)),
|
| 54 |
+
],
|
| 55 |
+
"C": [
|
| 56 |
+
(date(2024, 10, 19), date(2024, 11, 3)),
|
| 57 |
+
(date(2024, 12, 21), date(2025, 1, 5)),
|
| 58 |
+
(date(2025, 2, 15), date(2025, 3, 2)),
|
| 59 |
+
(date(2025, 4, 12), date(2025, 4, 27)),
|
| 60 |
+
(date(2025, 7, 5), date(2025, 8, 31)),
|
| 61 |
+
],
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
ALL_VACANCES = {
|
| 65 |
+
"2023-2024": VACANCES_2023_2024,
|
| 66 |
+
"2024-2025": VACANCES_2024_2025,
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
# ============================================================
|
| 70 |
+
# MAPPING DR → ZONE DE VACANCES (À ADAPTER)
|
| 71 |
+
# ============================================================
|
| 72 |
+
DR_TO_ZONE = {
|
| 73 |
+
# === ZONE A ===
|
| 74 |
+
"Besancon": "A",
|
| 75 |
+
"Bordeaux": "A",
|
| 76 |
+
"Clermont-Ferrand": "A",
|
| 77 |
+
"Dijon": "A",
|
| 78 |
+
"Grenoble": "A",
|
| 79 |
+
"Lyon": "A",
|
| 80 |
+
"Limoges": "A",
|
| 81 |
+
"Poitiers": "A",
|
| 82 |
+
# === ZONE B ===
|
| 83 |
+
"Aix-Marseille": "B",
|
| 84 |
+
"Amiens": "B",
|
| 85 |
+
"Caen": "B",
|
| 86 |
+
"Lille": "B",
|
| 87 |
+
"Nantes": "B",
|
| 88 |
+
"Nice": "B",
|
| 89 |
+
"Orleans-Tours": "B",
|
| 90 |
+
"Reims": "B",
|
| 91 |
+
"Rennes": "B",
|
| 92 |
+
"Rouen": "B",
|
| 93 |
+
"Strasbourg": "B",
|
| 94 |
+
# === ZONE C ===
|
| 95 |
+
"Creteil": "C",
|
| 96 |
+
"Montpellier": "C",
|
| 97 |
+
"Nancy-Metz": "C",
|
| 98 |
+
"Paris": "C",
|
| 99 |
+
"Toulouse": "C",
|
| 100 |
+
"Versailles": "C",
|
| 101 |
+
# --- Ajoute tes codes DR ici ---
|
| 102 |
+
"AFC": "C",
|
| 103 |
+
"AFL": "B",
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
def get_zone_for_dr(dr: str) -> str:
|
| 108 |
+
return DR_TO_ZONE.get(dr, "C")
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
def is_vacances(d: date, zone: str, vacances: Dict[str, List[Tuple[date, date]]]) -> bool:
|
| 112 |
+
for debut, fin in vacances.get(zone, []):
|
| 113 |
+
if debut <= d <= fin:
|
| 114 |
+
return True
|
| 115 |
+
return False
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
def get_periode_vacances(d: date, vacances: Dict[str, List[Tuple[date, date]]]) -> str:
|
| 119 |
+
for zone in ["A", "B", "C"]:
|
| 120 |
+
for debut, fin in vacances.get(zone, []):
|
| 121 |
+
if debut <= d <= fin:
|
| 122 |
+
m = d.month
|
| 123 |
+
if m in [10, 11]: return "Toussaint"
|
| 124 |
+
elif m in [12, 1]: return "Noel"
|
| 125 |
+
elif m in [2, 3]: return "Hiver"
|
| 126 |
+
elif m in [4, 5]: return "Printemps"
|
| 127 |
+
elif m in [7, 8]: return "Ete"
|
| 128 |
+
return "Hors_vacances"
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
def add_vacances_columns(df: pd.DataFrame, date_col: str = "Date", dr_col: str = "DR") -> pd.DataFrame:
|
| 132 |
+
"""Ajoute zone_vacances, is_vacances_zone, periode_vacances au DataFrame."""
|
| 133 |
+
df = df.copy()
|
| 134 |
+
df["Date"] = pd.to_datetime(df[date_col]).dt.tz_localize(None)
|
| 135 |
+
df["zone_vacances"] = df[dr_col].apply(get_zone_for_dr)
|
| 136 |
+
|
| 137 |
+
def get_annee_scolaire(d):
|
| 138 |
+
if d.month >= 9:
|
| 139 |
+
return f"{d.year}-{d.year+1}"
|
| 140 |
+
else:
|
| 141 |
+
return f"{d.year-1}-{d.year}"
|
| 142 |
+
|
| 143 |
+
df["annee_scolaire"] = df["Date"].apply(get_annee_scolaire)
|
| 144 |
+
|
| 145 |
+
def check_vacances(row):
|
| 146 |
+
d = row["Date"].date()
|
| 147 |
+
vac = ALL_VACANCES.get(row["annee_scolaire"], {})
|
| 148 |
+
return is_vacances(d, row["zone_vacances"], vac)
|
| 149 |
+
|
| 150 |
+
df["is_vacances_zone"] = df.apply(check_vacances, axis=1)
|
| 151 |
+
|
| 152 |
+
def get_periode(row):
|
| 153 |
+
d = row["Date"].date()
|
| 154 |
+
vac = ALL_VACANCES.get(row["annee_scolaire"], {})
|
| 155 |
+
return get_periode_vacances(d, vac)
|
| 156 |
+
|
| 157 |
+
df["periode_vacances"] = df.apply(get_periode, axis=1)
|
| 158 |
+
|
| 159 |
+
return df
|