Spaces:
Sleeping
Sleeping
Download src/module/add_data.py from jaimalklyde/ProjetData: direct link, hf CLI and curl.
- Browser
- Download file 5.74 kB
-
https://huggingface.co/spaces/jaimalklyde/ProjetData/resolve/main/src/module/add_data.py
- Command line
-
hf download hf://spaces/jaimalklyde/ProjetData/src/module/add_data.py
-
curl -L -o add_data.py https://huggingface.co/spaces/jaimalklyde/ProjetData/resolve/main/src/module/add_data.py
5.74 kB
| """ | |
| MODULE: DATA INJECTOR (FLUX CONTINU) | |
| ==================================== | |
| Responsabilité : Injection contrôlée de nouveaux lots de données. | |
| Mode : Append (Ajout à la suite sans écraser). | |
| Style : Professionnel (Sans Emoji). | |
| """ | |
| import pandas as pd | |
| import numpy as np | |
| import datetime as dt | |
| from faker import Faker | |
| import streamlit as st | |
| import random | |
| class DataInjector: | |
| def __init__(self, client, sheet_name): | |
| self.client = client | |
| self.sheet_name = sheet_name | |
| self.fake = Faker("fr_FR") | |
| # Services de l'hôpital | |
| self.svc_codes = ["URG", "MED", "PED", "REA", "INF", "ISO", "CAR", "NEU", "TRA"] | |
| def _append_to_sheet(self, df, worksheet_name): | |
| """Ajoute les données à la suite des lignes existantes dans Google Sheets""" | |
| try: | |
| sh = self.client.open(self.sheet_name) | |
| worksheet = sh.worksheet(worksheet_name) | |
| # Conversion en string pour l'API Google Sheets | |
| df_export = df.copy() | |
| for col in df_export.select_dtypes(include=['datetime64', 'object', 'datetimetz']).columns: | |
| df_export[col] = df_export[col].astype(str) | |
| # Extraction des valeurs brutes | |
| values = df_export.values.tolist() | |
| # Appel API | |
| worksheet.append_rows(values) | |
| return True | |
| except Exception as e: | |
| st.error(f"Erreur lors de l'ajout dans '{worksheet_name}': {e}") | |
| return False | |
| def generate_batch(self, days=7): | |
| """ | |
| Génère un lot de données pour X jours. | |
| Volume estimé pour 7 jours : ~63 lignes Ressources + ~400 lignes Admissions + Stocks. | |
| """ | |
| # On simule à partir d'aujourd'hui pour avoir des données "fraîches" | |
| start_date = dt.date.today() | |
| dates = pd.date_range(start_date, periods=days, freq="D") | |
| # 1. SCÉNARIOS (Météo/Épidémie) | |
| scen_rows = [] | |
| for d in dates: | |
| # Petit hasard pour rendre ça vivant | |
| r = np.random.random() | |
| if r < 0.1: sc = "Grippe" | |
| elif r < 0.05: sc = "Canicule" | |
| else: sc = "Normal" | |
| scen_rows.append({"date": d, "scenario": sc, "intensity": 1 if sc != "Normal" else 0}) | |
| df_scen = pd.DataFrame(scen_rows) | |
| # 2. ADMISSIONS (Le flux patients) | |
| adm_rows = [] | |
| for d in dates: | |
| for svc in self.svc_codes: | |
| # Variation aléatoire pour tester la sensibilité de l'IA | |
| n_patients = np.random.poisson(lam=random.randint(3, 12)) | |
| adm_rows.append({ | |
| "date": d, | |
| "service_code": svc, | |
| "nb_admissions": n_patients | |
| }) | |
| df_adm = pd.DataFrame(adm_rows) | |
| # 3. RESSOURCES (L'état des lits) | |
| res_rows = [] | |
| for d in dates: | |
| for svc in self.svc_codes: | |
| # Simulation d'une occupation variable | |
| lits_tot = 150 | |
| occup = np.random.randint(80, 155) # Parfois ça déborde (>150) | |
| # Injection d'anomalies pour tester le module DQ | |
| is_anomaly = 1 if occup > lits_tot else 0 | |
| anomaly_type = "suroccupation" if is_anomaly else None | |
| res_rows.append({ | |
| "date": d, | |
| "service_code": svc, | |
| "lits_total": lits_tot, | |
| "lits_occupes": occup, | |
| "personnel_disponible": np.random.randint(20, 35), | |
| "personnel_requis": 30, | |
| "taux_occupation": round(occup/lits_tot, 2), | |
| "dq_is_anomaly": is_anomaly, | |
| "dq_anomaly_type": anomaly_type | |
| }) | |
| df_res = pd.DataFrame(res_rows) | |
| return df_scen, df_adm, df_res | |
| def run(self, days_to_add): | |
| scen, adm, res = self.generate_batch(days=days_to_add) | |
| total_rows = len(scen) + len(adm) + len(res) | |
| with st.status(f"Injection de {total_rows} nouvelles lignes...", expanded=True) as status: | |
| st.write("Ajout au calendrier...") | |
| self._append_to_sheet(scen, "scenarios_calendrier") | |
| st.write(f"Ajout : {len(adm)} admissions...") | |
| self._append_to_sheet(adm, "admissions_jour") | |
| st.write(f"Ajout : {len(res)} relevés de ressources...") | |
| self._append_to_sheet(res, "ressources_jour") | |
| status.update(label="Injection terminée !", state="complete") | |
| return total_rows | |
| # --- INTERFACE --- | |
| def show_data_injector(client, sheet_name): | |
| st.markdown("## INJECTEUR DE FLUX (LIVE TEST)") | |
| st.caption("Ajoute des données récentes pour tester la réaction de l'IA et du Dashboard.") | |
| col1, col2 = st.columns([2, 1]) | |
| with col1: | |
| days = st.slider("Jours à simuler", min_value=1, max_value=14, value=7, | |
| help="7 jours génèrent environ 500 nouvelles lignes.") | |
| with col2: | |
| # Estimation du volume | |
| st.metric("Volume estimé", f"~{days * 9 * 6} lignes", delta="Nouveaux cas") | |
| # MODIFICATION ICI : Suppression de type='primary' pour éviter la couleur rouge | |
| if st.button("Injecter les données maintenant"): | |
| injector = DataInjector(client, sheet_name) | |
| count = injector.run(days) | |
| st.success(f"Opération réussie. {count} nouvelles lignes ont été ajoutées à la base.") | |
| st.warning("Note : Relancez l'ETL (Feature Engineering) pour que l'IA prenne en compte ces nouvelles données.") |