CoolFace
Apppublic

SimonAugus/Planning

sourceHugging Facecc-by-nc-4.0updated 2y agoView on Hugging Face
0likes
app.py191 linesDownload Raw Back to root
1import pandas as pd2from datetime import datetime, timedelta3from openpyxl import Workbook4from openpyxl.styles import PatternFill5from openpyxl.worksheet.table import Table, TableStyleInfo6import gradio as gr7from transformers import pipeline8from concurrent.futures import ThreadPoolExecutor9 10# Charger le modèle Hugging Face11generator = pipeline("text-generation", model="gpt2")12 13# Fonction pour générer des suggestions IA14def generer_analyse_ia(tache, projet, statut, duree_restante):15    if statut == "En retard":16        prompt = (17            f"La tâche '{tache}' dans le projet '{projet}' est en retard. "18            f"Proposez des solutions pour optimiser les délais, comme intervertir des tâches, ajouter des ressources "19            f"(et précisez le nombre nécessaire), ou toute autre mesure pour réduire les délais finaux. "20            f"La durée restante est estimée à {duree_restante} heures."21        )22        try:23            suggestion = generator(24                prompt,25                max_length=100,  # Longueur totale (entrée + sortie)26                max_new_tokens=50,  # Tokens générés27                num_return_sequences=1,28                truncation=True  # Tronquer si l'entrée est trop longue29            )30            return suggestion[0]['generated_text']31        except Exception as e:32            return f"Erreur IA : {str(e)}"33    return "RAS"34 35# Fonction pour définir les heures de travail36def heures_ouvrables(jour, personnes):37    heures_par_jour = 8 * personnes38    heures = []39    if jour.weekday() in [0, 1, 2, 3]:40        heures = [f"{hour}:30" for hour in range(7, 16)] * (heures_par_jour // 8)41    elif jour.weekday() == 4:42        heures = [f"{hour}:30" for hour in range(7, 14)] * (heures_par_jour // 8)43    return heures44 45# Fonction principale pour analyser le fichier Excel46def analyser_planning(file, personnes):47    try:48        df = pd.read_excel(file)49        print("Fichier Excel chargé avec succès.")50    except Exception as e:51        return f"Erreur lors de la lecture du fichier Excel : {str(e)}"52 53    # Vérification des colonnes attendues54    colonnes_attendues = ['Code unique', 'Projet', 'Tâche', 'Durée (H)', 'Date Start', 'Date Limite']55    for colonne in colonnes_attendues:56        if colonne not in df.columns:57            return f"Erreur : La colonne '{colonne}' est absente du fichier."58 59    # Conversion des dates60    df['Date Start'] = pd.to_datetime(df['Date Start'], format="%Y-%m-%d", errors='coerce')61    df['Date Limite'] = pd.to_datetime(df['Date Limite'], format="%Y-%m-%d", errors='coerce')62 63    # Vérification des dates et durées64    if df['Date Start'].isnull().any():65        return "Erreur : Certaines dates dans 'Date Start' sont manquantes ou mal formatées."66    if df['Date Limite'].isnull().any():67        return "Erreur : Certaines dates dans 'Date Limite' sont manquantes ou mal formatées."68    if df['Durée (H)'].isnull().any() or not pd.api.types.is_numeric_dtype(df['Durée (H)']):69        return "Erreur : La colonne 'Durée (H)' contient des valeurs manquantes ou non numériques."70 71    # Création de l'agenda vide72    date_fin = datetime.now() + timedelta(days=30)73    all_hours = []74    for single_date in pd.date_range(start=datetime.now(), end=date_fin):75        for hour in range(7, 16):76            hour_str = f"{hour}:30"77            all_hours.append({78                "Date": single_date.strftime("%d/%m/%Y"),79                "Heure": hour_str,80                "Code unique": None,81                "Projet": None,82                "Tâche": None,83                "Date Limite": None,84                "Statut": "Libre",85                "Analyse IA": None86            })87 88    agenda_df = pd.DataFrame(all_hours)89 90    # Fonction pour traiter une ligne avec ThreadPoolExecutor91    def process_row(row):92        code = row['Code unique']93        projet = row['Projet']94        tache = row['Tâche']95        duree = row['Durée (H)'] / personnes96        date_limite = row['Date Limite']97        date_start = row['Date Start']98        date_actuelle = max(datetime.now(), date_start)99 100        while duree > 0:101            if date_actuelle.weekday() >= 5:  # Weekends102                date_actuelle += timedelta(days=1)103                continue104 105            daily_slots = agenda_df[106                (agenda_df['Date'] == date_actuelle.strftime("%d/%m/%Y")) & 107                (agenda_df['Statut'] == "Libre")108            ]109 110            for idx, slot in daily_slots.iterrows():111                if duree <= 0:112                    break113 114                statut = "À temps" if date_actuelle <= date_limite else "En retard"115                analyse_ia = generer_analyse_ia(tache, projet, statut, duree)116 117                agenda_df.at[idx, 'Code unique'] = code118                agenda_df.at[idx, 'Projet'] = projet119                agenda_df.at[idx, 'Tâche'] = tache120                agenda_df.at[idx, 'Date Limite'] = date_limite.strftime("%d/%m/%Y")121                agenda_df.at[idx, 'Statut'] = statut122                agenda_df.at[idx, 'Analyse IA'] = analyse_ia123                duree -= 1124 125            if duree > 0:126                date_actuelle += timedelta(days=1)127 128    # Utilisation de ThreadPoolExecutor pour paralléliser les appels129    try:130        with ThreadPoolExecutor(max_workers=5) as executor:131            executor.map(process_row, [row for _, row in df.iterrows()])132    except Exception as e:133        return f"Erreur lors de la planification des tâches : {str(e)}"134 135    # Exportation du fichier Excel136    output_file = "retroplanning.xlsx"137    try:138        with pd.ExcelWriter(output_file, engine='openpyxl') as writer:139            agenda_df.to_excel(writer, index=False, sheet_name="Rétroplanning")140 141            workbook = writer.book142            sheet = writer.sheets["Rétroplanning"]143 144            table = Table(displayName="RétroplanningTable", ref=f"A1:{chr(65+len(agenda_df.columns)-1)}{len(agenda_df)+1}")145            style = TableStyleInfo(146                name="TableStyleMedium9",147                showFirstColumn=False,148                showLastColumn=False,149                showRowStripes=True,150                showColumnStripes=True151            )152            table.tableStyleInfo = style153            sheet.add_table(table)154 155            fill = PatternFill(start_color="D9EAD3", end_color="D9EAD3", fill_type="solid")156            for cell in sheet[1]:157                cell.fill = fill158 159            for column_cells in sheet.columns:160                max_length = 0161                col_letter = column_cells[0].column_letter162                for cell in column_cells:163                    if cell.value:164                        max_length = max(max_length, len(str(cell.value)))165                sheet.column_dimensions[col_letter].width = max_length + 2166 167        print("Fichier Excel exporté avec succès.")168        return output_file169 170    except Exception as e:171        return f"Erreur lors de l'exportation du fichier : {str(e)}"172 173# Interface utilisateur avec Gradio174def interface_planning(file, personnes):175    result = analyser_planning(file, personnes)176    if result.endswith(".xlsx"):177        return result178    return f"Erreur : {result}"179 180interface = gr.Interface(181    fn=interface_planning,182    inputs=[183        gr.File(label="Téléchargez votre planning (format Excel)"),184        gr.Number(value=1, label="Nombre de personnes", precision=0)185    ],186    outputs=gr.File(label="Téléchargez votre rétroplanning généré"),187    title="Analyseur de Planning avec Rétroplanning et IA",188    description="Téléchargez un fichier Excel contenant votre planning brut et indiquez le nombre de personnes disponibles. L'IA analysera et ajoutera des suggestions pour optimiser le planning."189)190 191interface.launch()