From ee8cfc619149237961f88cafa54f5f76972f9a9e Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Thu, 21 Apr 2022 20:48:38 +0200 Subject: [PATCH 1/4] msg erreur apo_compare_csv --- app/scodoc/sco_apogee_compare.py | 12 +++++++++--- sco_version.py | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/scodoc/sco_apogee_compare.py b/app/scodoc/sco_apogee_compare.py index 86e2f334..b6cb042b 100644 --- a/app/scodoc/sco_apogee_compare.py +++ b/app/scodoc/sco_apogee_compare.py @@ -272,9 +272,15 @@ def _build_etud_res(e, apo_data): r = {} for elt_code in apo_data.apo_elts: elt = apo_data.apo_elts[elt_code] - col_ids_type = [ - (ec["apoL_a01_code"], ec["Type R\xc3\xa9s."]) for ec in elt.cols - ] # les colonnes de cet élément + try: + # les colonnes de cet élément + col_ids_type = [ + (ec["apoL_a01_code"], ec["Type R\xc3\xa9s."]) for ec in elt.cols + ] + except KeyError as exc: + raise ScoValueError( + "Erreur: un élément sans 'Type R\xc3\xa9s.'. Vérifiez l'encodage de vos fichiers." + ) from exc r[elt_code] = {} for (col_id, type_res) in col_ids_type: r[elt_code][type_res] = e.cols[col_id] diff --git a/sco_version.py b/sco_version.py index 24931a73..06ddcfb8 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.2.7" +SCOVERSION = "9.2.8" SCONAME = "ScoDoc" From adbe466392e2ae391b4d635b3069595c4a89f226 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Thu, 21 Apr 2022 22:24:09 +0200 Subject: [PATCH 2/4] Fix: edit_ue_set_code_apogee --- app/scodoc/sco_etape_apogee.py | 7 ++----- app/views/notes.py | 1 + 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/app/scodoc/sco_etape_apogee.py b/app/scodoc/sco_etape_apogee.py index 9c0e004c..8a14f561 100644 --- a/app/scodoc/sco_etape_apogee.py +++ b/app/scodoc/sco_etape_apogee.py @@ -32,11 +32,8 @@ Voir sco_apogee_csv.py pour la structure du fichier Apogée. Stockage: utilise sco_archive.py - => /opt/scodoc/var/scodoc/archives/apo_csv//2016-1/2016-07-03-16-12-19/V3ASR.csv - pour une maquette de l'année scolaire 2016, semestre 1, etape V3ASR - - ou bien (à partir de ScoDoc 1678) : - /opt/scodoc/var/scodoc/archives/apo_csv//2016-1/2016-07-03-16-12-19/V3ASR!111.csv + exemple: + /opt/scodoc-data/archives/apo_csv//2016-1/2016-07-03-16-12-19/V3ASR!111.csv pour une maquette de l'étape V3ASR version VDI 111. La version VDI sera ignorée sauf si elle est indiquée dans l'étape du semestre. diff --git a/app/views/notes.py b/app/views/notes.py index d6c6e1b0..cd0e5238 100644 --- a/app/views/notes.py +++ b/app/views/notes.py @@ -473,6 +473,7 @@ sco_publish( "/edit_ue_set_code_apogee", sco_edit_ue.edit_ue_set_code_apogee, Permission.ScoChangeFormation, + methods=["POST"], ) sco_publish( "/formsemestre_edit_uecoefs", From 14aabab74682367c01af7c3743ad6f724f393a26 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Thu, 21 Apr 2022 22:28:17 +0200 Subject: [PATCH 3/4] Pandas: replace deprecated Int64Index by Index(dtype=int) --- app/comp/inscr_mod.py | 2 +- app/comp/moy_mod.py | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/comp/inscr_mod.py b/app/comp/inscr_mod.py index 56567f80..a76f2430 100644 --- a/app/comp/inscr_mod.py +++ b/app/comp/inscr_mod.py @@ -34,7 +34,7 @@ def df_load_modimpl_inscr(formsemestre) -> pd.DataFrame: ) df = df.merge(ins_df, how="left", left_index=True, right_index=True) # Force columns names to integers (moduleimpl ids) - df.columns = pd.Int64Index([int(x) for x in df.columns], dtype="int") + df.columns = pd.Index([int(x) for x in df.columns], dtype=int) # les colonnes de df sont en float (Nan) quand il n'y a # aucun inscrit au module. df.fillna(0, inplace=True) # les non-inscrits diff --git a/app/comp/moy_mod.py b/app/comp/moy_mod.py index 13829a39..f5efbeb2 100644 --- a/app/comp/moy_mod.py +++ b/app/comp/moy_mod.py @@ -169,9 +169,7 @@ class ModuleImplResults: self.en_attente = True # Force columns names to integers (evaluation ids) - evals_notes.columns = pd.Int64Index( - [int(x) for x in evals_notes.columns], dtype="int" - ) + evals_notes.columns = pd.Index([int(x) for x in evals_notes.columns], dtype=int) self.evals_notes = evals_notes def _load_evaluation_notes(self, evaluation: Evaluation) -> pd.DataFrame: From b4f5634f2b78bc3c0fe313422df6a63186fe23b7 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Thu, 21 Apr 2022 22:54:06 +0200 Subject: [PATCH 4/4] Fix some unit tests --- app/comp/moy_ue.py | 8 ++++---- tests/unit/sco_fake_gen.py | 2 +- tests/unit/test_but_ues.py | 29 +++++++++++++++++++---------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/app/comp/moy_ue.py b/app/comp/moy_ue.py index 6d80f0b7..2d337a3d 100644 --- a/app/comp/moy_ue.py +++ b/app/comp/moy_ue.py @@ -271,7 +271,7 @@ def compute_ue_moys_apc( ) # Annule les coefs des modules NaN modimpl_coefs_etuds_no_nan = np.where(np.isnan(sem_cube), 0.0, modimpl_coefs_etuds) - if modimpl_coefs_etuds_no_nan.dtype == np.object: # arrive sur des tableaux vides + if modimpl_coefs_etuds_no_nan.dtype == object: # arrive sur des tableaux vides modimpl_coefs_etuds_no_nan = modimpl_coefs_etuds_no_nan.astype(np.float) # # Version vectorisée @@ -356,7 +356,7 @@ def compute_ue_moys_classic( 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 + if modimpl_coefs_etuds_no_nan.dtype == object: # arrive sur des tableaux vides modimpl_coefs_etuds_no_nan = modimpl_coefs_etuds_no_nan.astype(np.float) # --------------------- Calcul des moyennes d'UE ue_modules = np.array( @@ -367,7 +367,7 @@ def compute_ue_moys_classic( ) # 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) - if coefs.dtype == np.object: # arrive sur des tableaux vides + if coefs.dtype == object: # arrive sur des tableaux vides coefs = coefs.astype(np.float) with np.errstate(invalid="ignore"): # ignore les 0/0 (-> NaN) etud_moy_ue = ( @@ -462,7 +462,7 @@ def compute_mat_moys_classic( 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 + if modimpl_coefs_etuds_no_nan.dtype == 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( diff --git a/tests/unit/sco_fake_gen.py b/tests/unit/sco_fake_gen.py index a07e8116..0c9931ad 100644 --- a/tests/unit/sco_fake_gen.py +++ b/tests/unit/sco_fake_gen.py @@ -204,7 +204,7 @@ class ScoFake(object): abbrev=None, ects=None, code_apogee=None, - module_type=None, + module_type=scu.ModuleType.STANDARD, ) -> int: oid = sco_edit_module.do_module_create(locals()) oids = sco_edit_module.module_list(args={"module_id": oid}) diff --git a/tests/unit/test_but_ues.py b/tests/unit/test_but_ues.py index 0898bec8..bc0ad622 100644 --- a/tests/unit/test_but_ues.py +++ b/tests/unit/test_but_ues.py @@ -2,20 +2,15 @@ Test calcul moyennes UE """ import numpy as np -from numpy.lib.nanfunctions import _nanquantile_1d -import pandas as pd from tests.unit import setup -from tests.unit import sco_fake_gen from app import db -from app import models -from app.comp import moy_mod from app.comp import moy_ue from app.comp import inscr_mod from app.models import FormSemestre, Evaluation, ModuleImplInscription -from app.models.etudiants import Identite -from app.scodoc import sco_codes_parcours, sco_saisie_notes -from app.scodoc.sco_utils import NOTES_ATTENTE, NOTES_NEUTRALISE +from app.scodoc import sco_saisie_notes +from app.scodoc.sco_codes_parcours import UE_SPORT +from app.scodoc.sco_utils import NOTES_NEUTRALISE from app.scodoc import sco_exceptions @@ -69,9 +64,20 @@ def test_ue_moy(test_client): _ = sco_saisie_notes.notes_add(G.default_user, evaluation2.id, [(etudid, n2)]) # Recalcul des moyennes sem_cube, _, _ = moy_ue.notes_sem_load_cube(formsemestre) + # Masque de tous les modules _sauf_ les bonus (sport) + modimpl_mask = [ + modimpl.module.ue.type != UE_SPORT + for modimpl in formsemestre.modimpls_sorted + ] etuds = formsemestre.etuds.all() etud_moy_ue = moy_ue.compute_ue_moys_apc( - sem_cube, etuds, modimpls, ues, modimpl_inscr_df, modimpl_coefs_df + sem_cube, + etuds, + modimpls, + ues, + modimpl_inscr_df, + modimpl_coefs_df, + modimpl_mask, ) return etud_moy_ue @@ -113,8 +119,11 @@ def test_ue_moy(test_client): # Recalcule les notes: sem_cube, _, _ = moy_ue.notes_sem_load_cube(formsemestre) etuds = formsemestre.etuds.all() + modimpl_mask = [ + modimpl.module.ue.type != UE_SPORT for modimpl in formsemestre.modimpls_sorted + ] etud_moy_ue = moy_ue.compute_ue_moys_apc( - sem_cube, etuds, modimpls, ues, modimpl_inscr_df, modimpl_coefs_df + sem_cube, etuds, modimpls, ues, modimpl_inscr_df, modimpl_coefs_df, modimpl_mask ) assert etud_moy_ue[ue1.id][etudid] == n1 assert etud_moy_ue[ue2.id][etudid] == n1