diff --git a/app/pe/pe_settag.py b/app/pe/pe_settag.py index e2f0a4f8..74a0cb22 100644 --- a/app/pe/pe_settag.py +++ b/app/pe/pe_settag.py @@ -35,9 +35,16 @@ Created on Fri Sep 9 09:15:05 2016 @author: barasc """ - +from app.comp.res_sem import load_formsemestre_results +from app.models import FormSemestre +from app.pe.pe_semestretag import SemestreTag from app.pe.pe_tools import pe_print, PE_DEBUG from app.pe import pe_tagtable +import pandas as pd +import numpy as np + + +from app.pe.pe_etudiant import EtudiantsJuryPE class SetTag(pe_tagtable.TableTag): @@ -50,80 +57,88 @@ class SetTag(pe_tagtable.TableTag): un etudiant non inscrit dans un S1 mais dans un S2 et un S3 n'est pas pris en compte). """ - # ------------------------------------------------------------------------------------------------------------------- - def __init__(self, nom_combinaison, parcours): - pe_tagtable.TableTag.__init__(self, nom=nom_combinaison) - self.combinaison = nom_combinaison - self.parcours = parcours # Le groupe de semestres/parcours à aggréger - - # ------------------------------------------------------------------------------------------- - def set_Etudiants( - self, etudiants: list[dict], juryPEDict, etudInfoDict, nom_sem_final=None + def __init__( + self, + nom, + formsemestre_terminal: FormSemestre, + semestres_aggreges: dict[int, FormSemestre], + semestres_taggues: dict[int, SemestreTag], + donnees_etudiants: EtudiantsJuryPE, ): - """Détermine la liste des étudiants à prendre en compte, en partant de - la liste en paramètre et en vérifiant qu'ils ont tous un parcours valide.""" - if nom_sem_final: - self.nom += "_" + nom_sem_final - for etudid in etudiants: - parcours_incomplet = ( - sum([juryPEDict[etudid][nom_sem] is None for nom_sem in self.parcours]) - > 0 - ) # manque-t-il des formsemestre_id validant aka l'étudiant n'a pas été inscrit dans tous les semestres de l'aggrégat - if not parcours_incomplet: - self.inscrlist.append(etudInfoDict[etudid]) - self.identdict[etudid] = etudInfoDict[etudid] + pe_tagtable.TableTag.__init__(self, nom) - delta = len(etudiants) - len(self.inscrlist) - if delta > 0: - pe_print(self.nom + " -> " + str(delta) + " étudiants supprimés") + """Le formsemestre terminal et les semestres aggrégés""" + self.formsemestre_terminal = formsemestre_terminal + nt = load_formsemestre_results(formsemestre_terminal) + self.semestres_aggreges = semestres_aggreges - # Le sous-ensemble des parcours - self.parcoursDict = {etudid: juryPEDict[etudid] for etudid in self.identdict} - - # ------------------------------------------------------------------------------------------- - def get_Fids_in_settag(self): - """Renvoie la liste des semestres (leur formsemestre_id) à prendre en compte - pour le calcul des moyennes, en considérant tous les étudiants inscrits et - tous les semestres de leur parcours""" - return list( - { - self.parcoursDict[etudid][nom_sem] - for etudid in self.identdict - for nom_sem in self.parcours + """Les semestres tags associés aux semestres aggrégés""" + try: + self.semestres_tags_aggreges = { + frmsem_id: semestres_taggues[frmsem_id] + for frmsem_id in semestres_taggues } - ) + except: + raise ValueError("Semestres taggués manquants") - # --------------------------------------------------------------------------------------------- - def set_SemTagDict(self, SemTagDict): - """Mémorise les semtag nécessaires au jury.""" - self.SemTagDict = {fid: SemTagDict[fid] for fid in self.get_Fids_in_settag()} - if PE_DEBUG >= 1: - pe_print(" => %d semestres fusionnés" % len(self.SemTagDict)) + """Les étudiants (état civil + cursus connu)""" + self.etuds = nt.etuds + 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() + + """Construit le cube de notes""" + self.notes_cube = {} + + """Les moyennes par tag""" + self.moyennes_tags = {} # ------------------------------------------------------------------------------------------------------------------- - def comp_data_settag(self): - """Calcule tous les données numériques relatives au settag""" - # Attributs relatifs aux tag pour les modules pris en compte - self.taglist = self.do_taglist() # la liste des tags - self.do_tagdict() # le dico descriptif des tags - # if PE_DEBUG >= 1: pe_print(" => Tags = " + ", ".join( self.taglist )) + 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 + """ + nb_tags = len(self.tags_sorted) + nb_etudiants = len(self.etuds) + nb_semestres = len(self.semestres_tags_aggreges) + + """Index du cube (etudids -> dim 0, tags -> dim 1)""" + etudids = [etud.etudid for etud in self.etuds] + tags = self.tags_sorted + semestres_id = list(self.semestres_tags_aggreges.keys()) + + dfs = {} + + for frmsem_id in semestres_id: + """Partant d'un dataframe vierge""" + df = pd.DataFrame(np.nan, index=etudids, columns=self.tags_sorted) + + """Charge les notes du semestre tag""" + notes = self.semestres_tags_aggreges[frmsem_id].notes + + """Les étudiants & les tags commun au dataframe final et aux notes du semestre)""" + etudids_communs = df.index.intersection(notes.index) + tags_communs = df.columns.intersection(notes.columns) + + """Injecte les notes par tag""" + df.loc[etudids_communs, tags_communs] = notes.loc[ + etudids_communs, tags_communs + ] + + """Stocke le df""" + dfs[frmsem_id] = df + + """Réunit les notes sous forme d'un cube etdids x tags x semestres""" + semestres_x_etudids_x_tags = [dfs[fid].values for fid in dfs] + etudids_x_tags_x_semestres = np.stack(semestres_x_etudids_x_tags, axis=-1) + + return etudids_x_tags_x_semestres + - # Calcul des moyennes de chaque étudiant par tag - reussiteAjoutTag = {"OK": [], "KO": []} - for tag in self.taglist: - moyennes = self.comp_MoyennesSetTag(tag, force=False) - res = self.add_moyennesTag(tag, moyennes) # pas de notes => pas de moyenne - reussiteAjoutTag["OK" if res else "KO"].append(tag) - if len(reussiteAjoutTag["OK"]) > 0 and PE_DEBUG: - pe_print( - " => Fusion de %d tags : " % (len(reussiteAjoutTag["OK"])) - + ", ".join(reussiteAjoutTag["OK"]) - ) - if len(reussiteAjoutTag["KO"]) > 0 and PE_DEBUG: - pe_print( - " => %d tags manquants : " % (len(reussiteAjoutTag["KO"])) - + ", ".join(reussiteAjoutTag["KO"]) - ) # ------------------------------------------------------------------------------------------------------------------- def get_etudids(self): @@ -131,13 +146,15 @@ class SetTag(pe_tagtable.TableTag): # ------------------------------------------------------------------------------------------------------------------- def do_taglist(self): - """Parcourt les tags des semestres taggués et les synthétise sous la forme - d'une liste en supprimant les doublons + """Synthétise les tags à partir des semestres (taggués) aggrégés + + Returns: + Une liste de tags triés par ordre alphabétique """ - ensemble = [] - for semtag in self.SemTagDict.values(): - ensemble.extend(semtag.get_all_tags()) - return sorted(list(set(ensemble))) + tags = [] + for frmsem_id in self.semestres_tags_aggreges: + tags.extend(self.semestres_tags_aggreges[frmsem_id].tags_sorted) + return sorted(set(tags)) # ------------------------------------------------------------------------------------------------------------------- def do_tagdict(self):