From 82713752c21da1bb28257bfdd993ec727a01968f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9o=20BARAS=20=28IUT1=20Grenoble=29?= Date: Wed, 24 Jan 2024 19:37:45 +0100 Subject: [PATCH] Mise en place des interclassements --- app/pe/pe_etudiant.py | 11 +- ..._interclassetag.py => pe_interclasstag.py} | 16 ++- app/pe/pe_jurype.py | 129 +++++++++--------- app/pe/pe_trajectoire.py | 3 +- app/pe/pe_trajectoiretag.py | 5 + 5 files changed, 85 insertions(+), 79 deletions(-) rename app/pe/{pe_interclassetag.py => pe_interclasstag.py} (92%) diff --git a/app/pe/pe_etudiant.py b/app/pe/pe_etudiant.py index 1c82d2387..fdbbc72b3 100644 --- a/app/pe/pe_etudiant.py +++ b/app/pe/pe_etudiant.py @@ -60,7 +60,9 @@ class EtudiantsJuryPE: self.trajectoires = {} "Les etudids des étudiants à considérer au jury (ceux qui seront effectivement diplômés)" + self.etudiants_diplomes = {} self.diplomes_ids = {} + "Les etudids des étudiants dont il faut calculer les moyennes/classements (même si d'éventuels abandons)" self.etudiants_ids = {} @@ -112,7 +114,8 @@ class EtudiantsJuryPE: pe_tools.pe_print() """Les étudiants à prendre dans le diplôme, étudiants ayant abandonnés non compris""" - self.diplomes_ids = self.get_etudiants_diplomes() + self.etudiants_diplomes = self.get_etudiants_diplomes() + self.diplomes_ids = set(self.etudiants_diplomes.keys()) """Les étudiants dont il faut calculer les moyennes""" self.etudiants_ids = {etudid for etudid in self.identites} @@ -122,16 +125,16 @@ class EtudiantsJuryPE: # Synthèse pe_tools.pe_print( - f" => {len(self.diplomes_ids)} étudiants à diplômer en {self.annee_diplome}" + f" => {len(self.etudiants_diplomes)} étudiants à diplômer en {self.annee_diplome}" ) - nbre_abandons = len(self.etudiants_ids) - len(self.diplomes_ids) + nbre_abandons = len(self.etudiants_ids) - len(self.etudiants_diplomes) pe_tools.pe_print(f" => {nbre_abandons} étudiants éliminer pour abandon") pe_tools.pe_print( f" => {len(self.formsemestres_jury_ids)} semestres dont il faut calculer la moyenne" ) pe_tools.pe_print( f" => quelques étudiants futurs diplômés : " - + ", ".join([str(etudid) for etudid in list(self.diplomes_ids)[:10]]) + + ", ".join([str(etudid) for etudid in list(self.etudiants_diplomes)[:10]]) ) pe_tools.pe_print( f" => semestres dont il faut calculer les moyennes : " diff --git a/app/pe/pe_interclassetag.py b/app/pe/pe_interclasstag.py similarity index 92% rename from app/pe/pe_interclassetag.py rename to app/pe/pe_interclasstag.py index 985837a6c..f20dbf24c 100644 --- a/app/pe/pe_interclassetag.py +++ b/app/pe/pe_interclasstag.py @@ -5,6 +5,7 @@ from app.pe.pe_tools import PE_DEBUG, pe_print import app.pe.pe_etudiant as pe_etudiant from app.pe.pe_etudiant import EtudiantsJuryPE from app.pe.pe_trajectoire import Trajectoire, TrajectoiresJuryPE +from app.pe.pe_trajectoiretag import TrajectoireTag from app.comp import moy_sem import pandas as pd @@ -34,7 +35,7 @@ class AggregatInterclasseTag(pe_tagtable.TableTag): pe_tagtable.TableTag.__init__(self, nom_aggregat) """Les étudiants diplômés et leurs trajectoires (cf. trajectoires.suivis)""" - self.diplomes_ids = etudiants.diplomes_ids + self.diplomes_ids = etudiants.etudiants_diplomes self.etudiants_diplomes = {etudid for etudid in self.diplomes_ids} """Les trajectoires (et leur version tagguées), en ne gardant que celles associées à l'aggrégat @@ -53,9 +54,9 @@ class AggregatInterclasseTag(pe_tagtable.TableTag): """Les trajectoires suivies par les étudiants du jury, en ne gardant que celles associées aux diplomés""" - self.suivis: dict[int, Trajectoire] = {} + self.suivi: dict[int, Trajectoire] = {} for etudid in self.diplomes_ids: - self.suivis[etudid] = trajectoires_jury_pe.suivis[etudid][nom_aggregat] + self.suivi[etudid] = trajectoires_jury_pe.suivi[etudid][nom_aggregat] """Les tags""" self.tags_sorted = self.do_taglist() @@ -77,6 +78,11 @@ class AggregatInterclasseTag(pe_tagtable.TableTag): "nb_inscrits": len(moy_gen_tag), } + def get_repr(self) -> str: + """Une représentation textuelle""" + return f"Aggrégat {self.nom}" + + def do_taglist(self): """Synthétise les tags à partir des trajectoires_tagguées @@ -89,8 +95,6 @@ class AggregatInterclasseTag(pe_tagtable.TableTag): tags.extend(trajectoire.tags_sorted) return sorted(set(tags)) - def get_etudids(self): - return list(self.etudiants_diplomes.keys()) def compute_notes_matrice(self): """Construit la matrice de notes (etudid x tags) @@ -101,7 +105,7 @@ class AggregatInterclasseTag(pe_tagtable.TableTag): nb_etudiants = len(self.diplomes_ids) """Index de la matrice (etudids -> dim 0, tags -> dim 1)""" - etudids = [etud.etudid for etud in self.diplomes_ids] + etudids = list(self.diplomes_ids) tags = self.tags_sorted """Partant d'un dataframe vierge""" diff --git a/app/pe/pe_jurype.py b/app/pe/pe_jurype.py index 5b36638fe..932d03e43 100644 --- a/app/pe/pe_jurype.py +++ b/app/pe/pe_jurype.py @@ -47,30 +47,23 @@ import io import os from zipfile import ZipFile -import app.pe.pe_etudiant -import app.pe.pe_settag_interclasse + from app.comp import res_sem from app.comp.res_compat import NotesTableCompat from app.comp.res_sem import load_formsemestre_results from app.models import Formation, FormSemestre from app.models.etudiants import Identite from app.pe.pe_semestretag import SemestreTag +from app.pe.pe_interclasstag import AggregatInterclasseTag +from app.pe.pe_trajectoiretag import TrajectoireTag from app.scodoc.gen_tables import GenTable, SeqGenTable import app.scodoc.sco_utils as scu -from app.scodoc import ( - codes_cursus, - sco_formsemestre_inscriptions, -) # codes_cursus.NEXT -> sem suivant -from app.scodoc import sco_etud -from app.scodoc import sco_report -from app.scodoc import sco_formsemestre -from app.pe import pe_tagtable +from app.scodoc import codes_cursus from app.pe import pe_tools from app.pe import pe_semestretag -from app.pe import pe_trajectoiretag from app.pe.pe_etudiant import EtudiantsJuryPE -from app.pe.pe_trajectoire import TrajectoiresJuryPE +from app.pe.pe_trajectoire import TrajectoiresJuryPE, Trajectoire # ---------------------------------------------------------------------------------------- @@ -143,6 +136,7 @@ class JuryPE(object): self.etudiants.find_etudiants(self.formation_id) """Génère les semestres taggués (avec le calcul des moyennes) pour le jury PE""" + pe_tools.pe_print("*** Génère les semestres taggués") self.semestres_taggues = compute_semestres_tag(self.etudiants) if pe_tools.PE_DEBUG: @@ -158,42 +152,50 @@ class JuryPE(object): """Génère les trajectoires (combinaison de semestres suivis par un étudiant pour atteindre le semestre final d'un aggrégat) """ + pe_tools.pe_print( + "*** Génère les trajectoires (différentes combinaisons de semestres) des étudiants" + ) self.trajectoires = TrajectoiresJuryPE(self.diplome) self.trajectoires.cree_trajectoires(self.etudiants) - - """Génère les aggrégats de semestre (par ex: 1A, 3S, 5S) avec calcul - des moyennes pour le jury""" + """Génère les moyennes par tags des trajectoires""" + pe_tools.pe_print("*** Calcule les moyennes par tag des trajectoires possibles") self.trajectoires_tagguees = compute_trajectoires_tag( - self.etudiants, self.semestres_taggues + self.trajectoires, self.etudiants, self.semestres_taggues ) if pe_tools.PE_DEBUG: - """Intègre le bilan des aggrégats de semestres au zip final""" - for aggregat in self.trajectoires_tagguees: - for fid in self.trajectoires_tagguees[aggregat]: - set_tag = self.trajectoires_tagguees[aggregat][fid] - filename = set_tag.nom.replace(" ", "_") + ".csv" - pe_tools.pe_print(f" - Export csv de {filename} ") - self.add_file_to_zip( - filename, set_tag.str_tagtable(), path="details_semestres" - ) + """Intègre le bilan des trajectoires tagguées au zip final""" + for trajectoire_id in self.trajectoires_tagguees: + trajectoire_tagguee = self.trajectoires_tagguees[trajectoire_id] + filename = trajectoire_tagguee.get_repr().replace(" ", "_") + ".csv" + pe_tools.pe_print(f" - Export csv de {filename} ") + self.add_file_to_zip( + filename, + trajectoire_tagguee.str_tagtable(), + path="details_semestres", + ) - """Génère les interclassements par (nom d') aggrégat""" - self.aggregats_taggues_interclasses = compute_interclassements( - self.etudiants, # - self.trajectoires_tagguees, + """Génère les interclassements (par promo et) par (nom d') aggrégat""" + pe_tools.pe_print("*** Génère les interclassements par aggrégat") + self.interclassements_taggues = compute_interclassements( + self.etudiants, self.trajectoires, self.trajectoires_tagguees ) - # Les interclassements - # -------------------- + if pe_tools.PE_DEBUG: - pe_tools.pe_print( - "*** Création des interclassements au sein de la promo sur différentes combinaisons de semestres" - ) + """Intègre le bilan des aggrégats (par promo) au zip final""" + for nom_aggregat in self.interclassements_taggues: + interclass_tag = self.interclassements_taggues[nom_aggregat] + filename = interclass_tag.get_repr().replace(" ", "_") + ".csv" + pe_tools.pe_print(f" - Export csv de {filename} ") + self.add_file_to_zip( + filename, + interclass_tag.str_tagtable(), + path="details_semestres", + ) """Synthèse des éléments du jury PE""" - if False: - self.synthetise_juryPE() + self.synthetise_juryPE() # Export des données => mode 1 seule feuille -> supprimé # filename = self.NOM_EXPORT_ZIP + "jurySyntheseDict_" + str(self.diplome) + '.xls' @@ -243,7 +245,7 @@ class JuryPE(object): # Méthodes pour la synthèse du juryPE # ***************************************************************************************************************** def synthetise_juryPE(self): - """Synthétise tous les résultats du jury PE dans un dictionnaire""" + """Synthétise tous les résultats du jury PE dans des dataframess""" self.syntheseJury = {} for etudid in self.etudiants.get_etudids(self.diplome): etudinfo = self.ETUDINFO_DICT[etudid] @@ -663,9 +665,11 @@ def compute_semestres_tag(etudiants: EtudiantsJuryPE): return semestres_tags -def compute_trajectoires_tag(trajectoires: TrajectoiresJuryPE, - etudiants: EtudiantsJuryPE, - semestres_taggues: dict[int, SemestreTag]): +def compute_trajectoires_tag( + trajectoires: TrajectoiresJuryPE, + etudiants: EtudiantsJuryPE, + semestres_taggues: dict[int, SemestreTag], +): """Créée les trajectoires tagguées (combinaison aggrégeant plusieurs semestres au sens d'un aggrégat (par ex: '3S')), en calculant les moyennes et les classements par tag pour chacune. @@ -694,16 +698,16 @@ def compute_trajectoires_tag(trajectoires: TrajectoiresJuryPE, trajectoires_tagguees = {} - for trajectoire_id in trajectoires_tagguees: - trajectoire = trajectoires[trajectoire_id] + for trajectoire_id in trajectoires.trajectoires: + trajectoire = trajectoires.trajectoires[trajectoire_id] nom = trajectoire.get_repr() pe_tools.pe_print(f" --> Fusion {nom}") """Création de la trajectoire_tagguee associée""" - trajectoire_tagguee = pe_trajectoiretag.TrajectoireTag( - nom, trajectoire, semestres_taggues, etudiants - ) + trajectoire_tagguee = TrajectoireTag( + nom, trajectoire, semestres_taggues, etudiants + ) """Mémorise le résultat""" trajectoires_tagguees[trajectoire_id] = trajectoire_tagguee @@ -711,33 +715,22 @@ def compute_trajectoires_tag(trajectoires: TrajectoiresJuryPE, return trajectoires_tagguees - def compute_interclassements( - etudiants: EtudiantsJuryPE, aggregats_taggues: dict[str, dict] + etudiants: EtudiantsJuryPE, + trajectoires_jury_pe: TrajectoiresJuryPE, + trajectoires_tagguees: dict[tuple, Trajectoire], ): """Interclasse les étudiants, (nom d') aggrégat par aggrégat, - pour fournir un classement sur la promo. Le classement est établit au regard du nombre + pour fournir un classement sur la promo. Le classement est établi au regard du nombre d'étudiants ayant participé au même aggrégat. """ - etudiants_diplomes = etudiants.get_etudiants_diplomes() + pe_tools.pe_print(" Interclassement sur la promo") - """ - for i, nom in enumerate(pe_tools.PARCOURS.keys()): - settag = app.pe.pe_settag_interclasse.SetTagInterClasse(nom, diplome=diplome) - nbreEtudInscrits = settag.set_Etudiants( - lesEtudids, self.etudiants.cursus, self.etudiants.identites + aggregats_interclasses_taggues = {} + for nom_aggregat in pe_tools.TOUS_LES_SEMESTRES + pe_tools.TOUS_LES_AGGREGATS: + pe_tools.pe_print(f" --> {nom_aggregat}") + interclass = AggregatInterclasseTag( + nom_aggregat, etudiants, trajectoires_jury_pe, trajectoires_tagguees ) - if nbreEtudInscrits > 0: - pe_tools.pe_print("%d) %s avec interclassement sur la promo" % (i + 1, nom)) - if nom in pe_tools.TOUS_LES_SEMESTRES: - settag.set_SetTagDict(self.semestres_taggues) - else: # cas des aggrégats - settag.set_SetTagDict(self.aggregats_taggues[nom]) - settag.comp_data_settag() - self.promoTagDict[nom] = settag - else: - pe_tools.pe_print( - "%d) Pas d'interclassement %s sur la promo faute de notes" - % (i + 1, nom) - ) - """ \ No newline at end of file + aggregats_interclasses_taggues[nom_aggregat] = interclass + return aggregats_interclasses_taggues diff --git a/app/pe/pe_trajectoire.py b/app/pe/pe_trajectoire.py index fbbf1ca85..415fee24d 100644 --- a/app/pe/pe_trajectoire.py +++ b/app/pe/pe_trajectoire.py @@ -91,7 +91,8 @@ class TrajectoiresJuryPE: for etudid in etudiants.cursus: if etudid not in self.suivi: - self.suivi[etudid] = {} + self.suivi[etudid] = {aggregat: None + for aggregat in pe_tools.TOUS_LES_SEMESTRES + pe_tools.TOUS_LES_AGGREGATS} """Le formsemestre terminal (dernier en date) associé au semestre marquant la fin de l'aggrégat diff --git a/app/pe/pe_trajectoiretag.py b/app/pe/pe_trajectoiretag.py index 547599e46..abefa0087 100644 --- a/app/pe/pe_trajectoiretag.py +++ b/app/pe/pe_trajectoiretag.py @@ -122,6 +122,11 @@ class TrajectoireTag(pe_tagtable.TableTag): "nb_inscrits": len(moy_gen_tag), } + def get_repr(self): + """Renvoie une représentation textuelle (celle de la trajectoire sur laquelle elle + est basée)""" + return self.trajectoire.get_repr() + def compute_notes_cube(self): """Construit le cube de notes (etudid x tags x semestre_aggregé) nécessaire au calcul des moyennes de l'aggrégat