diff --git a/app/pe/moys/pe_interclasstag.py b/app/pe/moys/pe_interclasstag.py index 3d2b5302d..3e026b5b0 100644 --- a/app/pe/moys/pe_interclasstag.py +++ b/app/pe/moys/pe_interclasstag.py @@ -84,7 +84,7 @@ class InterClassTag(pe_tabletags.TableTag): self.type = type_interclassement pe_affichage.pe_print( - f"--> Interclassement par 🗂️{type_interclassement} pour le RCS ⏯️{nom_rcs}" + f"*** Interclassement par 🗂️{type_interclassement} pour le RCS ⏯️{nom_rcs}" ) # Les informations sur les étudiants diplômés @@ -119,13 +119,20 @@ class InterClassTag(pe_tabletags.TableTag): # Les données sur les tags self.tags_sorted = self._do_taglist() """Liste des tags (triés par ordre alphabétique)""" - aff_tag = ["👜" + tag for tag in self.tags_sorted] - pe_affichage.pe_print(f"--> Tags : {', '.join(aff_tag)}") + aff = pe_affichage.aff_tag(self.tags_sorted) + pe_affichage.pe_print(f"--> Tags : {aff}") # Les données sur les UEs (si SxTag) ou compétences (si RCSTag) self.champs_sorted = self._do_ues_ou_competences_list() """Les champs (UEs ou compétences) de l'interclassement""" - self._aff_comp_ou_ues_debug() + if self.type == pe_moytag.CODE_MOY_UE: + pe_affichage.pe_print( + f"--> UEs : {pe_affichage.aff_UEs(self.champs_sorted)}" + ) + else: + pe_affichage.pe_print( + f"--> Compétences : {pe_affichage.aff_competences(self.champs_sorted)}" + ) # Construit la matrice de notes etudids_sorted = sorted(list(self.diplomes_ids)) @@ -136,15 +143,14 @@ class InterClassTag(pe_tabletags.TableTag): # Synthétise les moyennes/classements par tag self.moyennes_tags: dict[str, pe_moytag.MoyennesTag] = {} for tag in self.tags_sorted: - pe_affichage.pe_print(f"--> Moyenne 👜{tag} : ") - notes = self.compute_notes_matrice(tag, etudids_sorted, self.champs_sorted) coeffs = self.compute_coeffs_matrice( tag, etudids_sorted, self.champs_sorted ) - self.__aff_profil_coeffs(coeffs) + aff = pe_affichage.aff_profil_coeffs(coeffs, with_index=True) + pe_affichage.pe_print(f"--> Moyenne 👜{tag} avec coeffs: {aff} ") self.moyennes_tags[tag] = pe_moytag.MoyennesTag( tag, @@ -248,7 +254,7 @@ class InterClassTag(pe_tabletags.TableTag): for rcstag in self.rcstags.values(): if tag in rcstag.moyennes_tags: # Charge les coeffs au tag d'un RCStag - coeffs: pd.DataFrame = rcstag.moyennes_tags[tag].matrice_notes + coeffs: pd.DataFrame = rcstag.moyennes_tags[tag].matrice_coeffs_moy_gen # Etudiants/Champs communs entre le RCSTag et les données interclassées ( @@ -279,21 +285,6 @@ class InterClassTag(pe_tabletags.TableTag): dict_champs.extend(champs) return sorted(set(dict_champs)) - def _aff_comp_ou_ues_debug(self): - """Affichage pour debug""" - aff_comp = [] - - for comp in self.champs_sorted: - liste = [] - if self.type == pe_moytag.CODE_MOY_UE: - liste += ["📍" + comp] - else: - liste += ["💡" + comp] - if self.type == pe_moytag.CODE_MOY_UE: - pe_affichage.pe_print(f"--> UEs : {', '.join(aff_comp)}") - else: - pe_affichage.pe_print(f"--> Compétences : {', '.join(aff_comp)}") - def has_tags(self): """Indique si l'interclassement a des tags (cas d'un interclassement sur un S5 qui n'a pas eu lieu) diff --git a/app/pe/moys/pe_moy.py b/app/pe/moys/pe_moy.py index 2342a7a13..5936f06bd 100644 --- a/app/pe/moys/pe_moy.py +++ b/app/pe/moys/pe_moy.py @@ -99,7 +99,9 @@ class Moyenne: def get_df_synthese(self): """Renvoie le df de synthese limité aux colonnes de synthese""" - return self.df[self.COLONNES_SYNTHESE] + df = self.df[self.COLONNES_SYNTHESE].copy() + df["rang"] = df["rang"].replace("nan", "") + return df def to_dict(self) -> dict: """Renvoie un dictionnaire de synthèse des moyennes/classements/statistiques générale (but)""" diff --git a/app/pe/moys/pe_rcstag.py b/app/pe/moys/pe_rcstag.py index 22d806cbc..75286aeb4 100644 --- a/app/pe/moys/pe_rcstag.py +++ b/app/pe/moys/pe_rcstag.py @@ -173,7 +173,10 @@ class RCSemXTag(pe_tabletags.TableTag): self.etudids_sorted, self.competences_sorted, ) - pe_affichage.aff_profil_coeffs(matrice_coeffs_moy_gen) + aff = pe_affichage.aff_profil_coeffs( + matrice_coeffs_moy_gen, with_index=True + ) + pe_affichage.pe_print(f" > Moyenne calculée avec pour coeffs : {aff}") # Mémorise les moyennes et les coeff associés self.moyennes_tags[tag] = pe_moytag.MoyennesTag( @@ -344,23 +347,19 @@ class RCSemXTag(pe_tabletags.TableTag): inscription_df = pd.DataFrame( 0, index=etudids_sorted, columns=competences_sorted ) + + # Les étudiants dont les résultats au sxtag ont été calculés + etudids_sxtag = sxtag.etudids_sorted + + # Les étudiants communs + etudids_communs = sorted(set(etudids_sorted) & set(etudids_sxtag)) + + # Acte l'inscription + inscription_df.loc[etudids_communs, :] = 1 + # Stocke les dfs inscriptions_dfs[sxtag_id] = inscription_df - for etudid in etudids_sorted: - for sem in self.rcsemx.aggregat: - if etudid in self.semXs_suivis: - semx_suivi = self.semXs_suivis[etudid][sem] - if semx_suivi: - semx_suivi_id = semx_suivi.rcs_id - if semx_suivi_id not in self.sxtags_connus: - pe_affichage.pe_print( - f"Un SxTag est manquant : {semx_suivi_id}" - ) - if semx_suivi_id in inscriptions_dfs: - # Si le sxtag est l'un des siens - inscriptions_dfs[semx_suivi_id].loc[etudid, :] = 1 - """Réunit les inscriptions sous forme d'un cube etudids x competences x semestres""" sxtag_x_etudids_x_comps = [inscriptions_dfs[sxtag_id] for sxtag_id in sxstags] inscriptions_etudids_x_comps_x_sxtag = np.stack( @@ -434,14 +433,13 @@ def compute_coeffs_competences( # Applique le masque des inscriptions aux coeffs et aux notes coeffs_significatifs = coeff_cube * inscriptions - set_cube_significatif = set_cube * inscriptions - - # Quelles entrées du cube contiennent des notes ? - mask = ~np.isnan(set_cube_significatif) # Enlève les NaN du cube de notes pour les entrées manquantes coeffs_cube_no_nan = np.nan_to_num(coeffs_significatifs, nan=0.0) + # Quelles entrées du cube contiennent des notes ? + mask = ~np.isnan(set_cube) + # Retire les coefficients associés à des données sans notes coeffs_cube_no_nan = coeffs_cube_no_nan * mask @@ -453,7 +451,7 @@ def compute_coeffs_competences( coeff_tag, index=etudids_sorted, columns=competences_sorted ) # Remet à Nan les coeffs à 0 - coeffs_df.fillna(np.nan) + coeffs_df = coeffs_df.fillna(np.nan) return coeffs_df diff --git a/app/pe/moys/pe_ressemtag.py b/app/pe/moys/pe_ressemtag.py index 39636f1f5..2b2b7581d 100644 --- a/app/pe/moys/pe_ressemtag.py +++ b/app/pe/moys/pe_ressemtag.py @@ -8,7 +8,7 @@ # Copyright (c) 1999 - 2024 Emmanuel Viennet. All rights reserved. # # This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by +# it under the terms of the GNU Generfal Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # diff --git a/app/pe/moys/pe_sxtag.py b/app/pe/moys/pe_sxtag.py index e81d0c6df..36ef71a42 100644 --- a/app/pe/moys/pe_sxtag.py +++ b/app/pe/moys/pe_sxtag.py @@ -189,7 +189,10 @@ class SxTag(pe_tabletags.TableTag): ) # Affichage de debug - self.__aff_profil_coeff_ects(tag) + aff = pe_affichage.aff_profil_coeffs( + self.matrice_coeffs_moy_gen, with_index=True + ) + pe_affichage.pe_print(f" > MoyTag 👜{tag} : {aff}") # Mémorise les infos pour la moyennes au tag self.moyennes_tags[tag] = pe_moytag.MoyennesTag( @@ -471,6 +474,6 @@ def compute_notes_ues( columns=acronymes_sorted, # les acronymes d'UEs ) - etud_moy_tag_df.fillna(np.nan) + etud_moy_tag_df = etud_moy_tag_df.fillna(np.nan) return etud_moy_tag_df diff --git a/app/pe/pe_affichage.py b/app/pe/pe_affichage.py index 79dfaabfa..3dc97265c 100644 --- a/app/pe/pe_affichage.py +++ b/app/pe/pe_affichage.py @@ -9,7 +9,7 @@ from flask import g from app import log -PE_DEBUG = True +PE_DEBUG = False # On stocke les logs PE dans g.scodoc_pe_log @@ -76,6 +76,31 @@ def aff_profil_coeffs(matrice_coeffs_moy_gen, with_index=False): profils_aff = "\n" + "\n".join(elmts) else: profils_aff = "\n".join(profils) - pe_print( - f" > Moyenne calculée avec pour coeffs (de compétences) : {profils_aff}" - ) + return profils_aff + + +def aff_UEs(champs): + """Affiche les UEs""" + champs_tries = sorted(champs) + aff_comp = [] + + for comp in champs_tries: + aff_comp += ["📍" + comp] + return ", ".join(aff_comp) + + +def aff_competences(champs): + """Affiche les compétences""" + champs_tries = sorted(champs) + aff_comp = [] + + for comp in champs_tries: + aff_comp += ["💡" + comp] + return ", ".join(aff_comp) + + +def aff_tag(tags): + """Affiche les tags""" + tags_tries = sorted(tags) + aff_tag = ["👜" + tag for tag in tags_tries] + return ", ".join(aff_tag) diff --git a/app/pe/pe_jury.py b/app/pe/pe_jury.py index c20825170..e47442ee6 100644 --- a/app/pe/pe_jury.py +++ b/app/pe/pe_jury.py @@ -451,6 +451,7 @@ class JuryPE(object): 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)}") output.seek(0) @@ -563,6 +564,7 @@ class JuryPE(object): tags_cibles=[tag], cohorte="Promo", ) + if not df_promo.empty: aff_aggregat += [aggregat] df = df.join(df_promo) @@ -634,14 +636,14 @@ class JuryPE(object): ) if colonne in df.columns: valeur = df.loc[etudid, colonne] - if valeur != "nan": + if valeur and str(valeur) != "nan": moyennes[tag][aggregat][comp]["rang_groupe"] = valeur colonne = pe_moytag.get_colonne_df( aggregat, tag, comp, "Promo", "rang" ) if colonne in df.columns: valeur = df.loc[etudid, colonne] - if valeur != "nan": + if valeur and str(valeur) != "nan": moyennes[tag][aggregat][comp]["rang_promo"] = valeur html = template.render(