From 6749ca70d6b244773ca0b0a647902532d8e833db Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Tue, 28 May 2024 13:51:27 +0200 Subject: [PATCH] Fix prise en compte evals session 2 avec poids ne couvrant pas toutes les UEs (#811) --- app/comp/moy_mod.py | 14 +++++++++----- app/comp/moy_ue.py | 6 ++++-- app/comp/res_but.py | 9 +++++---- sco_version.py | 2 +- tests/unit/test_but_modules.py | 6 ++++-- tests/unit/test_but_ues.py | 11 +++++++++-- 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/app/comp/moy_mod.py b/app/comp/moy_mod.py index 3ed27ffa..aa315ffd 100644 --- a/app/comp/moy_mod.py +++ b/app/comp/moy_mod.py @@ -360,12 +360,13 @@ class ModuleImplResultsAPC(ModuleImplResults): "Calcul des moyennes de modules à la mode BUT" def compute_module_moy( - self, - evals_poids_df: pd.DataFrame, + self, evals_poids_df: pd.DataFrame, modimpl_coefs_df: pd.DataFrame ) -> pd.DataFrame: """Calcule les moyennes des étudiants dans ce module - Argument: evals_poids: DataFrame, colonnes: UEs, Lignes: EVALs + Argument: + evals_poids: DataFrame, colonnes: UEs, lignes: EVALs + modimpl_coefs_df: DataFrame, colonnes: modimpl_id, lignes: ue_id Résultat: DataFrame, colonnes UE, lignes etud = la note de l'étudiant dans chaque UE pour ce module. @@ -427,8 +428,11 @@ class ModuleImplResultsAPC(ModuleImplResults): Evaluation.EVALUATION_SESSION2, ) - # Vrai si toutes les UEs ont bien une note de session 2 calculée: - etuds_use_session2 = np.all(np.isfinite(etuds_moy_module_s2), axis=1) + # Vrai si toutes les UEs avec coef non nul ont bien une note de session 2 calculée: + mod_coefs = modimpl_coefs_df[modimpl.id] + etuds_use_session2 = np.all( + np.isfinite(etuds_moy_module_s2[:, mod_coefs != 0]), axis=1 + ) etuds_moy_module = np.where( etuds_use_session2[:, np.newaxis], etuds_moy_module_s2, diff --git a/app/comp/moy_ue.py b/app/comp/moy_ue.py index d247301f..24fdbd46 100644 --- a/app/comp/moy_ue.py +++ b/app/comp/moy_ue.py @@ -183,7 +183,9 @@ def notes_sem_assemble_cube(modimpls_notes: list[pd.DataFrame]) -> np.ndarray: return modimpls_notes.swapaxes(0, 1) -def notes_sem_load_cube(formsemestre: FormSemestre) -> tuple: +def notes_sem_load_cube( + formsemestre: FormSemestre, modimpl_coefs_df: pd.DataFrame +) -> tuple: """Construit le "cube" (tenseur) des notes du semestre. Charge toutes les notes (sql), calcule les moyennes des modules et assemble le cube. @@ -208,7 +210,7 @@ def notes_sem_load_cube(formsemestre: FormSemestre) -> tuple: for modimpl in formsemestre.modimpls_sorted: mod_results = moy_mod.ModuleImplResultsAPC(modimpl, etudids, etudids_actifs) evals_poids = modimpl.get_evaluations_poids() - etuds_moy_module = mod_results.compute_module_moy(evals_poids) + etuds_moy_module = mod_results.compute_module_moy(evals_poids, modimpl_coefs_df) modimpls_results[modimpl.id] = mod_results modimpls_evals_poids[modimpl.id] = evals_poids modimpls_notes.append(etuds_moy_module) diff --git a/app/comp/res_but.py b/app/comp/res_but.py index c6d99fb9..a92c9950 100644 --- a/app/comp/res_but.py +++ b/app/comp/res_but.py @@ -59,16 +59,17 @@ class ResultatsSemestreBUT(NotesTableCompat): def compute(self): "Charge les notes et inscriptions et calcule les moyennes d'UE et gen." + self.modimpl_coefs_df, _, _ = moy_ue.df_load_modimpl_coefs( + self.formsemestre, modimpls=self.formsemestre.modimpls_sorted + ) ( self.sem_cube, self.modimpls_evals_poids, self.modimpls_results, - ) = moy_ue.notes_sem_load_cube(self.formsemestre) + ) = moy_ue.notes_sem_load_cube(self.formsemestre, self.modimpl_coefs_df) self.modimpl_inscr_df = inscr_mod.df_load_modimpl_inscr(self.formsemestre) self.ues_inscr_parcours_df = self.load_ues_inscr_parcours() - self.modimpl_coefs_df, _, _ = moy_ue.df_load_modimpl_coefs( - self.formsemestre, modimpls=self.formsemestre.modimpls_sorted - ) + # l'idx de la colonne du mod modimpl.id est # modimpl_coefs_df.columns.get_loc(modimpl.id) # idx de l'UE: modimpl_coefs_df.index.get_loc(ue.id) diff --git a/sco_version.py b/sco_version.py index 4675621d..16534d3d 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.6.967" +SCOVERSION = "9.6.968" SCONAME = "ScoDoc" diff --git a/tests/unit/test_but_modules.py b/tests/unit/test_but_modules.py index 684248e6..515e156e 100644 --- a/tests/unit/test_but_modules.py +++ b/tests/unit/test_but_modules.py @@ -253,8 +253,10 @@ def test_module_moy(test_client): mod_results = moy_mod.ModuleImplResultsAPC(modimpl, etudids, etudids_actifs) evals_notes = mod_results.evals_notes assert evals_notes[evaluation1.id].dtype == np.float64 - - etuds_moy_module = mod_results.compute_module_moy(evals_poids) + modimpl_coefs_df, _, _ = moy_ue.df_load_modimpl_coefs( + formsemestre, modimpls=formsemestre.modimpls_sorted + ) + etuds_moy_module = mod_results.compute_module_moy(evals_poids, modimpl_coefs_df) return etuds_moy_module # --- Notes ordinaires: diff --git a/tests/unit/test_but_ues.py b/tests/unit/test_but_ues.py index ee66bcde..1c0e33ae 100644 --- a/tests/unit/test_but_ues.py +++ b/tests/unit/test_but_ues.py @@ -1,6 +1,7 @@ """ Test calcul moyennes UE """ + import numpy as np from tests.unit import setup @@ -63,7 +64,10 @@ def test_ue_moy(test_client): _ = sco_saisie_notes.notes_add(G.default_user, evaluation1.id, [(etudid, n1)]) _ = sco_saisie_notes.notes_add(G.default_user, evaluation2.id, [(etudid, n2)]) # Recalcul des moyennes - sem_cube, _, _ = moy_ue.notes_sem_load_cube(formsemestre) + modimpl_coefs_df, _, _ = moy_ue.df_load_modimpl_coefs( + formsemestre, modimpls=formsemestre.modimpls_sorted + ) + sem_cube, _, _ = moy_ue.notes_sem_load_cube(formsemestre, modimpl_coefs_df) # Masque de tous les modules _sauf_ les bonus (sport) modimpl_mask = [ modimpl.module.ue.type != UE_SPORT @@ -117,7 +121,10 @@ def test_ue_moy(test_client): exception_raised = True assert exception_raised # Recalcule les notes: - sem_cube, _, _ = moy_ue.notes_sem_load_cube(formsemestre) + modimpl_coefs_df, _, _ = moy_ue.df_load_modimpl_coefs( + formsemestre, modimpls=formsemestre.modimpls_sorted + ) + sem_cube, _, _ = moy_ue.notes_sem_load_cube(formsemestre, modimpl_coefs_df) etuds = formsemestre.etuds.all() modimpl_mask = [ modimpl.module.ue.type != UE_SPORT for modimpl in formsemestre.modimpls_sorted