From cd8d73b41f1e32098ef96d7b952839663ad28080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9o=20BARAS=20=28IUT1=20Grenoble=29?= Date: Thu, 25 Jan 2024 19:42:22 +0100 Subject: [PATCH] Version 2 fonctionnelle --- app/pe/pe_etudiant.py | 4 ++- app/pe/pe_jury.py | 71 +++++++++++++++++++------------------ app/pe/pe_trajectoiretag.py | 8 ++--- app/pe/pe_view.py | 22 ++++++------ 4 files changed, 53 insertions(+), 52 deletions(-) diff --git a/app/pe/pe_etudiant.py b/app/pe/pe_etudiant.py index 26edc720..ea043f3d 100644 --- a/app/pe/pe_etudiant.py +++ b/app/pe/pe_etudiant.py @@ -142,7 +142,9 @@ class EtudiantsJuryPE: + ", ".join([str(fid) for fid in list(self.formsemestres_jury_ids)]) ) # Les abandons : - # sorted([etudiants.cursus[etudid]['nom'] for etudid in etudiants.cursus if etudid not in etudiants.diplomes_ids]) + self.abandons = sorted([self.cursus[etudid]['nom'] + for etudid in self.cursus if etudid not in self.diplomes_ids]) + def get_etudiants_diplomes(self) -> dict[int, Identite]: """Identités des étudiants (sous forme d'un dictionnaire `{etudid: Identite(etudid)}` diff --git a/app/pe/pe_jury.py b/app/pe/pe_jury.py index 1f858504..8e8f03fa 100644 --- a/app/pe/pe_jury.py +++ b/app/pe/pe_jury.py @@ -71,17 +71,17 @@ import numpy as np # ---------------------------------------------------------------------------------------- class JuryPE(object): """Classe mémorisant toutes les informations nécessaires pour établir un jury de PE. - Modèle basé sur NotesTable. + Modèle basé sur NotesTable. - Attributs : + Attributs : - * diplome : l'année d'obtention du diplome BUT et du jury de PE (généralement février XXXX) - * juryEtudDict : dictionnaire récapitulant les étudiants participant au jury PE (données administratives + - celles des semestres valides à prendre en compte permettant le calcul des moyennes ... - ``{'etudid : { 'nom', 'prenom', 'civilite', 'diplome', '', }}`` - - Rq: il contient à la fois les étudiants qui vont être diplomés à la date prévue - et ceux qui sont éliminés (abandon, redoublement, ...) pour affichage alternatif + * diplome : l'année d'obtention du diplome BUT et du jury de PE (généralement février XXXX) + * juryEtudDict : dictionnaire récapitulant les étudiants participant au jury PE (données administratives + + celles des semestres valides à prendre en compte permettant le calcul des moyennes ... + ``{'etudid : { 'nom', 'prenom', 'civilite', 'diplome', '', }}`` + a + Rq: il contient à la fois les étudiants qui vont être diplomés à la date prévue + et ceux qui sont éliminés (abandon, redoublement, ...) pour affichage alternatif """ # Variables de classe décrivant les aggrégats, leur ordre d'apparition temporelle et @@ -100,8 +100,6 @@ class JuryPE(object): meme_programme: si True, impose un même programme pour tous les étudiants participant au jury, si False, permet des programmes differents """ - self.promoTagDict = {} - "L'année du diplome" self.diplome = diplome @@ -113,8 +111,6 @@ class JuryPE(object): self.zipdata = io.BytesIO() self.zipfile = ZipFile(self.zipdata, "w") - - """Chargement des étudiants à prendre en compte dans le jury""" pe_comp.pe_print( f"*** Recherche et chargement des étudiants diplômés en {self.diplome} pour la formation {self.formation_id}" @@ -187,14 +183,19 @@ class JuryPE(object): # Export des données => mode 1 seule feuille -> supprimé pe_comp.pe_print("*** Export du jury de synthese") - filename = "synthese_jury_" + str(self.diplome) + '.xls' + filename = "synthese_jury_" + str(self.diplome) + ".xlsx" with pd.ExcelWriter(filename, engine="openpyxl") as writer: for onglet in self.synthese: df = self.synthese[onglet] - df.to_excel(writer, onglet, index=True, header=True) # écriture dans l'onglet + df.to_excel( + writer, onglet, index=True, header=True + ) # écriture dans l'onglet # worksheet = writer.sheets[onglet] # l'on - self.zipfile.write(filename) + self.add_file_to_zip( + filename, + open(filename, "rb").read(), + ) """Fin !!!! Tada :)""" @@ -208,7 +209,7 @@ class JuryPE(object): data: Les données du fichier path: Un dossier dans l'arborescence du zip """ - path_in_zip = os.path.join(self.nom_export_zip, path, filename) + path_in_zip = os.path.join(path, filename) # self.nom_export_zip, self.zipfile.writestr(path_in_zip, data) def get_zipped_data(self): @@ -231,7 +232,6 @@ class JuryPE(object): tags = sorted(set(tags)) return tags - # **************************************************************************************************************** # # Méthodes pour la synthèse du juryPE # ***************************************************************************************************************** @@ -251,7 +251,6 @@ class JuryPE(object): synthese[tag] = self.df_tag(tag) return synthese - def df_administratif(self): """Synthétise toutes les données administratives des étudiants""" @@ -270,10 +269,10 @@ class JuryPE(object): "Nom": etudiant.nom, "Prenom": etudiant.prenom, "Civilite": etudiant.civilite_str, - "Age": pe_comp.calcul_age(etudiant.date_naissance), + "Age": pe_comp.calcul_age(etudiant.date_naissance), "Date d'entree": cursus["entree"], "Date de diplome": cursus["diplome"], - "Nbre de semestres": len(formsemestres) + "Nbre de semestres": len(formsemestres), } # Ajout des noms de semestres parcourus @@ -281,9 +280,11 @@ class JuryPE(object): administratif[etudid] |= etapes """Construction du dataframe""" - df = pd.DataFrame.from_dict(administratif, orient='index') - return df + df = pd.DataFrame.from_dict(administratif, orient="index") + """Tri par nom/prénom""" + df.sort_values(by=["Nom", "Prenom"], inplace = True) + return df def df_tag(self, tag): """Génère le DataFrame synthétisant les moyennes/classements (groupe, @@ -299,7 +300,6 @@ class JuryPE(object): etudids = list(self.diplomes_ids) aggregats = pe_comp.TOUS_LES_PARCOURS - donnees = {} for etudid in etudids: @@ -315,18 +315,21 @@ class JuryPE(object): trajectoire = self.trajectoires.suivi[etudid][aggregat] """Les moyennes par tag de cette trajectoire""" if trajectoire: - trajectoire_tagguee = self.trajectoires_tagguees[trajectoire.trajectoire_id] + trajectoire_tagguee = self.trajectoires_tagguees[ + trajectoire.trajectoire_id + ] bilan = trajectoire_tagguee.moyennes_tags[tag] donnees[etudid] |= { f"{aggregat} notes ": f"{bilan['notes'].loc[etudid]:.1f}", f"{aggregat} class. (groupe)": f"{bilan['classements'].loc[etudid]}/{bilan['nb_inscrits']}", - f"{aggregat} min/moy/max (groupe)": f"{bilan['min']:.1f}/{bilan['moy']:.1f}/{bilan['max']:.1f}"} + f"{aggregat} min/moy/max (groupe)": f"{bilan['min']:.1f}/{bilan['moy']:.1f}/{bilan['max']:.1f}", + } else: donnees[etudid] |= { f"{aggregat} notes ": "-", f"{aggregat} class. (groupe)": "-", - f"{aggregat} min/moy/max (groupe)": "-" + f"{aggregat} min/moy/max (groupe)": "-", } """L'interclassement""" @@ -335,29 +338,29 @@ class JuryPE(object): bilan = interclass.moyennes_tags[tag] donnees[etudid] |= { - f"{aggregat} class. (promo)": f"{bilan['classements'].loc[etudid]}/{bilan['nb_inscrits']}", - f"{aggregat} min/moy/max (promo)": f"{bilan['min']:.1f}/{bilan['moy']:.1f}/{bilan['max']:.1f}" + f"{aggregat} class. (promo)": f"{bilan['classements'].loc[etudid]}/{bilan['nb_inscrits']}", + f"{aggregat} min/moy/max (promo)": f"{bilan['min']:.1f}/{bilan['moy']:.1f}/{bilan['max']:.1f}", } else: donnees[etudid] |= { f"{aggregat} class. (promo)": "-", - f"{aggregat} min/moy/max (promo)": "-" + f"{aggregat} min/moy/max (promo)": "-", } # Fin de l'aggrégat + """Construction du dataFrame""" + df = pd.DataFrame.from_dict(donnees, orient="index") - df = pd.DataFrame.from_dict(donnees, orient='index') + """Tri par nom/prénom""" + df.sort_values(by=["Nom", "Prenom"], inplace = True) return df - - def table_syntheseJury(self, mode="singlesheet"): # was str_syntheseJury """Table(s) du jury mode: singlesheet ou multiplesheet pour export excel """ sT = SeqGenTable() # le fichier excel à générer - if mode == "singlesheet": return sT.get_genTable("singlesheet") else: diff --git a/app/pe/pe_trajectoiretag.py b/app/pe/pe_trajectoiretag.py index de9449c2..71b665dc 100644 --- a/app/pe/pe_trajectoiretag.py +++ b/app/pe/pe_trajectoiretag.py @@ -93,9 +93,6 @@ class TrajectoireTag(TableTag): self.etuds = nt.etuds # assert self.etuds == trajectoire.suivi # manque-t-il des étudiants ? self.etudiants = {etud.etudid: etud.etat_civil for etud in self.etuds} - self.cursus = { - etudid: donnees_etudiants.cursus[etudid] for etudid in self.etudiants - } """Les tags extraits de tous les semestres""" self.tags_sorted = self.do_taglist() @@ -104,7 +101,7 @@ class TrajectoireTag(TableTag): self.notes_cube = self.compute_notes_cube() """Calcul les moyennes par tag sous forme d'un dataframe""" - etudids = self.get_etudids() + etudids = list(self.etudiants.keys()) self.notes = compute_tag_moy(self.notes_cube, etudids, self.tags_sorted) """Synthétise les moyennes/classements par tag""" @@ -166,8 +163,7 @@ class TrajectoireTag(TableTag): return etudids_x_tags_x_semestres - def get_etudids(self): - return list(self.etudiants.keys()) + def do_taglist(self): """Synthétise les tags à partir des semestres (taggués) aggrégés diff --git a/app/pe/pe_view.py b/app/pe/pe_view.py index 779e049d..e464ab34 100644 --- a/app/pe/pe_view.py +++ b/app/pe/pe_view.py @@ -45,8 +45,8 @@ from app.scodoc import sco_formsemestre from app.scodoc import html_sco_header from app.scodoc import sco_preferences -from app.pe import pe_tools -from app.pe import pe_jurype +from app.pe import pe_comp +from app.pe import pe_jury from app.pe import pe_avislatex @@ -75,7 +75,7 @@ def _pe_view_sem_recap_form(formsemestre_id): return "\n".join(H) + html_sco_header.sco_footer() # L'année du diplome - diplome = pe_tools.get_annee_diplome_semestre(sem_base) + diplome = pe_comp.get_annee_diplome_semestre(sem_base) H = [ html_sco_header.sco_header(page_title="Avis de poursuite d'études"), @@ -136,12 +136,12 @@ def pe_view_sem_recap( ) # L'année du diplome - diplome = pe_tools.get_annee_diplome_semestre(sem_base) + diplome = pe_comp.get_annee_diplome_semestre(sem_base) - jury = pe_jurype.JuryPE(diplome, sem_base.formation.formation_id) + jury = pe_jury.JuryPE(diplome, sem_base.formation.formation_id) # Ajout avis LaTeX au même zip: - etudids = list(jury.syntheseJury.keys()) + # etudids = list(jury.syntheseJury.keys()) # Récupération du template latex, du footer latex et du tag identifiant les annotations relatives aux PE # (chaines unicodes, html non quoté) @@ -187,11 +187,11 @@ def pe_view_sem_recap( ) # Ajout des annotations PE dans un fichier excel - sT = pe_avislatex.table_syntheseAnnotationPE(jury.syntheseJury, tag_annotation_pe) - if sT: - jury.add_file_to_zip( - jury.nom_export_zip + "_annotationsPE" + scu.XLSX_SUFFIX, sT.excel() - ) + # sT = pe_avislatex.table_syntheseAnnotationPE(jury.syntheseJury, tag_annotation_pe) + # if sT: + # jury.add_file_to_zip( + # jury.nom_export_zip + "_annotationsPE" + scu.XLSX_SUFFIX, sT.excel() + # ) if False: latex_pages = {} # Dictionnaire de la forme nom_fichier => contenu_latex