From b8cb592ac93026d232b9f203da531e270ed547a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9o=20BARAS=20=28IUT1=20Grenoble=29?= Date: Fri, 16 Feb 2024 16:07:48 +0100 Subject: [PATCH] =?UTF-8?q?Calcul=20des=20RCS=20de=20type=20Sx=20(avec=20s?= =?UTF-8?q?=C3=A9lection=20du=20max=20des=20UEs=20des=20redoublants)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/pe/pe_jury.py | 64 +++++++++++++++++++------- app/pe/pe_moytag.py | 66 ++++++++++++++++++++++++--- app/pe/pe_rcstag.py | 4 +- app/pe/pe_ressemtag.py | 52 +++++++-------------- app/pe/pe_semtag.py | 100 ++++++++++++++++++++++++++++------------- app/pe/pe_tabletags.py | 34 ++++++++++++-- 6 files changed, 224 insertions(+), 96 deletions(-) diff --git a/app/pe/pe_jury.py b/app/pe/pe_jury.py index bfe72bd2d..70d97237d 100644 --- a/app/pe/pe_jury.py +++ b/app/pe/pe_jury.py @@ -50,6 +50,7 @@ from zipfile import ZipFile import numpy as np import pandas as pd +from app.pe import pe_semtag from app.pe.pe_affichage import NOM_STAT_PROMO, SANS_NOTE, NOM_STAT_GROUPE import app.pe.pe_affichage as pe_affichage from app.pe.pe_etudiant import * # TODO A éviter -> pe_etudiant. @@ -96,7 +97,9 @@ class JuryPE(object): pe_affichage.pe_print("*** Aucun étudiant diplômé") else: self._gen_xls_diplomes(zipfile) + self._gen_rcss() self._gen_xls_resultats_semestres_taggues(zipfile) + self._gen_xls_semestres_taggues(zipfile) # self._gen_xls_rcss_tags(zipfile) # self._gen_xls_interclassements_rcss(zipfile) # self._gen_xls_synthese_jury_par_tag(zipfile) @@ -142,12 +145,53 @@ class JuryPE(object): output, engine="openpyxl" ) as writer: for res_sem_tag in self.res_sems_tags.values(): - onglet = res_sem_tag.get_repr() + onglet = res_sem_tag.get_repr(verbose=False) df = res_sem_tag.df_moyennes_et_classements() # écriture dans l'onglet df.to_excel(writer, onglet, index=True, header=True) output.seek(0) + self.add_file_to_zip( + zipfile, + f"resultats_semestres_taggues_{self.diplome}.xlsx", + output.read(), + path="details", + ) + + def _gen_rcss(self): + """Génère les RCS (attribut `rcss_jury`), combinaisons de semestres suivis par les étudiants au sens + d'un nom de RCS (par ex: '3S'). + """ + pe_affichage.pe_print( + "*** Génère les RCS (différentes combinaisons de semestres) des étudiants" + ) + self.rcss_jury = pe_rcs.RCSsJuryPE(self.diplome) + self.rcss_jury.cree_rcss(self.etudiants) + + def _gen_xls_semestres_taggues(self, zipfile: ZipFile): + """Génère les semestres taggués en s'appuyant sur les RCS de type Sx (pour + identifier les redoublements impactant les semestres taggués). + """ + # Génère les moyennes des RCS de type Sx + pe_affichage.pe_print("*** Calcule les moyennes de semestres = RCS de type Sx") + + self.sems_tags = {} + for rcs_id, rcs in self.rcss_jury.rcss.items(): + if rcs.nom.startswith("S"): + self.sems_tags[rcs_id] = pe_semtag.SemTag(rcs, self.res_sems_tags) + + # Intègre le bilan des semestres taggués au zip final + output = io.BytesIO() + with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated + output, engine="openpyxl" + ) as writer: + for sem_tag in self.sems_tags.values(): + onglet = sem_tag.get_repr(verbose=False) + df = sem_tag.df_moyennes_et_classements() + # écriture dans l'onglet + df.to_excel(writer, onglet, index=True, header=True) + output.seek(0) + self.add_file_to_zip( zipfile, f"semestres_taggues_{self.diplome}.xlsx", @@ -156,11 +200,7 @@ class JuryPE(object): ) def _gen_xls_rcss_tags(self, zipfile: ZipFile): - """Génère : - - * les RCS (combinaisons de semestres suivis par les étudiants au sens - d'un aggrégat (par ex: '3S')) - * les RCS tagguées des RCS, en calculant les moyennes et les classements par tag + """Génère les RCS tagguées des RCS, en calculant les moyennes et les classements par tag pour chacune. Stocke le résultat dans self.rccs_tag, un dictionnaire de @@ -183,14 +223,9 @@ class JuryPE(object): """ - pe_affichage.pe_print( - "*** Génère les trajectoires (différentes combinaisons de semestres) des étudiants" - ) - self.rcss_jury = pe_rcs.RCSsJuryPE(self.diplome) - self.rcss_jury.cree_rcss(self.etudiants) - # Génère les moyennes par tags des trajectoires - pe_affichage.pe_print("*** Calcule les moyennes par tag des RCS possibles") + # Génère les moyennes des RCS de type Sx + pe_affichage.pe_print("*** Calcule les moyennes des RCS de type Sx") self.rcss_tags = {} for rcs_id, rcs in self.rcss_jury.rcss.items(): @@ -597,9 +632,6 @@ def compute_resultats_semestres_tag(etudiants: EtudiantsJuryPE) -> dict: return semestres_tags - - - def compute_interclassements( etudiants: EtudiantsJuryPE, trajectoires_jury_pe: pe_rcs.RCSsJuryPE, diff --git a/app/pe/pe_moytag.py b/app/pe/pe_moytag.py index 159661d19..a2428f34a 100644 --- a/app/pe/pe_moytag.py +++ b/app/pe/pe_moytag.py @@ -1,9 +1,11 @@ import numpy as np import pandas as pd +from app import comp from app.comp.moy_sem import comp_ranks_series from app.models import UniteEns from app.pe import pe_affichage +from app.scodoc.codes_cursus import UE_SPORT class Moyenne: @@ -157,8 +159,9 @@ class MoyennesTag: def __init__( self, tag: str, - ues: list[UniteEns], + ues: dict[int, UniteEns], notes_ues: pd.DataFrame, + ues_inscr_parcours_df: pd.DataFrame # notes_gen: pd.Series, ): """Classe centralisant la synthèse des moyennes/classements d'une série @@ -169,23 +172,41 @@ class MoyennesTag: tag: Un tag ues: La liste des UEs ayant servie au calcul de la moyenne notes_ues: Les moyennes (etudid x acronymes_ues) aux différentes UEs et pour le tag + ues_inscr_parcours_df: Les inscriptions des etudid au UE # notes_gen: Une série de notes (moyenne) sous forme d'un pd.Series() (toutes UEs confondues) """ self.tag = tag """Le tag associé aux moyennes""" # Les UE - self.ues: dict[int, UniteEns] = {ue.id: ue for ue in ues} + self.ues: dict[int, UniteEns] = ues """Les UEs sur lesquelles sont calculées les moyennes""" + colonnes = list(notes_ues.columns) - acronymes = [self.ues[ue_id].acronyme for ue_id in colonnes] - assert len(set(acronymes)) == len(colonnes), \ - "Deux UEs ne peuvent pas avoir le même acronyme" + acronymes: list[str] = [self.ues[ue_id].acronyme for ue_id in self.ues] + assert len(set(acronymes)) == len( + colonnes + ), "Deux UEs ne peuvent pas avoir le même acronyme" + + # Les inscriptions des etudids aux UEs + self.ues_inscr_parcours_df: pd.DataFrame = ues_inscr_parcours_df + """Les inscriptions des etudids au UE en fonction de leur parcours""" + + # Les coefficients à appliquer aux UEs pour la moyenne générale = ECTS + self.ects = self.ues_inscr_parcours_df.fillna(0.0) * [ + ue.ects + for ue in self.ues.values() # if ue.type != UE_SPORT <= déjà supprimé + ] + # Les profils d'ects (pour debug) + profils_ects = [] + for val in list(self.ects.values): + if tuple(val) not in profils_ects: + profils_ects.append(tuple(val)) # Les moyennes par UE - self.notes_ues = notes_ues + self.notes_ues: pd.DataFrame = notes_ues """Les notes aux UEs (dataframe)""" - self.notes_ues.columns = acronymes # remplace les ue.id par leur acronyme + self.notes_ues.columns = acronymes # remplace les ue.id par leur acronyme self.moys_ues: dict[int, pd.DataFrame] = {} """Les dataframes retraçant les moyennes/classements/statistiques des étudiants aux UEs""" for ue in self.ues.values(): # if ue.type != UE_SPORT: @@ -193,11 +214,42 @@ class MoyennesTag: self.moys_ues[ue.acronyme] = Moyenne(notes) # Les moyennes générales + notes_gen = self.compute_moy_gen(self.notes_ues, self.ects) self.notes_gen = notes_gen """Les notes générales (moyenne toutes UEs confonudes)""" self.moy_gen = Moyenne(notes_gen) """Le dataframe retraçant les moyennes/classements/statistiques général""" + pe_affichage.pe_print(f"> MoyTag pour {tag} avec") + pe_affichage.pe_print(f" - ues={acronymes}") + pe_affichage.pe_print(f" - ects={profils_ects}") + + def __eq__(self, other): """Egalité de deux MoyenneTag lorsque leur tag sont identiques""" return self.tag == other.tag + + def compute_moy_gen( + self, moy_ues: pd.DataFrame, coeff_ues: pd.DataFrame + ) -> pd.Series: + """Calcule la moyenne générale (toutes UE confondus) + pour le tag considéré, en pondérant les notes obtenues au UE + par les crédits ECTS. + + Args: + moy_ues: Les moyennes etudids x acronymes_ues + coeff_ues: Les coeff etudids x ueids + """ + + # Calcule la moyenne générale dans le semestre (pondérée par le ECTS) + try: + moy_gen_tag = comp.moy_sem.compute_sem_moys_apc_using_ects( + moy_ues, + coeff_ues, + # formation_id=self.formsemestre.formation_id, + skip_empty_ues=True, + ) + except TypeError as e: + raise TypeError("Pb dans le calcul de la moyenne toutes UEs confondues") + + return moy_gen_tag diff --git a/app/pe/pe_rcstag.py b/app/pe/pe_rcstag.py index f44ba13ae..ef4585894 100644 --- a/app/pe/pe_rcstag.py +++ b/app/pe/pe_rcstag.py @@ -94,7 +94,7 @@ class RCSTag(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.etats_civils = {etud.etudid: etud.nomprenom for etud in self.etuds} self.tags_sorted = self.do_taglist() """Tags extraits de tous les semestres""" @@ -102,7 +102,7 @@ class RCSTag(TableTag): self.notes_cube = self.compute_notes_cube() """Cube de notes""" - etudids = list(self.etudiants.keys()) + etudids = list(self.etats_civils.keys()) self.notes = compute_tag_moy(self.notes_cube, etudids, self.tags_sorted) """Calcul les moyennes par tag sous forme d'un dataframe""" diff --git a/app/pe/pe_ressemtag.py b/app/pe/pe_ressemtag.py index 8729580f4..5dff02eac 100644 --- a/app/pe/pe_ressemtag.py +++ b/app/pe/pe_ressemtag.py @@ -70,19 +70,15 @@ class ResSemTag(TableTag): self.formsemestre = FormSemestre.get_formsemestre(formsemestre_id) # Le nom du res_semestre taggué - self.nom = self.get_repr(mode="long") + self.nom = self.get_repr(verbose=True) - pe_affichage.pe_print( - f"--> Résultats de Semestre taggués {self.nom}" - ) + pe_affichage.pe_print(f"--> Résultats de semestre taggués {self.nom}") # Les résultats du semestre self.nt = load_formsemestre_results(self.formsemestre) - # Les étudiants - self.etuds = self.nt.etuds - self.etudiants = {etud.etudid: etud.etat_civil for etud in self.etuds} - self.etudids = list(self.etudiants.keys()) + # Les étudiants (etuds, états civils & etudis) + self.add_etuds(self.nt.etuds) # Les notes, les modules implémentés triés, les étudiants, les coeffs, # récupérés notamment de py:mod:`res_but` @@ -109,12 +105,17 @@ class ResSemTag(TableTag): for tag in tags_dict["personnalises"]: # pe_affichage.pe_print(f" -> Traitement du tag {tag}") - infos_tag = tags_dict["personnalises"][tag] + infos_tag = tags_dict["personnalises"][tag] moy_ues_tag = self.compute_moy_ues_tag(infos_tag) # moy_gen_tag = self.compute_moy_gen_tag(moy_ues_tag) + ues_dict = {ue.id: ue for ue in ues_hors_sport} self.moyennes_tags[tag] = MoyennesTag( - tag, ues_hors_sport, moy_ues_tag # moy_gen_tag + tag, + ues_dict, + moy_ues_tag, + self.ues_inscr_parcours_df + # moy_gen_tag ) # Ajoute les d'UE moyennes générales de BUT pour le semestre considéré @@ -128,8 +129,10 @@ class ResSemTag(TableTag): ) # moy_ues = self.nt.etud_moy_ue[ue_id] # moy_gen_but = self.nt.etud_moy_gen + ues_dict = {ue.id: ue for ue in ues_hors_sport} + self.moyennes_tags["but"] = MoyennesTag( - "but", ues_hors_sport, df_ues #, moy_gen_but + "but", ues_dict, df_ues, self.ues_inscr_parcours_df # , moy_gen_but ) self.tags_sorted = self.get_all_tags() @@ -144,11 +147,11 @@ class ResSemTag(TableTag): # f" => Traitement des tags {', '.join(self.tags_sorted)}" # ) - def get_repr(self, mode="long"): + def get_repr(self, verbose=False): """Nom affiché pour le semestre taggué""" - if mode == "short": + if verbose: return f"{self.formsemestre} ({self.formsemestre_id})" - else: # mode == "long" + else: return pe_etudiant.nom_semestre_etape(self.formsemestre, avec_fid=True) def compute_moy_ues_tag(self, info_tag: dict[int, dict]) -> pd.DataFrame: @@ -192,25 +195,6 @@ class ResSemTag(TableTag): ) return moyennes_ues_tag - def compute_moy_gen_tag(self, moy_ues_tag: pd.DataFrame) -> pd.Series: - """Calcule la moyenne générale (toutes UE confondus) - pour le tag considéré, en les pondérant par les crédits ECTS. - """ - # Les ects - ects = self.ues_inscr_parcours_df.fillna(0.0) * [ - ue.ects for ue in self.ues if ue.type != UE_SPORT - ] - - # Calcule la moyenne générale dans le semestre (pondérée par le ECTS) - moy_gen_tag = comp.moy_sem.compute_sem_moys_apc_using_ects( - moy_ues_tag, - ects, - formation_id=self.formsemestre.formation_id, - skip_empty_ues=True, - ) - - return moy_gen_tag - def _get_tags_dict(self): """Renvoie les tags personnalisés (déduits des modules du semestre) et les tags automatiques ('but'), et toutes leurs informations, @@ -272,8 +256,6 @@ class ResSemTag(TableTag): raise ScoValueError(message) - - def get_moduleimpl(modimpl_id) -> dict: """Renvoie l'objet modimpl dont l'id est modimpl_id""" modimpl = db.session.get(ModuleImpl, modimpl_id) diff --git a/app/pe/pe_semtag.py b/app/pe/pe_semtag.py index 645c3da7a..d98cd0848 100644 --- a/app/pe/pe_semtag.py +++ b/app/pe/pe_semtag.py @@ -49,7 +49,7 @@ from app.pe.pe_moytag import MoyennesTag class SemTag(TableTag): - def __init__(self, rcs: RCS, semestres_taggues: dict[int, ResSemTag]): + def __init__(self, rcs: RCS, res_sems_tags: dict[int, ResSemTag]): """Calcule les moyennes/classements par tag à un RCS d'un seul semestre (ici semestre) de type 'Sx' (par ex. 'S1', 'S2', ...) : @@ -62,7 +62,7 @@ class SemTag(TableTag): Args: rcs: Un RCS (identifié par un nom et l'id de son semestre terminal) - semestres_taggues: Les données sur les semestres taggués + res_sems_tags: Les données sur les résultats des semestres taggués """ TableTag.__init__(self) @@ -88,27 +88,20 @@ class SemTag(TableTag): self.semestres_aggreges = rcs.semestres_aggreges """Les semestres aggrégés""" - self.semestres_tags_aggreges = {} - """Les semestres tags associés aux semestres aggrégés""" + self.res_sems_tags = {} + """Les résultats des semestres taggués (limités aux semestres aggrégés)""" try: for frmsem_id in self.semestres_aggreges: - self.semestres_tags_aggreges[frmsem_id] = semestres_taggues[frmsem_id] + self.res_sems_tags[frmsem_id] = res_sems_tags[frmsem_id] except: - raise ValueError("Semestres taggués manquants") + raise ValueError("Résultats des semestres taggués manquants") - # Les données des étudiants - self.etuds = nt.etuds - """Les étudiants""" - self.etudids = [etud.etudid for etud in self.etuds] - """Les etudids""" - self.etats_civils = { - etudid: self.etuds[etudid].etat_civil for etudid in self.etudids - } - """Les états civils""" + # Les étudiants (etuds, états civils & etudis) + self.add_etuds(nt.etuds) # Les tags self.tags_sorted = self.comp_tags_list() - """Tags extraits du semestre terminal de l'aggrégat""" + """Tags (extraits uniquement du semestre terminal de l'aggrégat)""" # Les UEs self.ues = self.comp_ues(tag="but") @@ -116,20 +109,33 @@ class SemTag(TableTag): """UEs extraites du semestre terminal de l'aggrégat (avec check de concordance sur les UE des semestres_aggrégés)""" + # Les inscriptions aux UEs + self.ues_inscr_parcours_df = self.comp_ues_inscr_parcours(tag="but") + """Les inscriptions aux UEs (extraites uniquement du semestre terminal)""" + self.moyennes_tags: dict[str, MoyennesTag] = {} """Moyennes/classements par tag (qu'ils soient personnalisés ou automatiques)""" - self.notes: dict[str, pd.DataFrame] = {} - """Les notes aux différents tags""" + self.moyennes_tags: dict[str, pd.DataFrame] = {} + """Les notes aux UEs dans différents tags""" + # Masque des inscriptions + inscr_mask = self.ues_inscr_parcours_df.to_numpy() for tag in self.tags_sorted: # Cube de note - notes_cube = self.compute_notes_ues_cube(tag, self.acronymes_ues) + notes_cube = self.compute_notes_ues_cube(tag, self.acronymes_ues_sorted) # Calcule des moyennes sous forme d'un dataframe""" - self.notes[tag] = compute_notes_ues(notes_cube, self.etudids, self.acronymes_ues) - + moys_ues = compute_notes_ues( + notes_cube, + self.etudids, + self.acronymes_ues_sorted, + inscr_mask, + ) # Les moyennes - self.moyennes_tags[tag] = MoyennesTag(tag, self.notes[tag]) + self.moyennes_tags[tag] = MoyennesTag(tag, + self.ues, + moys_ues, + self.ues_inscr_parcours_df) def __eq__(self, other): """Egalité de 2 RCS taggués sur la base de leur identifiant""" @@ -147,7 +153,7 @@ class SemTag(TableTag): # Index du cube (etudids -> dim 0, ues -> dim 1, semestres -> dim2) etudids = [etud.etudid for etud in self.etuds] # acronymes_ues = sorted([ue.acronyme for ue in self.ues.values()]) - semestres_id = list(self.semestres_tags_aggreges.keys()) + semestres_id = list(self.res_sems_tags.keys()) dfs = {} @@ -156,10 +162,12 @@ class SemTag(TableTag): df = pd.DataFrame(np.nan, index=etudids, columns=acronymes_ues_sorted) # Charge les notes du semestre tag - sem_tag = self.semestres_tags_aggreges[frmsem_id] + sem_tag = self.res_sems_tags[frmsem_id] moys_tag = sem_tag.moyennes_tags[tag] - notes = moys_tag.notes_ues # dataframe etudids x ues - acronymes_ues_sem = list(notes.columns) # les acronymes des UEs du semestre tag + notes = moys_tag.notes_ues # dataframe etudids x ues + acronymes_ues_sem = list( + notes.columns + ) # les acronymes des UEs du semestre tag # UEs communes à celles du SemTag (celles du dernier semestre du RCS) ues_communes = list(set(acronymes_ues_sorted) & set(acronymes_ues_sem)) @@ -168,7 +176,9 @@ class SemTag(TableTag): etudids_communs = df.index.intersection(notes.index) # Recopie - df.loc[etudids_communs, ues_communes] = notes.loc[etudids_communs, ues_communes] + df.loc[etudids_communs, ues_communes] = notes.loc[ + etudids_communs, ues_communes + ] # Supprime tout ce qui n'est pas numérique for col in df.columns: @@ -182,7 +192,7 @@ class SemTag(TableTag): etudids_x_ues_x_semestres = np.stack(semestres_x_etudids_x_ues, axis=-1) return etudids_x_ues_x_semestres - def comp_tags_list(self): + def comp_tags_list(self) -> list[str]: """Récupère les tag du semestre taggué associé au semestre final du RCS Returns: @@ -190,7 +200,7 @@ class SemTag(TableTag): """ tags = [] dernier_frmid = self.formsemestre_terminal.formsemestre_id - dernier_semestre_tag = self.semestres_tags_aggreges[dernier_frmid] + dernier_semestre_tag = self.res_sems_tags[dernier_frmid] tags = dernier_semestre_tag.tags_sorted pe_affichage.pe_print(f"* Tags : {', '.join(tags)}") return tags @@ -203,12 +213,29 @@ class SemTag(TableTag): Un dictionnaire donnant les UEs """ dernier_frmid = self.formsemestre_terminal.formsemestre_id - dernier_semestre_tag = self.semestres_tags_aggreges[dernier_frmid] + dernier_semestre_tag = self.res_sems_tags[dernier_frmid] moy_tag = dernier_semestre_tag.moyennes_tags[tag] return moy_tag.ues # les UEs + def comp_ues_inscr_parcours(self, tag="but") -> pd.DataFrame: + """Récupère les informations d'inscription des étudiants aux UEs : ne + conserve que les UEs du semestre terminal (pour les redoublants) -def compute_notes_ues(set_cube: np.array, etudids: list, acronymes_ues: list): + Returns: + Un dataFrame etudids x UE indiquant si un étudiant est inscrit à une UE + """ + dernier_frmid = self.formsemestre_terminal.formsemestre_id + dernier_semestre_tag = self.res_sems_tags[dernier_frmid] + moy_tag = dernier_semestre_tag.moyennes_tags[tag] + return moy_tag.ues_inscr_parcours_df + + +def compute_notes_ues( + set_cube: np.array, + etudids: list, + acronymes_ues: list, + inscr_mask: np.array, +): """Calcule la moyenne par UEs à un tag donné en prenant la note maximum (UE par UE) obtenue par un étudiant à un semestre. @@ -217,18 +244,27 @@ def compute_notes_ues(set_cube: np.array, etudids: list, acronymes_ues: list): (semestre_ids x etudids x UEs), des floats avec des NaN etudids: liste des étudiants (dim. 0 du cube) acronymes_ues: liste des acronymes des ues (dim. 1 du cube) + inscr_mask: masque etudids x UE traduisant les inscriptions des + étudiants aux UE (du semestre terminal) Returns: Un DataFrame avec pour columns les moyennes par ues, et pour rows les etudid """ nb_etuds, nb_ues, nb_semestres = set_cube.shape + nb_etuds_mask, nb_ues_mask = inscr_mask.shape assert nb_etuds == len(etudids) assert nb_ues == len(acronymes_ues) + assert nb_etuds == nb_etuds_mask + assert nb_ues == nb_ues_mask # Quelles entrées du cube contiennent des notes ? mask = ~np.isnan(set_cube) - # Enlève les NaN du cube pour les entrées manquantes + # Entrées à garder dans le cube en fonction du mask d'inscription + inscr_mask_3D = np.stack([inscr_mask]*nb_semestres, axis=-1) + set_cube = set_cube*inscr_mask_3D + + # Enlève les NaN du cube pour les entrées manquantes : NaN -> -1.0 set_cube_no_nan = np.nan_to_num(set_cube, nan=-1.0) # Les moyennes par ues diff --git a/app/pe/pe_tabletags.py b/app/pe/pe_tabletags.py index a31df3005..f876dedb3 100644 --- a/app/pe/pe_tabletags.py +++ b/app/pe/pe_tabletags.py @@ -39,6 +39,8 @@ Created on Thu Sep 8 09:36:33 2016 import pandas as pd +from app.models import Identite + TAGS_RESERVES = ["but"] @@ -47,7 +49,23 @@ class TableTag(object): """Classe centralisant différentes méthodes communes aux SemestreTag, TrajectoireTag, AggregatInterclassTag """ - pass + # Les étudiants + self.etuds: list[Identite] = None # A venir + """Les étudiants""" + self.etats_civils: dict[int, Identite] = None + """Les états civils""" + self.etudids: list[int] = None + """Les etudids""" + + def add_etuds(self, etuds: list[Identite]): + """Mémorise les informations sur les étudiants + + Args: + etuds: la liste des identités de l'étudiant + """ + self.etuds = etuds + self.etats_civils = {etud.etudid: etud.etat_civil for etud in self.etuds} + self.etudids = list(self.etats_civils.keys()) def get_all_tags(self): """Liste des tags de la table, triée par ordre alphabétique, @@ -70,15 +88,23 @@ class TableTag(object): Le dataframe des notes et des classements """ - etudiants = self.etudiants + etudiants = self.etats_civils df = pd.DataFrame.from_dict(etudiants, orient="index", columns=["nom"]) tags_tries = self.get_all_tags() for tag in tags_tries: moy_tag = self.moyennes_tags[tag] + for acronyme in moy_tag.moys_ues: + moy = moy_tag.moys_ues[acronyme] # une moyenne + df = df.join(moy.synthese["notes"].rename(f"Moy {tag}-{acronyme}")) + df = df.join( + moy.synthese["classements"].rename(f"Class {tag}-{acronyme}") + ) moy_gen = moy_tag.moy_gen - df = df.join(moy_gen.synthese["notes"].rename(f"Moy {tag}")) - df = df.join(moy_gen.synthese["classements"].rename(f"Class {tag}")) + df = df.join(moy_gen.synthese["notes"].rename(f"Moy {tag} (gen)")) + df = df.join(moy_gen.synthese["classements"].rename(f"Class {tag} (gen)")) + + df.sort_values(by=['nom']) return df