diff --git a/app/pe/pe_moytag.py b/app/pe/pe_moytag.py index 1df487ff9..d5e64a794 100644 --- a/app/pe/pe_moytag.py +++ b/app/pe/pe_moytag.py @@ -155,13 +155,12 @@ class Moyenne: return self.synthese["nb_inscrits"] > 0 - class MoyennesTag: def __init__( self, tag: str, - matrice_notes: pd.DataFrame, # etudids x colonnes - matrice_coeffs: pd.DataFrame # etudids x colonnes + matrice_notes: pd.DataFrame, # etudids x colonnes + matrice_coeffs: pd.DataFrame, # etudids x colonnes ): """Classe centralisant la synthèse des moyennes/classements d'une série d'étudiants à un tag donné, en différenciant les notes @@ -193,13 +192,30 @@ class MoyennesTag: self.moyennes[col] = Moyenne(notes) # Les moyennes générales - notes_gen = self.compute_moy_gen(self.matrice_notes, self.matrice_coeffs_moy_gen) - self.notes_gen = notes_gen + notes_gen = pd.Series(np.nan, index=self.matrice_notes.index) """Les notes générales (moyenne toutes UEs confonudes)""" + if self.has_notes(): + notes_gen = self.compute_moy_gen( + self.matrice_notes, self.matrice_coeffs_moy_gen + ) + self.notes_gen = notes_gen self.moyenne_gen = Moyenne(notes_gen) """Le dataframe retraçant les moyennes/classements/statistiques général""" + def has_notes(self): + """Détermine si les moyennes (aux UEs ou aux compétences) + ont des notes + Returns: + True si a des notes, False sinon + """ + notes = self.matrice_notes + nbre_nan = notes.isna().sum().sum() + nbre_notes_potentielles = len(notes.index) * len(notes.columns) + if nbre_nan == nbre_notes_potentielles: + return False + else: + return True def compute_moy_gen(self, moys: pd.DataFrame, coeffs: pd.DataFrame) -> pd.Series: """Calcule la moyenne générale (toutes UE/compétences confondus) @@ -225,4 +241,3 @@ class MoyennesTag: ) return moy_gen_tag - diff --git a/app/pe/pe_rcstag.py b/app/pe/pe_rcstag.py index 70d114910..94fe3051f 100644 --- a/app/pe/pe_rcstag.py +++ b/app/pe/pe_rcstag.py @@ -95,7 +95,13 @@ class RCSTag(TableTag): self.add_etuds(nt.etuds) # Les compétences (extraites de tous les Sxtags) + self.association_ues_comp = self.mapping_ue_competences() + print(self.association_ues_comp) + """Association indiquant pour chaque UE , quelle compétence lui correspond""" self.competences_sorted = self.do_complist() + """Liste des compétences triées""" + + """Compétences extraites de tous les SxTag aggrégés""" pe_affichage.pe_print(f"* Compétences : {', '.join(self.competences_sorted)}") @@ -164,10 +170,8 @@ class RCSTag(TableTag): coeffs = moys_tag.matrice_coeffs_moy_gen.copy() # les coeffs # Traduction des UE en compétences - association_ues_comp = self.mapping_ue_competences() - print(association_ues_comp) ues_columns_df = notes.columns - comp_associes_aux_ues = [association_ues_comp[ue] for ue in ues_columns_df] + comp_associes_aux_ues = [self.association_ues_comp[ue] for ue in ues_columns_df] notes.columns = comp_associes_aux_ues coeffs.columns = comp_associes_aux_ues @@ -224,8 +228,8 @@ class RCSTag(TableTag): def do_complist(self): """Synthétise les compétences à partir des Sxtags aggrégés""" - dict_comptences = self.mapping_ue_competences() - return sorted(set(dict_comptences.values())) + dict_competences = self.mapping_ue_competences() + return sorted(set(dict_competences.values())) def compute_notes_competences( diff --git a/app/pe/pe_sxtag.py b/app/pe/pe_sxtag.py index 132824df8..208d9629d 100644 --- a/app/pe/pe_sxtag.py +++ b/app/pe/pe_sxtag.py @@ -143,59 +143,72 @@ class SxTag(TableTag): self.ressembuttags, self.fid_final, ) - # Affichage pour debug - for etud in self.etuds: - cap = [] - for frmsem_id in self.ressembuttags: - if frmsem_id != self.fid_final: - for accr in self.acronymes_ues_sorted: - if self.masque_df[frmsem_id].loc[etud.etudid, accr] > 0.0: - cap += [accr] - if cap: - pe_affichage.pe_print( - f" ⚠ Capitalisation de {etud.etat_civil} : {', '.join(cap)}" - ) + self._aff_capitalisations() for tag in self.tags_sorted: - # Cube de note etudids x UEs - notes_df, notes_cube = compute_notes_ues_cube( - tag, self.etudids_sorted, self.acronymes_ues_sorted, self.ressembuttags - ) + # Y-a-t-il des notes ? + if not self.has_notes(tag): + pe_affichage.pe_print(f"> MoyTag 🏷{tag} actuellement sans ◯ notes") + matrice_moys_ues = pd.DataFrame(np.nan, index=self.etudids_sorted, columns=self.acronymes_ues_sorted) + else: + # Cube de note etudids x UEs + notes_df, notes_cube = compute_notes_ues_cube( + tag, + self.etudids_sorted, + self.acronymes_ues_sorted, + self.ressembuttags, + ) + # self.ues_inscr_parcours = ~np.isnan(self.matrice_coeffs.to_numpy()) + # inscr_mask = self.ues_inscr_parcours + # Calcule des moyennes sous forme d'un dataframe + inscr_mask = ~np.isnan(self.ues_inscr_parcours_df.to_numpy()) + matrice_moys_ues: pd.DataFrame = compute_notes_ues( + notes_cube, + masque_cube, + self.etudids_sorted, + self.acronymes_ues_sorted, + inscr_mask, + ) + # Les profils d'ects (pour debug) + profils_ects = [] + for i in self.matrice_coeffs_moy_gen.index: + val = tuple(self.matrice_coeffs_moy_gen.loc[i].fillna("x")) + if tuple(val) not in profils_ects: + profils_ects.append(tuple(val)) + pe_affichage.pe_print( + f"> MoyTag 🏷{tag} avec " + + f"ues={self.acronymes_ues_sorted} " + + f"ects={profils_ects}" + ) - # self.ues_inscr_parcours = ~np.isnan(self.matrice_coeffs.to_numpy()) - # inscr_mask = self.ues_inscr_parcours - - # Calcule des moyennes sous forme d'un dataframe - inscr_mask = ~np.isnan(self.ues_inscr_parcours_df.to_numpy()) - matrice_moys_ues: pd.DataFrame = compute_notes_ues( - notes_cube, - masque_cube, - self.etudids_sorted, - self.acronymes_ues_sorted, - inscr_mask, - ) - - # Les profils d'ects (pour debug) - profils_ects = [] - for i in self.matrice_coeffs_moy_gen.index: - val = tuple(self.matrice_coeffs_moy_gen.loc[i].fillna("x")) - if tuple(val) not in profils_ects: - profils_ects.append(tuple(val)) - - # Les moyennes + # Les moyennes au tag self.moyennes_tags[tag] = MoyennesTag( - tag, matrice_moys_ues, self.matrice_coeffs_moy_gen - ) + tag, matrice_moys_ues, self.matrice_coeffs_moy_gen + ) - pe_affichage.pe_print( - f"> MoyTag 🏷{tag} avec " - + f"ues={self.acronymes_ues_sorted} " - + f"ects={profils_ects}" - ) + + def has_notes(self, tag): + """Détermine si le SxTag, pour un tag donné, est en cours d'évaluation. + Si oui, n'a pas (encore) de notes dans le resformsemestre final. + + Args: + tag: Le tag visé + + Returns: + True si a des notes, False sinon + """ + moy_tag_dernier_sem = self.ressembuttag_final.moyennes_tags[tag] + notes = moy_tag_dernier_sem.matrice_notes + nbre_nan = notes.isna().sum().sum() + nbre_notes_potentielles = len(notes.index) * len(notes.columns) + if nbre_nan == nbre_notes_potentielles: + return False + else: + return True def __eq__(self, other): """Egalité de 2 SxTag sur la base de leur identifiant""" @@ -210,6 +223,20 @@ class SxTag(TableTag): # affichage = [str(fid) for fid in self.ressembuttags] return f"{self.sxtag_id[0]}Tag (#{self.fid_final})" + def _aff_capitalisations(self): + """Affichage des capitalisations du sxtag pour debug""" + for etud in self.etuds: + cap = [] + for frmsem_id in self.ressembuttags: + if frmsem_id != self.fid_final: + for accr in self.acronymes_ues_sorted: + if self.masque_df[frmsem_id].loc[etud.etudid, accr] > 0.0: + cap += [accr] + if cap: + pe_affichage.pe_print( + f" ⚠ Capitalisation de {etud.etat_civil} : {', '.join(cap)}" + ) + def compute_notes_ues_cube( tag, etudids_sorted, acronymes_ues_sorted, ressembuttags @@ -291,7 +318,7 @@ def compute_masques_ues_cube( # Partant d'un dataframe contenant des 1.0 if frmsem_id == formsemestre_id_final: df = pd.DataFrame(1.0, index=etudids_sorted, columns=acronymes_ues_sorted) - else: # semestres redoublés + else: # semestres redoublés df = pd.DataFrame(0.0, index=etudids_sorted, columns=acronymes_ues_sorted) # Traitement des capitalisations