diff --git a/app/pe/moys/pe_interclasstag.py b/app/pe/moys/pe_interclasstag.py index 7150ebe8..70624f96 100644 --- a/app/pe/moys/pe_interclasstag.py +++ b/app/pe/moys/pe_interclasstag.py @@ -145,11 +145,7 @@ class InterClassTag(pe_tabletags.TableTag): self.moyennes_tags: dict[str, pe_moytag.MoyennesTag] = {} for tag in self.tags_sorted: # Les moyennes tous modules confondus - notes_gen = self.compute_notes_matrice(tag, pole=None) - # Les ressources - notes_res = self.compute_notes_matrice(tag, pole=ModuleType.RESSOURCE) - # Les SAEs - notes_saes = self.compute_notes_matrice(tag, pole=ModuleType.SAE) + notes_gen = self.compute_notes_matrice(tag) # Les coefficients de la moyenne générale coeffs = self.compute_coeffs_matrice(tag) @@ -160,8 +156,6 @@ class InterClassTag(pe_tabletags.TableTag): tag, self.type, notes_gen, - notes_res, - notes_saes, coeffs, # limite les moyennes aux étudiants de la promo ) @@ -180,7 +174,7 @@ class InterClassTag(pe_tabletags.TableTag): tags.extend(rcstag.tags_sorted) return sorted(set(tags)) - def compute_notes_matrice(self, tag, pole=None) -> pd.DataFrame: + def compute_notes_matrice(self, tag) -> pd.DataFrame: """Construit la matrice de notes (etudids x champs) en reportant les moyennes obtenues par les étudiants aux semestres de l'aggrégat pour le tag visé. @@ -203,13 +197,8 @@ class InterClassTag(pe_tabletags.TableTag): # Charge les moyennes au tag d'un RCStag if tag in rcstag.moyennes_tags: moytag = rcstag.moyennes_tags[tag] - notes: pd.DataFrame = None - if pole == ModuleType.RESSOURCE: - notes = moytag.matrice_notes_res - elif pole == ModuleType.SAE: - notes = moytag.matrice_notes_saes - else: - notes = moytag.matrice_notes_gen # dataframe etudids x ues + + notes = moytag.matrice_notes_gen # dataframe etudids x ues # Etudiants/Champs communs entre le RCSTag et les données interclassées ( @@ -291,7 +280,7 @@ class InterClassTag(pe_tabletags.TableTag): return None def compute_df_synthese_moyennes_tag( - self, tag, pole, aggregat=None, type_colonnes=False + self, tag, aggregat=None, type_colonnes=False ) -> pd.DataFrame: """Construit le dataframe retraçant pour les données des moyennes pour affichage dans la synthèse du jury PE. (cf. to_df()) @@ -333,7 +322,6 @@ class InterClassTag(pe_tabletags.TableTag): if tag in rcstag.moyennes_tags: moytag: pd.DataFrame = rcstag.moyennes_tags[tag] df_moytag = moytag.to_df( - pole, aggregat=aggregat, cohorte="Groupe", ) @@ -349,7 +337,7 @@ class InterClassTag(pe_tabletags.TableTag): df[col] = df[col].astype(str) initialisation = True - # Injecte les notes des étudiants - df.loc[etudids, :] = df_moytag.loc[etudids, :] + # Injecte les notes des étudiants + df.loc[etudids, :] = df_moytag.loc[etudids, :] return df diff --git a/app/pe/moys/pe_moy.py b/app/pe/moys/pe_moy.py index 5936f06b..328c07b4 100644 --- a/app/pe/moys/pe_moy.py +++ b/app/pe/moys/pe_moy.py @@ -115,47 +115,6 @@ class Moyenne: } return synthese - def get_rangs_inscrits(self) -> pd.Series: - """Série des rangs classement/nbre_inscrit""" - return self.df_gen["rang"] - - def get_min(self) -> pd.Series: - """Série des min""" - return self.df_gen["min"].round(2) - - def get_max(self) -> pd.Series: - """Série des max""" - return self.df_gen["max"].round(2) - - def get_moy(self) -> pd.Series: - """Série des moy""" - return self.df_gen["moy"].round(2) - - def get_note_for_df(self, etudid: int): - """Note d'un étudiant donné par son etudid""" - return round(self.df_gen["note"].loc[etudid], 2) - - def get_min_for_df(self) -> float: - """Min renseigné pour affichage dans un df""" - return round(self.synthese["min"], 2) - - def get_max_for_df(self) -> float: - """Max renseigné pour affichage dans un df""" - return round(self.synthese["max"], 2) - - def get_moy_for_df(self) -> float: - """Moyenne renseignée pour affichage dans un df""" - return round(self.synthese["moy"], 2) - - def get_class_for_df(self, etudid: int) -> str: - """Classement ramené au nombre d'inscrits, - pour un étudiant donné par son etudid""" - classement = self.df_gen["rang"].loc[etudid] - if not pd.isna(classement): - return classement - else: - return pe_affichage.SANS_NOTE - def is_significatif(self) -> bool: """Indique si la moyenne est significative (c'est-à-dire à des notes)""" return self.synthese["nb_inscrits"] > 0 diff --git a/app/pe/moys/pe_moytag.py b/app/pe/moys/pe_moytag.py index ca6aa50f..68b0022c 100644 --- a/app/pe/moys/pe_moytag.py +++ b/app/pe/moys/pe_moytag.py @@ -17,8 +17,6 @@ class MoyennesTag: tag: str, type_moyenne: str, matrice_notes_gen: pd.DataFrame, # etudids x colonnes - matrice_notes_res: pd.DataFrame, - matrice_notes_saes: pd.DataFrame, matrice_coeffs: pd.DataFrame, # etudids x colonnes ): """Classe centralisant la synthèse des moyennes/classements d'une série @@ -29,12 +27,8 @@ class MoyennesTag: Args: tag: Un tag matrice_notes_gen: Les moyennes (etudid x acronymes_ues ou etudid x compétences) - aux différentes UEs ou compétences (indépendamment des ressources - ou SAEs) - matrice_notes_res: Les moyennes limitées aux ressources - matrice_notes_saes: Les moyennes limitées aux saes - matrice_coeffs: Les coeff à appliquer pour le calcul de la moyenne générale - # notes_gen: Une série de notes (moyenne) sous forme d'un ``pd.Series`` (toutes UEs confondues) + aux différentes UEs ou compétences + # 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""" @@ -46,14 +40,6 @@ class MoyennesTag: self.matrice_notes_gen: pd.DataFrame = matrice_notes_gen """Les notes par UEs ou Compétences (DataFrame)""" - # Les moyennes par UE/compétences (limitées aux ressources) - self.matrice_notes_res: pd.DataFrame = matrice_notes_res - """Les notes aux ressources par UEs ou Compétences""" - - # Les moyennes par UE/compétences (limitées aux SAEs) - self.matrice_notes_saes: pd.DataFrame = matrice_notes_saes - """Les notes aux SAEs par UEs ou Compétences""" - self.matrice_coeffs_moy_gen: pd.DataFrame = matrice_coeffs """Les coeffs à appliquer pour le calcul des moyennes générales (toutes UE ou compétences confondues). NaN si étudiant non inscrit""" @@ -61,12 +47,6 @@ class MoyennesTag: self.moyennes_gen: dict[int, pd.DataFrame] = {} """Dataframes retraçant les moyennes/classements/statistiques des étudiants aux UEs""" - self.moyennes_res: dict[int, pd.DataFrame] = {} - """Dataframes retraçant les moyennes/classements/statistiques des étudiants, limitées aux ressources""" - - self.moyennes_saes: dict[int, pd.DataFrame] = {} - """Dataframes retraçant les moyennes/classements/statistiques des étudiants, limitées aux SAEs""" - self.etudids = self.matrice_notes_gen.index """Les étudids renseignés dans les moyennes""" @@ -76,60 +56,25 @@ class MoyennesTag: # Les moyennes tous modules confondus notes = matrice_notes_gen[col] self.moyennes_gen[col] = pe_moy.Moyenne(notes) - # par ressources - notes = matrice_notes_res[col] - self.moyennes_res[col] = pe_moy.Moyenne(notes) - # par SAEs - notes = matrice_notes_saes[col] - self.moyennes_saes[col] = pe_moy.Moyenne(notes) # Les moyennes générales (toutes UEs confondues) self.notes_gen = pd.Series(np.nan, index=self.matrice_notes_gen.index) - if self.has_notes(pole=None): + if self.has_notes(): self.notes_gen = self.compute_moy_gen( self.matrice_notes_gen, self.matrice_coeffs_moy_gen ) self.moyenne_gen = pe_moy.Moyenne(self.notes_gen) """Dataframe retraçant les moyennes/classements/statistiques général (toutes UESs confondues et modules confondus)""" - self.notes_res = pd.Series(np.nan, index=self.matrice_notes_res.index) - if self.has_notes(pole=ModuleType.RESSOURCE): - self.notes_res = self.compute_moy_gen( - self.matrice_notes_res, self.matrice_coeffs_moy_gen - ) - self.moyenne_res = pe_moy.Moyenne(self.notes_res) - """Dataframe retraçant les moyennes/classements/statistiques général (toutes UESs confondues et uniquement sur les ressources)""" - - self.notes_saes = pd.Series(np.nan, index=self.matrice_notes_saes.index) - if self.has_notes(pole=ModuleType.SAE): - self.notes_saes = self.compute_moy_gen( - self.matrice_notes_saes, self.matrice_coeffs_moy_gen - ) - self.moyenne_saes = pe_moy.Moyenne(self.notes_saes) - """Dataframe retraçant les moyennes/classements/statistiques général (toutes UESs confondues et uniquement sur les SAEs)""" - - def has_notes(self, pole): + def has_notes(self): """Détermine si les moyennes (aux UEs ou aux compétences) ont des notes - `pole` détermine les modules pris en compte : - - * si `pole` vaut `ModuleType.RESSOURCE`, seules les ressources sont prises - en compte (moyenne de ressources par UEs) - * si `pole` vaut `ModuleType.SAE`, seules les SAEs sont prises en compte - * si `pole` vaut `None` (ou toute autre valeur), - tous les modules sont pris en compte (moyenne d'UEs) - - Returns: True si la moytag a des notes, False sinon """ - if pole == ModuleType.RESSOURCE: - notes = self.matrice_notes_res - elif pole == ModuleType.SAE: - notes = self.matrice_notes_saes - else: - notes = self.matrice_notes_gen + notes = self.matrice_notes_gen + nbre_nan = notes.isna().sum().sum() nbre_notes_potentielles = len(notes.index) * len(notes.columns) if nbre_nan == nbre_notes_potentielles: @@ -162,7 +107,7 @@ class MoyennesTag: return moy_gen_tag - def to_df(self, pole, aggregat=None, cohorte=None) -> pd.DataFrame: + def to_df(self, aggregat=None, cohorte=None) -> pd.DataFrame: """Renvoie le df synthétisant l'ensemble des données connues Adapte les intitulés des colonnes aux données fournies @@ -179,30 +124,19 @@ class MoyennesTag: # Ajout des notes pour tous les champs champs = list(self.champs) for champ in champs: - if pole == ModuleType.RESSOURCE: - df_champ = self.moyennes_res[champ].get_df_synthese() - elif pole == ModuleType.SAE: - df_champ = self.moyennes_saes[champ].get_df_synthese() - else: - df_champ = self.moyennes_gen[champ].get_df_synthese() # le dataframe + df_champ = self.moyennes_gen[champ].get_df_synthese() # le dataframe # Renomme les colonnes cols = [ - get_colonne_df(aggregat, pole, self.tag, champ, cohorte, critere) + get_colonne_df(aggregat, self.tag, champ, cohorte, critere) for critere in pe_moy.Moyenne.COLONNES_SYNTHESE ] df_champ.columns = cols df = df.join(df_champ) # Ajoute la moy générale - df_moy_gen: pd.DataFrame = None - if pole == ModuleType.RESSOURCE: - df_moy_gen = self.moyenne_res.get_df_synthese() - elif pole == ModuleType.SAE: - df_moy_gen = self.moyenne_saes.get_df_synthese() - else: - df_moy_gen = self.moyenne_gen.get_df_synthese() + df_moy_gen = self.moyenne_gen.get_df_synthese() cols = [ - get_colonne_df(aggregat, pole, self.tag, CHAMP_GENERAL, cohorte, critere) + get_colonne_df(aggregat, self.tag, CHAMP_GENERAL, cohorte, critere) for critere in pe_moy.Moyenne.COLONNES_SYNTHESE ] df_moy_gen.columns = cols @@ -211,18 +145,13 @@ class MoyennesTag: return df -def get_colonne_df(aggregat, pole, tag, champ, cohorte, critere): +def get_colonne_df(aggregat, tag, champ, cohorte, critere): """Renvoie le tuple (aggregat, tag, champ, cohorte, critere) utilisé pour désigner les colonnes du df""" liste_champs = [] if aggregat != None: liste_champs += [aggregat] - if pole == ModuleType.RESSOURCE: - liste_champs += ["ressources"] - elif pole == ModuleType.SAE: - liste_champs += ["saes"] - else: - liste_champs += ["global"] + liste_champs += [tag, champ] if cohorte != None: liste_champs += [cohorte] diff --git a/app/pe/moys/pe_rcstag.py b/app/pe/moys/pe_rcstag.py index 10bcd60b..cf135174 100644 --- a/app/pe/moys/pe_rcstag.py +++ b/app/pe/moys/pe_rcstag.py @@ -142,29 +142,12 @@ class RCSemXTag(pe_tabletags.TableTag): # Traitement des notes # ******************** - ### Moyennes tous modules confondus # Cube de notes (etudids_sorted x compétences_sorted x sxstags) - notes_df, notes_cube = self.compute_notes_comps_cube(tag, mode=None) + notes_df, notes_cube = self.compute_notes_comps_cube(tag) # Calcule les moyennes sous forme d'un dataframe en les "aggrégant" # compétence par compétence moys_competences = self.compute_notes_competences(notes_cube, inscr_cube) - ## Moyennes des ressources - notes_df_res, notes_cube_res = self.compute_notes_comps_cube( - tag, mode=ModuleType.RESSOURCE - ) - moys_competences_res = self.compute_notes_competences( - notes_cube_res, inscr_cube - ) - - ## Moyennes des SAEs - notes_df_sae, notes_cube_sae = self.compute_notes_comps_cube( - tag, mode=ModuleType.SAE - ) - moys_competences_saes = self.compute_notes_competences( - notes_cube_sae, inscr_cube - ) - # Traitement des coeffs pour la moyenne générale # *********************************************** # Df des coeffs sur tous les SxTags aggrégés @@ -186,8 +169,6 @@ class RCSemXTag(pe_tabletags.TableTag): tag, pe_moytag.CODE_MOY_COMPETENCES, moys_competences, - moys_competences_res, - moys_competences_saes, matrice_coeffs_moy_gen, ) @@ -205,19 +186,11 @@ class RCSemXTag(pe_tabletags.TableTag): else: return f"{self.__class__.__name__} {self.rcs_id}" - def compute_notes_comps_cube(self, tag, mode=None): + def compute_notes_comps_cube(self, tag): """Pour un tag donné, construit le cube de notes (etudid x competences x SxTag) nécessaire au calcul des moyennes, en remplaçant les données d'UE (obtenus du SxTag) par les compétences - `mode` détermine les modules pris en compte : - - * si `mode` vaut `ModuleType.RESSOURCE`, seules les ressources sont prises - en compte (moyenne de ressources par UEs) - * si `mode` vaut `ModuleType.SAE`, seules les SAEs sont prises en compte - * si `mode` vaut `None` (ou toute autre valeur), - tous les modules sont pris en compte (moyenne d'UEs) - Args: tag: Le tag visé """ @@ -235,12 +208,7 @@ class RCSemXTag(pe_tabletags.TableTag): if tag in sxtag.moyennes_tags: # si le tag est présent dans le semestre moys_tag = sxtag.moyennes_tags[tag] - if mode == ModuleType.RESSOURCE: - notes = moys_tag.matrice_notes_res.copy() # avec une copie - elif mode == ModuleType.SAE: - notes = moys_tag.matrice_notes_saes.copy() - else: - notes = moys_tag.matrice_notes_gen.copy() # dataframe etudids x ues + notes = moys_tag.matrice_notes_gen.copy() # dataframe etudids x ues # Traduction des acronymes d'UE en compétences acronymes_ues_columns = notes.columns diff --git a/app/pe/moys/pe_ressemtag.py b/app/pe/moys/pe_ressemtag.py index d974f47c..bc1a5c07 100644 --- a/app/pe/moys/pe_ressemtag.py +++ b/app/pe/moys/pe_ressemtag.py @@ -67,13 +67,15 @@ class ResSemBUTTag(ResultatsSemestreBUT, pe_tabletags.TableTag): # Le nom du res_semestre taggué self.nom = self.get_repr(verbose=True) - pe_affichage.pe_print(f"*** ResSemBUTTag du {self.nom}") - # Les étudiants (etuds, états civils & etudis) ajouté self.add_etuds(self.etuds) self.etudids_sorted = sorted(self.etudids) """Les etudids des étudiants du ResultatsSemestreBUT triés""" + pe_affichage.pe_print( + f"*** ResSemBUTTag du {self.nom} => {len(self.etudids_sorted)} étudiants" + ) + # Les UEs (et les dispenses d'UE) self.ues_standards: list[UniteEns] = [ ue for ue in self.ues if ue.type == sco_codes.UE_STANDARD @@ -145,33 +147,37 @@ class ResSemBUTTag(ResultatsSemestreBUT, pe_tabletags.TableTag): info_tag = tags_dict["personnalises"][tag] # Les moyennes générales par UEs moy_ues_tag = self.compute_moy_ues_tag(info_tag=info_tag, pole=None) - # Les moyennes par ressources de chaque UE - moy_res_tag = self.compute_moy_ues_tag( - info_tag=info_tag, pole=ModuleType.RESSOURCE - ) - # Les moyennes par SAEs de chaque UE - moy_saes_tag = self.compute_moy_ues_tag( - info_tag=info_tag, pole=ModuleType.SAE - ) + # Mémorise les moyennes self.moyennes_tags[tag] = pe_moytag.MoyennesTag( tag, pe_moytag.CODE_MOY_UE, moy_ues_tag, - moy_res_tag, - moy_saes_tag, self.matrice_coeffs_moy_gen, ) # Ajoute les moyennes par UEs + la moyenne générale (but) moy_gen = self.compute_moy_gen() - moy_res_gen = self.compute_moy_ues_tag(info_tag=None, pole=ModuleType.RESSOURCE) - moy_saes_gen = self.compute_moy_ues_tag(info_tag=None, pole=ModuleType.SAE) - self.moyennes_tags["but"] = pe_moytag.MoyennesTag( "but", pe_moytag.CODE_MOY_UE, moy_gen, + self.matrice_coeffs_moy_gen, + ) + + # Ajoute la moyenne générale par ressources + moy_res_gen = self.compute_moy_ues_tag(info_tag=None, pole=ModuleType.RESSOURCE) + self.moyennes_tags["ressources"] = pe_moytag.MoyennesTag( + "ressources", + pe_moytag.CODE_MOY_UE, moy_res_gen, + self.matrice_coeffs_moy_gen, + ) + + # Ajoute la moyenne générale par saes + moy_saes_gen = self.compute_moy_ues_tag(info_tag=None, pole=ModuleType.SAE) + self.moyennes_tags["saes"] = pe_moytag.MoyennesTag( + "saes", + pe_moytag.CODE_MOY_UE, moy_saes_gen, self.matrice_coeffs_moy_gen, ) @@ -364,7 +370,7 @@ class ResSemBUTTag(ResultatsSemestreBUT, pe_tabletags.TableTag): # noms_tags_comp = list(set(dict_ues_competences.values())) # BUT - dict_tags["auto"] = {"but": {}} + dict_tags["auto"] = {"but": {}, "ressources": {}, "saes": {}} return dict_tags def _check_tags(self, dict_tags): diff --git a/app/pe/moys/pe_sxtag.py b/app/pe/moys/pe_sxtag.py index 18cb8b3c..6ddb1ee9 100644 --- a/app/pe/moys/pe_sxtag.py +++ b/app/pe/moys/pe_sxtag.py @@ -188,46 +188,21 @@ class SxTag(pe_tabletags.TableTag): matrice_moys_ues = pd.DataFrame( np.nan, index=self.etudids_sorted, columns=self.acronymes_sorted ) - matrice_moys_res = pd.DataFrame( - np.nan, index=self.etudids_sorted, columns=self.acronymes_sorted - ) - matrice_moys_saes = pd.DataFrame( - np.nan, index=self.etudids_sorted, columns=self.acronymes_sorted - ) else: # Moyennes tous modules confondus ### Cube de note etudids x UEs tous modules confondus - notes_df_gen, notes_cube_gen = self.compute_notes_ues_cube( - tag, mode=None - ) + notes_df_gen, notes_cube_gen = self.compute_notes_ues_cube(tag) + # DataFrame des moyennes (tous modules confondus) matrice_moys_ues = self.compute_notes_ues( notes_cube_gen, masque_cube, inscr_mask ) - ### Moyennes par ressources - notes_df_res, notes_cube_res = self.compute_notes_ues_cube( - tag, mode=ModuleType.RESSOURCE - ) - matrice_moys_res = self.compute_notes_ues( - notes_cube_res, masque_cube, inscr_mask - ) - - ### Moyennes par SAEs - notes_df_saes, notes_cube_saes = self.compute_notes_ues_cube( - tag, mode=ModuleType.SAE - ) - matrice_moys_saes = self.compute_notes_ues( - notes_cube_saes, masque_cube, inscr_mask - ) - - # Mémorise les infos pour la moyennes au tag + # Mémorise les infos pour la moyenne au tag self.moyennes_tags[tag] = pe_moytag.MoyennesTag( tag, pe_moytag.CODE_MOY_UE, matrice_moys_ues, - matrice_moys_res, - matrice_moys_saes, self.matrice_coeffs_moy_gen, ) @@ -248,7 +223,7 @@ class SxTag(pe_tabletags.TableTag): True si a des notes, False sinon """ moy_tag_dernier_sem = self.ressembuttag_final.moyennes_tags[tag] - return moy_tag_dernier_sem.has_notes(None) + return moy_tag_dernier_sem.has_notes() def __eq__(self, other): """Egalité de 2 SxTag sur la base de leur identifiant""" @@ -263,19 +238,11 @@ class SxTag(pe_tabletags.TableTag): # affichage = [str(fid) for fid in self.ressembuttags] return f"SXTag {self.agregat}#{self.fid_final}" - def compute_notes_ues_cube(self, tag, mode=None) -> (pd.DataFrame, np.array): + def compute_notes_ues_cube(self, tag) -> (pd.DataFrame, np.array): """Construit le cube de notes des UEs (etudid x accronyme_ue x semestre_aggregé) nécessaire au calcul des moyennes du tag pour le RCS Sx. (Renvoie également le dataframe associé pour debug). - `mode` détermine les modules pris en compte : - - * si `mode` vaut `ModuleType.RESSOURCE`, seules les ressources sont prises - en compte (moyenne de ressources par UEs) - * si `mode` vaut `ModuleType.SAE`, seules les SAEs sont prises en compte - * si `mode` vaut `None` (ou toute autre valeur), - tous les modules sont pris en compte (moyenne d'UEs) - Args: tag: Le tag considéré (personalisé ou "but") """ @@ -295,12 +262,7 @@ class SxTag(pe_tabletags.TableTag): # Charge les notes du semestre tag sem_tag = self.ressembuttags[frmsem_id] moys_tag = sem_tag.moyennes_tags[tag] - if mode == ModuleType.RESSOURCE: - notes = moys_tag.matrice_notes_res - elif mode == ModuleType.SAE: - notes = moys_tag.matrice_notes_saes - else: - notes = moys_tag.matrice_notes_gen # dataframe etudids x ues + notes = moys_tag.matrice_notes_gen # dataframe etudids x ues # les étudiants et les acronymes communs etudids_communs, acronymes_communs = pe_comp.find_index_and_columns_communs( diff --git a/app/pe/moys/pe_tabletags.py b/app/pe/moys/pe_tabletags.py index 9f5bf7de..5da211c5 100644 --- a/app/pe/moys/pe_tabletags.py +++ b/app/pe/moys/pe_tabletags.py @@ -79,13 +79,12 @@ class TableTag(object): tag: str = "" moytag: pe_moytag.MoyennesTag = None for tag, moytag in self.moyennes_tags.items(): - if moytag.has_notes(None): + if moytag.has_notes(): tags.append(tag) return sorted(tags) def to_df( self, - pole, administratif=True, aggregat=None, tags_cibles=None, @@ -103,7 +102,6 @@ class TableTag(object): aggregat: l'aggrégat représenté tags_cibles: la liste des tags ciblés cohorte: la cohorte représentée - pole: Les modules à prendre en compte dans la moyenne (None=tous, Ressources ou SAEs) Returns: Le dataframe complet de synthèse """ @@ -128,7 +126,7 @@ class TableTag(object): for tag in tags_cibles: if tag in self.moyennes_tags: moy_tag_df = self.moyennes_tags[tag].to_df( - pole, aggregat=aggregat, cohorte=cohorte + aggregat=aggregat, cohorte=cohorte ) df = df.join(moy_tag_df) @@ -163,7 +161,6 @@ def _get_champ_administratif(champ, aggregat=None, cohorte=None): liste = [] if aggregat != None: liste += [aggregat] - liste += [""] # le pole (None, RESSOURCES, SAEs) liste += ["Administratif", "Identité"] if cohorte != None: liste += [champ] diff --git a/app/pe/pe_etudiant.py b/app/pe/pe_etudiant.py index 9e7fbb80..86f92dd9 100644 --- a/app/pe/pe_etudiant.py +++ b/app/pe/pe_etudiant.py @@ -358,7 +358,9 @@ class EtudiantsJuryPE: etudiant = self.identites[etudid] cursus = self.cursus[etudid] formsemestres = cursus["formsemestres"] - + parcours = cursus["parcours"] + if not parcours: + parcours = "" if cursus["diplome"]: diplome = cursus["diplome"] else: @@ -372,6 +374,7 @@ class EtudiantsJuryPE: "Prenom": etudiant.prenom, "Civilite": etudiant.civilite_str, "Age": pe_comp.calcul_age(etudiant.date_naissance), + "Parcours": parcours, "Date entree": cursus["entree"], "Date diplome": diplome, "Nb semestres": len(formsemestres), diff --git a/app/pe/pe_jury.py b/app/pe/pe_jury.py index 2d2fbde7..7b42204a 100644 --- a/app/pe/pe_jury.py +++ b/app/pe/pe_jury.py @@ -199,19 +199,14 @@ class JuryPE(object): ) as writer: onglets = [] for res_sem_tag in self.ressembuttags.values(): - for pole in [None, ModuleType.RESSOURCE, ModuleType.SAE]: - onglet = res_sem_tag.get_repr(verbose=True) - onglet = onglet.replace("Semestre ", "S") - if pole: - onglet += ( - " (res.)" if pole == ModuleType.RESSOURCE else " (saes)" - ) - onglets += ["📊" + onglet] - df = res_sem_tag.to_df(pole) - # Conversion colonnes en multiindex - df = convert_colonnes_to_multiindex(df) - # écriture dans l'onglet - df.to_excel(writer, onglet, index=True, header=True) + onglet = res_sem_tag.get_repr(verbose=True) + onglet = onglet.replace("Semestre ", "S") + onglets += ["📊" + onglet] + df = res_sem_tag.to_df() + # Conversion colonnes en multiindex + df = convert_colonnes_to_multiindex(df) + # écriture dans l'onglet + df.to_excel(writer, onglet, index=True, header=True) pe_affichage.pe_print( f"--> Export excel de {', '.join(onglets)}", info=True ) @@ -269,13 +264,18 @@ class JuryPE(object): """ # Génère les moyennes des RCS de type Sx pe_affichage.pe_print( - "***************************************************************************\n" - "*** Calcule les moyennes des SxTag (moyennes d'un RCS de type Sx)\n" + "***************************************************************************" + ) + pe_affichage.pe_print( + "*** Calcule les moyennes des SxTag (moyennes d'un RCS de type Sx)", + info=True, + ) + pe_affichage.pe_print( "***************************************************************************" ) # Les SxTag (moyenne de Sx par UE) - pe_affichage.pe_print("1) Calcul des moyennes") + pe_affichage.pe_print("1) Calcul des moyennes", info=True) self.sxtags = {} for rcf_id, rcf in self.rcss_jury.semXs.items(): # SxTag traduisant le RCF @@ -283,7 +283,7 @@ class JuryPE(object): self.sxtags[sxtag_id] = pe_sxtag.SxTag(sxtag_id, rcf, self.ressembuttags) # Intègre le bilan des semestres taggués au zip final - pe_affichage.pe_print("2) Bilan") + pe_affichage.pe_print("2) Bilan", info=True) output = io.BytesIO() with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated output, engine="openpyxl" @@ -291,20 +291,17 @@ class JuryPE(object): onglets = [] for sxtag in self.sxtags.values(): if sxtag.is_significatif(): - for pole in [None, ModuleType.RESSOURCE, ModuleType.SAE]: - onglet = sxtag.get_repr(verbose=False) - if pole: - onglet += ( - " (res.)" if pole == ModuleType.RESSOURCE else " (saes)" - ) - onglets += ["📊" + onglet] - df = sxtag.to_df(pole) - # Conversion colonnes en multiindex - df = convert_colonnes_to_multiindex(df) + onglet = sxtag.get_repr(verbose=False) + onglets += ["📊" + onglet] + df = sxtag.to_df() + # Conversion colonnes en multiindex + df = convert_colonnes_to_multiindex(df) - # écriture dans l'onglet - df.to_excel(writer, onglet, index=True, header=True) - pe_affichage.pe_print(f"--> Export excel de {', '.join(onglets)}") + # écriture dans l'onglet + df.to_excel(writer, onglet, index=True, header=True) + pe_affichage.pe_print( + f"--> Export excel de {', '.join(onglets)}", info=True + ) output.seek(0) if onglets: @@ -319,9 +316,14 @@ class JuryPE(object): """Génère les regroupements cohérents de RCFs qu'ont suivi chaque étudiant""" pe_affichage.pe_print( - """******************************************************************************\n""" + """******************************************************************************""" + ) + pe_affichage.pe_print( """*** Génère les RCSemX (regroupements cohérents de données extraites des SemX)\n""" - """*** amenant du S1 à un semestre final\n""" + """*** amenant du S1 à un semestre final""", + info=True, + ) + pe_affichage.pe_print( """******************************************************************************""" ) self.rcss_jury.cree_rcsemxs(self.etudiants) @@ -348,12 +350,16 @@ class JuryPE(object): # Génère les moyennes des RCS de type Sx pe_affichage.pe_print( - """****************************************************\n""" - """*** Génère les moyennes associées aux RCSemX \n""" + """****************************************************""" + ) + pe_affichage.pe_print( + """*** Génère les moyennes associées aux RCSemX""", info=True + ) + pe_affichage.pe_print( """****************************************************""" ) - pe_affichage.pe_print("1) Calcul des moyennes des RCSTag") + pe_affichage.pe_print("1) Calcul des moyennes des RCSTag", info=True) self.rcsstags = {} for rcs_id, rcsemx in self.rcss_jury.rcsemxs.items(): self.rcsstags[rcs_id] = pe_rcstag.RCSemXTag( @@ -361,7 +367,7 @@ class JuryPE(object): ) # Intègre le bilan des trajectoires tagguées au zip final - pe_affichage.pe_print("2) Bilan") + pe_affichage.pe_print("2) Bilan", info=True) output = io.BytesIO() with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated output, engine="openpyxl" @@ -369,21 +375,18 @@ class JuryPE(object): onglets = [] for rcs_tag in self.rcsstags.values(): if rcs_tag.is_significatif(): - for pole in [None, ModuleType.RESSOURCE, ModuleType.SAE]: - onglet = rcs_tag.get_repr(verbose=False) - if pole: - onglet += ( - " (res.)" if pole == ModuleType.RESSOURCE else " (saes)" - ) - onglets += ["📊" + onglet] + onglet = rcs_tag.get_repr(verbose=False) + onglets += ["📊" + onglet] - df = rcs_tag.to_df(pole) - # Conversion colonnes en multiindex - df = convert_colonnes_to_multiindex(df) - onglets += ["📊" + onglet] - # écriture dans l'onglet - df.to_excel(writer, onglet, index=True, header=True) - pe_affichage.pe_print(f"--> Export excel de {', '.join(onglets)}") + df = rcs_tag.to_df() + # Conversion colonnes en multiindex + df = convert_colonnes_to_multiindex(df) + onglets += ["📊" + onglet] + # écriture dans l'onglet + df.to_excel(writer, onglet, index=True, header=True) + pe_affichage.pe_print( + f"--> Export excel de {', '.join(onglets)}", info=True + ) output.seek(0) if onglets: @@ -401,10 +404,15 @@ class JuryPE(object): et ceux par compétences (sur les RCSTag). """ pe_affichage.pe_print( - """******************************************************************\n""" - """*** Génère les interclassements sur chaque type de RCS/agrgégat\n""" """******************************************************************""" ) + pe_affichage.pe_print( + """*** Génère les interclassements sur chaque type de RCS/agrgégat""" + ) + pe_affichage.pe_print( + """******************************************************************""" + ) + self.interclasstags = { pe_moytag.CODE_MOY_UE: {}, pe_moytag.CODE_MOY_COMPETENCES: {}, @@ -449,22 +457,15 @@ class JuryPE(object): interclasstag = self.interclasstags[type_interclass] for nom_rcs, interclass in interclasstag.items(): if interclass.is_significatif(): - for pole in [None, ModuleType.RESSOURCE, ModuleType.SAE]: - onglet = interclass.get_repr() - if pole: - onglet += ( - " (res.)" - if pole == ModuleType.RESSOURCE - else " (saes)" - ) - onglets += ["📊" + onglet] - df = interclass.to_df(pole, cohorte="Promo") - # Conversion colonnes en multiindex - df = convert_colonnes_to_multiindex(df) - onglets += [onglet] - # écriture dans l'onglet - df.to_excel(writer, onglet, index=True, header=True) - pe_affichage.pe_print(f"=> Export excel de {', '.join(onglets)}") + onglet = interclass.get_repr() + onglets += ["📊" + onglet] + df = interclass.to_df(cohorte="Promo") + # Conversion colonnes en multiindex + df = convert_colonnes_to_multiindex(df) + onglets += [onglet] + # écriture dans l'onglet + df.to_excel(writer, onglet, index=True, header=True) + pe_affichage.pe_print(f"=> Export excel de {', '.join(onglets)}", info=True) output.seek(0) @@ -479,11 +480,18 @@ class JuryPE(object): def _gen_xls_synthese_jury_par_tag(self, zipfile: ZipFile): """Synthèse des éléments du jury PE tag par tag""" pe_affichage.pe_print( - "*** Synthèse finale des moyennes par tag et par type de moyennes (UEs ou Compétences)***" + "**************************************************************************************" + ) + pe_affichage.pe_print( + "*** Synthèse finale des moyennes par tag et par type de moyennes (UEs ou Compétences)", + info=True, + ) + pe_affichage.pe_print( + "**************************************************************************************" ) self.synthese = {} - pe_affichage.pe_print(" -> Synthèse des données administratives") + pe_affichage.pe_print(" -> Synthèse des données administratives", info=True) self.synthese["administratif"] = self.etudiants.df_administratif( self.diplomes_ids ) @@ -491,13 +499,10 @@ class JuryPE(object): tags = self._do_tags_list(self.interclasstags) for tag in tags: for type_moy in [pe_moytag.CODE_MOY_UE, pe_moytag.CODE_MOY_COMPETENCES]: - for pole in [None, ModuleType.RESSOURCE, ModuleType.SAE]: - self.synthese[(tag, type_moy, pole)] = self.df_tag_type( - tag, type_moy, pole - ) + self.synthese[(tag, type_moy)] = self.df_tag_type(tag, type_moy) # Export des données => mode 1 seule feuille -> supprimé - pe_affichage.pe_print("*** Export du jury de synthese par tags") + pe_affichage.pe_print("*** Export du jury de synthese par tags", info=True) output = io.BytesIO() with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated output, engine="openpyxl" @@ -509,25 +514,19 @@ class JuryPE(object): df_final = convert_colonnes_to_multiindex(df_final) # Nom de l'onglet if isinstance(onglet, tuple): - (repr, type_moy, pole) = onglet - nom_onglet = onglet[0][: 31 - 11] + (repr, type_moy) = onglet + nom_onglet = onglet[0][: 31 - 7] if type_moy == pe_moytag.CODE_MOY_COMPETENCES: - nom_onglet = nom_onglet + "(Comp" + nom_onglet = nom_onglet + " (Comp)" else: - nom_onglet = nom_onglet + "(UE" - if pole and pole == ModuleType.RESSOURCE: - nom_onglet = nom_onglet + ",res)" - elif pole and pole == ModuleType.SAE: - nom_onglet = nom_onglet + ",saes)" - else: - nom_onglet = nom_onglet + ")" + nom_onglet = nom_onglet + " (UEs)" else: nom_onglet = onglet onglets += [nom_onglet] # écriture dans l'onglet: df_final = df_final.replace("nan", "") df_final.to_excel(writer, nom_onglet, index=True, header=True) - pe_affichage.pe_print(f"=> Export excel de {', '.join(onglets)}") + pe_affichage.pe_print(f"=> Export excel de {', '.join(onglets)}", info=True) output.seek(0) self.add_file_to_zip( @@ -537,7 +536,9 @@ class JuryPE(object): def _gen_html_synthese_par_etudiant(self, zipfile: ZipFile): """Synthèse des éléments du jury PE, étudiant par étudiant""" # Synthèse des éléments du jury PE - pe_affichage.pe_print("*** Synthèse finale étudiant par étudiant***") + pe_affichage.pe_print("**************************************************") + pe_affichage.pe_print("*** Synthèse finale étudiant par étudiant", info=True) + pe_affichage.pe_print("**************************************************") etudids = list(self.diplomes_ids) for etudid in etudids: @@ -589,7 +590,7 @@ class JuryPE(object): # Méthodes pour la synthèse du juryPE # ***************************************************************************************************************** - def df_tag_type(self, tag, type_moy, pole): + def df_tag_type(self, tag, type_moy): """Génère le DataFrame synthétisant les moyennes/classements (groupe + interclassement promo) pour tous les aggrégats prévus, en fonction du type (UEs ou Compétences) de données souhaitées, @@ -625,7 +626,7 @@ class JuryPE(object): if interclass.is_significatif(): # Le dataframe du classement sur le groupe df_groupe = interclass.compute_df_synthese_moyennes_tag( - tag, pole, aggregat=aggregat, type_colonnes=False + tag, aggregat=aggregat, type_colonnes=False ) if not df_groupe.empty: aff_aggregat += [aggregat] @@ -633,7 +634,6 @@ class JuryPE(object): # Le dataframe du classement sur la promo df_promo = interclass.to_df( - pole, administratif=False, aggregat=aggregat, tags_cibles=[tag], @@ -645,15 +645,8 @@ class JuryPE(object): df = df.join(df_promo) if aff_aggregat: - aff_aggregat = sorted(set(aff_aggregat)) - if pole and pole == ModuleType.RESSOURCE: - aff_pole = "et par ressources" - elif pole and pole == ModuleType.SAE: - aff_pole = "et par saes" - else: - aff_pole = "tous modules confondus" pe_affichage.pe_print( - f" -> Synthèse de 👜{tag} par {type_moy} {aff_pole} avec {', '.join(aff_aggregat)}" + f" -> Synthèse de 👜{tag} par {type_moy} avec {', '.join(aff_aggregat)}" ) else: pe_affichage.pe_print(f" -> Synthèse du tag {tag} par {type_moy} : ") @@ -668,11 +661,12 @@ class JuryPE(object): Returns: Un tuple nom, prenom, html """ - pole = None - etudiant = self.etudiants.identites[etudid] nom = etudiant.nom prenom = etudiant.prenom # initial du prénom + parcours = self.etudiants.cursus[etudid]["parcours"] + if not parcours: + parcours = "" # Accès au template environnement = jinja2.Environment( @@ -682,7 +676,7 @@ class JuryPE(object): # Colonnes des tableaux htmls => competences competences = [] - for aggregat in pe_rcs.TOUS_LES_RCS_AVEC_PLUSIEURS_SEM: + for aggregat in pe_rcs.TOUS_LES_RCS: # L'interclassement associé interclass = self.interclasstags[pe_moytag.CODE_MOY_COMPETENCES][aggregat] competences.extend(interclass.champs_sorted) @@ -696,7 +690,7 @@ class JuryPE(object): for tag in tags: moyennes[tag] = {} # Les données de synthèse - df = self.synthese[(tag, pe_moytag.CODE_MOY_COMPETENCES, pole)] + df = self.synthese[(tag, pe_moytag.CODE_MOY_COMPETENCES)] for aggregat in pe_rcs.TOUS_LES_RCS: # moyennes[tag][aggregat] = {} descr = pe_rcs.get_descr_rcs(aggregat) @@ -710,22 +704,24 @@ class JuryPE(object): "rang_promo": "", } colonne = pe_moytag.get_colonne_df( - aggregat, pole, tag, comp, "Groupe", "note" + aggregat, tag, comp, "Groupe", "note" ) if colonne in df.columns: valeur = df.loc[etudid, colonne] if not np.isnan(valeur): moy[comp]["note"] = round(valeur, 2) est_significatif = True + # else: + # print(f"{colonne} manquante") colonne = pe_moytag.get_colonne_df( - aggregat, pole, tag, comp, "Groupe", "rang" + aggregat, tag, comp, "Groupe", "rang" ) if colonne in df.columns: valeur = df.loc[etudid, colonne] if valeur and str(valeur) != "nan": moy[comp]["rang_groupe"] = valeur colonne = pe_moytag.get_colonne_df( - aggregat, pole, tag, comp, "Promo", "rang" + aggregat, tag, comp, "Promo", "rang" ) if colonne in df.columns: valeur = df.loc[etudid, colonne] @@ -738,7 +734,7 @@ class JuryPE(object): html = template.render( nom=nom, prenom=prenom, - pole="Moyennes calculées tous modules (ressources/SAEs) confondus", + parcours=parcours, colonnes_html=colonnes_html, tags=tags, moyennes=moyennes, diff --git a/app/pe/rcss/pe_rcs.py b/app/pe/rcss/pe_rcs.py index 435e857d..8b6af4de 100644 --- a/app/pe/rcss/pe_rcs.py +++ b/app/pe/rcss/pe_rcs.py @@ -38,11 +38,11 @@ TYPES_RCS = { }, "3S": { "aggregat": ["S1", "S2", "S3"], - "descr": "Moyenne du semestre 1 au semestre 3 (S1+S2+S3)", + "descr": "Moyenne du S1 au S3 (S1+S2+S3)", }, "4S": { "aggregat": ["S1", "S2", "S3", "S4"], - "descr": "Moyenne du semestre 1 au semestre 4 (S1+S2+S3+S4)", + "descr": "Moyenne du S1 au S4 (S1+S2+S3+S4)", }, "S5": { "aggregat": ["S5"], @@ -58,7 +58,7 @@ TYPES_RCS = { }, "5S": { "aggregat": ["S1", "S2", "S3", "S4", "S5"], - "descr": "Moyenne du semestre 1 au semestre 5 (S1+S2+S3+S4+S5)", + "descr": "Moyenne du S1 au S5 (S1+S2+S3+S4+S5)", }, "6S": { "aggregat": ["S1", "S2", "S3", "S4", "S5", "S6"], diff --git a/app/templates/pe/pe_view_resultats_etudiant.j2 b/app/templates/pe/pe_view_resultats_etudiant.j2 index f72e2cf1..63cbc1e2 100644 --- a/app/templates/pe/pe_view_resultats_etudiant.j2 +++ b/app/templates/pe/pe_view_resultats_etudiant.j2 @@ -25,7 +25,9 @@
-

Résultats PE de {{prenom}} {{nom}}

+

Résultats PE de {{prenom}} {{nom}} ({{ parcours }})

+ +

Légende

    @@ -33,8 +35,6 @@
  • ../.. Classement par promo
- {{ pole }} - {% for tag in tags %}

Tag 👜 {{ tag }}