Nouveau calcul (correct?) de la moyenne de matière en classic

This commit is contained in:
Emmanuel Viennet 2022-02-28 20:02:10 +01:00
parent b56a20643d
commit 13b40936b8
2 changed files with 67 additions and 6 deletions

View File

@ -40,13 +40,11 @@ def compute_mat_moys_classic(
modimpl_mask = np.array( modimpl_mask = np.array(
[m.module.matiere.id == matiere_id for m in formsemestre.modimpls_sorted] [m.module.matiere.id == matiere_id for m in formsemestre.modimpls_sorted]
) )
etud_moy_gen, _, _ = moy_ue.compute_ue_moys_classic( etud_moy_mat = moy_ue.compute_mat_moys_classic(
formsemestre,
sem_matrix=sem_matrix, sem_matrix=sem_matrix,
ues=ues,
modimpl_inscr_df=modimpl_inscr_df, modimpl_inscr_df=modimpl_inscr_df,
modimpl_coefs=modimpl_coefs, modimpl_coefs=modimpl_coefs,
modimpl_mask=modimpl_mask, modimpl_mask=modimpl_mask,
) )
matiere_moy[matiere_id] = etud_moy_gen matiere_moy[matiere_id] = etud_moy_mat
return matiere_moy return matiere_moy

View File

@ -294,7 +294,8 @@ def compute_ue_moys_classic(
modimpl_coefs: np.array, modimpl_coefs: np.array,
modimpl_mask: np.array, modimpl_mask: np.array,
) -> tuple[pd.Series, pd.DataFrame, pd.DataFrame]: ) -> tuple[pd.Series, pd.DataFrame, pd.DataFrame]:
"""Calcul de la moyenne d'UE en mode classique. """Calcul de la moyenne d'UE et de la moy. générale en mode classique (DUT, LMD, ...).
La moyenne d'UE est un nombre (note/20), ou NI ou NA ou ERR La moyenne d'UE est un nombre (note/20), ou NI ou NA ou ERR
NI non inscrit à (au moins un) module de cette UE NI non inscrit à (au moins un) module de cette UE
NA pas de notes disponibles NA pas de notes disponibles
@ -363,7 +364,7 @@ def compute_ue_moys_classic(
modimpl_coefs_etuds_no_nan_stacked = np.stack( modimpl_coefs_etuds_no_nan_stacked = np.stack(
[modimpl_coefs_etuds_no_nan.T] * nb_ues [modimpl_coefs_etuds_no_nan.T] * nb_ues
) )
# nb_ue x nb_etuds x nb_mods : coefs prenant en compte NaN et inscriptions # nb_ue x nb_etuds x nb_mods : coefs prenant en compte NaN et inscriptions:
coefs = (modimpl_coefs_etuds_no_nan_stacked * ue_modules).swapaxes(1, 2) coefs = (modimpl_coefs_etuds_no_nan_stacked * ue_modules).swapaxes(1, 2)
if coefs.dtype == np.object: # arrive sur des tableaux vides if coefs.dtype == np.object: # arrive sur des tableaux vides
coefs = coefs.astype(np.float) coefs = coefs.astype(np.float)
@ -408,6 +409,68 @@ def compute_ue_moys_classic(
return etud_moy_gen_s, etud_moy_ue_df, etud_coef_ue_df return etud_moy_gen_s, etud_moy_ue_df, etud_coef_ue_df
def compute_mat_moys_classic(
sem_matrix: np.array,
modimpl_inscr_df: pd.DataFrame,
modimpl_coefs: np.array,
modimpl_mask: np.array,
) -> pd.Series:
"""Calcul de la moyenne sur un sous-enemble de modules en formation CLASSIQUE
La moyenne est un nombre (note/20 ou NaN.
Le masque modimpl_mask est un tableau de booléens (un par modimpl) qui
permet de sélectionner un sous-ensemble de modules (ceux de la matière d'intérêt).
sem_matrix: notes moyennes aux modules (tous les étuds x tous les modimpls)
ndarray (etuds x modimpls)
(floats avec des NaN)
etuds : listes des étudiants (dim. 0 de la matrice)
modimpl_inscr_df: matrice d'inscription du semestre (etud x modimpl)
modimpl_coefs: vecteur des coefficients de modules
modimpl_mask: masque des modimpls à prendre en compte
Résultat:
- moyennes: pd.Series, index etudid
"""
if (not len(modimpl_mask)) or (
sem_matrix.shape[0] == 0
): # aucun module ou aucun étudiant
# etud_moy_gen_s, etud_moy_ue_df, etud_coef_ue_df
return pd.Series(
[0.0] * len(modimpl_inscr_df.index), index=modimpl_inscr_df.index
)
# Restreint aux modules sélectionnés:
sem_matrix = sem_matrix[:, modimpl_mask]
modimpl_inscr = modimpl_inscr_df.values[:, modimpl_mask]
modimpl_coefs = modimpl_coefs[modimpl_mask]
nb_etuds, nb_modules = sem_matrix.shape
assert len(modimpl_coefs) == nb_modules
# Enlève les NaN du numérateur:
sem_matrix_no_nan = np.nan_to_num(sem_matrix, nan=0.0)
# Ne prend pas en compte les notes des étudiants non inscrits au module:
# Annule les notes:
sem_matrix_inscrits = np.where(modimpl_inscr, sem_matrix_no_nan, 0.0)
# Annule les coefs des modules où l'étudiant n'est pas inscrit:
modimpl_coefs_etuds = np.where(
modimpl_inscr, np.stack([modimpl_coefs.T] * nb_etuds), 0.0
)
# Annule les coefs des modules NaN (nb_etuds x nb_mods)
modimpl_coefs_etuds_no_nan = np.where(
np.isnan(sem_matrix), 0.0, modimpl_coefs_etuds
)
if modimpl_coefs_etuds_no_nan.dtype == np.object: # arrive sur des tableaux vides
modimpl_coefs_etuds_no_nan = modimpl_coefs_etuds_no_nan.astype(np.float)
etud_moy_mat = (modimpl_coefs_etuds_no_nan * sem_matrix_inscrits).sum(
axis=1
) / modimpl_coefs_etuds_no_nan.sum(axis=1)
return pd.Series(etud_moy_mat, index=modimpl_inscr_df.index)
def compute_malus( def compute_malus(
formsemestre: FormSemestre, formsemestre: FormSemestre,
sem_modimpl_moys: np.array, sem_modimpl_moys: np.array,