import numpy as np import pandas as pd from app import comp from app.comp.moy_sem import comp_ranks_series from app.pe.moys import pe_moy CODE_MOY_UE = "UEs" CODE_MOY_COMPETENCES = "Compétences" CHAMP_GENERAL = "Général" # Nom du champ de la moyenne générale class MoyennesTag: def __init__( self, tag: str, type_moyenne: str, 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 obtenues aux UE et au général (toutes UEs confondues) Args: tag: Un tag matrice_notes: Les moyennes (etudid x acronymes_ues ou etudid x compétences) aux différentes UEs ou compétences 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) """ self.tag = tag """Le tag associé aux moyennes""" self.type = type_moyenne """Le type de moyennes (par UEs ou par compétences)""" # Les moyennes par UE self.matrice_notes: pd.DataFrame = matrice_notes """Les notes aux UEs ou aux compétences (DataFrame)""" 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""" self.moyennes: dict[int, pd.DataFrame] = {} """Les dataframes retraçant les moyennes/classements/statistiques des étudiants aux UEs""" self.etudids = self.matrice_notes.index """Les étudids renseignés dans les moyennes""" self.champs = self.matrice_notes.columns """Les champs (acronymes d'UE ou compétences) renseignés dans les moyennes""" for col in self.champs: # if ue.type != UE_SPORT: notes = matrice_notes[col] self.moyennes[col] = pe_moy.Moyenne(notes) # Les moyennes générales 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 = pe_moy.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 la moytag 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) pour le tag considéré, en pondérant les notes obtenues au UE par les coeff (généralement les crédits ECTS). Args: moys: Les moyennes etudids x acronymes_ues/compétences coeff: Les coeff etudids x ueids/compétences """ # 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( moys, coeffs.fillna(0.0), # 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/compétences confondues" ) return moy_gen_tag 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 (nom d'aggrégat, type de cohorte). """ etudids_sorted = sorted(self.etudids) df = pd.DataFrame(index=etudids_sorted) # Ajout des notes pour tous les champs champs = list(self.champs) for champ in champs: df_champ = self.moyennes[champ].get_df_synthese() # le dataframe # Renomme les colonnes cols = [ 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 = self.moyenne_gen.get_df_synthese() cols = [ get_colonne_df(aggregat, self.tag, CHAMP_GENERAL, cohorte, critere) for critere in pe_moy.Moyenne.COLONNES_SYNTHESE ] df_moy_gen.columns = cols df = df.join(df_moy_gen) return df 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] liste_champs += [tag, champ] if cohorte != None: liste_champs += [cohorte] liste_champs += [critere] return "|".join(liste_champs)