From ba974df04f138743168b732f2f254852b6985ac6 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 21 Feb 2022 15:10:10 +0100 Subject: [PATCH 1/3] =?UTF-8?q?Fix:=20mise=20=C3=A0=20jour=20bonus=20sur?= =?UTF-8?q?=20oy.=20gen.=20apr=C3=A8s=20capitalisation=20UEs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/comp/res_common.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/comp/res_common.py b/app/comp/res_common.py index b019c9770..14042364a 100644 --- a/app/comp/res_common.py +++ b/app/comp/res_common.py @@ -165,7 +165,6 @@ class ResultatsSemestre(ResultatsCache): """ # Supposant qu'il y a peu d'UE capitalisées, # on va soustraire la moyenne d'UE et ajouter celle de l'UE capitalisée. - # return # XXX XXX XXX if not self.validations: self.validations = res_sem.load_formsemestre_validations(self.formsemestre) ue_capitalisees = self.validations.ue_capitalisees @@ -184,7 +183,9 @@ class ResultatsSemestre(ResultatsCache): sum_coefs_ue = 0.0 for ue in self.formsemestre.query_ues(): ue_cap = self.get_etud_ue_status(etudid, ue.id) - if ue_cap and ue_cap["is_capitalized"]: + if ue_cap is None: + continue + if ue_cap["is_capitalized"]: recompute_mg = True coef = ue_cap["coef_ue"] if not np.isnan(ue_cap["moy"]): @@ -195,6 +196,12 @@ class ResultatsSemestre(ResultatsCache): # On doit prendre en compte une ou plusieurs UE capitalisées # et donc recalculer la moyenne générale self.etud_moy_gen[etudid] = sum_notes_ue / sum_coefs_ue + # Ajoute le bonus sport + if self.bonus is not None and self.bonus[etudid]: + self.etud_moy_gen[etudid] += self.bonus[etudid] + self.etud_moy_gen[etudid] = max( + 0.0, min(self.etud_moy_gen[etudid], 20.0) + ) def _get_etud_ue_cap(self, etudid, ue): """""" From 0801919b80d6e24c81f8dab3b94489c74c53f5bc Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 21 Feb 2022 17:36:50 +0100 Subject: [PATCH 2/3] =?UTF-8?q?Calcul=20moyennes=20mati=C3=A8res=20(format?= =?UTF-8?q?ions=20classiques).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/comp/moy_mat.py | 52 +++++++++++++++++++++++++++++++++++++++++ app/comp/moy_ue.py | 1 - app/comp/res_classic.py | 17 +++++++++++++- app/comp/res_common.py | 8 +++++-- 4 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 app/comp/moy_mat.py diff --git a/app/comp/moy_mat.py b/app/comp/moy_mat.py new file mode 100644 index 000000000..e5ba903c2 --- /dev/null +++ b/app/comp/moy_mat.py @@ -0,0 +1,52 @@ +############################################################################## +# ScoDoc +# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved. +# See LICENSE +############################################################################## + +"""Calcul des moyennes de matières +""" + +# C'est un recalcul (optionnel) effectué _après_ le calcul standard. + +import numpy as np +import pandas as pd +from app.comp import moy_ue +from app.models.formsemestre import FormSemestre + +from app.scodoc.sco_codes_parcours import UE_SPORT +from app.scodoc.sco_utils import ModuleType + + +def compute_mat_moys_classic( + formsemestre: FormSemestre, + sem_matrix: np.array, + ues: list, + modimpl_inscr_df: pd.DataFrame, + modimpl_coefs: np.array, +) -> dict: + """Calcul des moyennes par matières. + Result: dict, { matiere_id : Series, index etudid } + """ + modimpls_std = [ + m + for m in formsemestre.modimpls_sorted + if (m.module.module_type == ModuleType.STANDARD) + and (m.module.ue.type != UE_SPORT) + ] + matiere_ids = {m.module.matiere.id for m in modimpls_std} + matiere_moy = {} # { matiere_id : moy pd.Series, index etudid } + for matiere_id in matiere_ids: + modimpl_mask = np.array( + [m.module.matiere.id == matiere_id for m in formsemestre.modimpls_sorted] + ) + etud_moy_gen, _, _ = moy_ue.compute_ue_moys_classic( + formsemestre, + sem_matrix=sem_matrix, + ues=ues, + modimpl_inscr_df=modimpl_inscr_df, + modimpl_coefs=modimpl_coefs, + modimpl_mask=modimpl_mask, + ) + matiere_moy[matiere_id] = etud_moy_gen + return matiere_moy diff --git a/app/comp/moy_ue.py b/app/comp/moy_ue.py index 8b98d2ef4..563fb3b1d 100644 --- a/app/comp/moy_ue.py +++ b/app/comp/moy_ue.py @@ -27,7 +27,6 @@ """Fonctions de calcul des moyennes d'UE (classiques ou BUT) """ -from re import X import numpy as np import pandas as pd diff --git a/app/comp/res_classic.py b/app/comp/res_classic.py index 1dfcfb4da..ecc1e5004 100644 --- a/app/comp/res_classic.py +++ b/app/comp/res_classic.py @@ -15,7 +15,7 @@ from flask import g, url_for from app import db from app import log -from app.comp import moy_mod, moy_ue, inscr_mod +from app.comp import moy_mat, moy_mod, moy_ue, inscr_mod from app.comp.res_common import NotesTableCompat from app.comp.bonus_spo import BonusSport from app.models import ScoDocSiteConfig @@ -24,6 +24,7 @@ from app.models.formsemestre import FormSemestre from app.models.ues import UniteEns from app.scodoc.sco_codes_parcours import UE_SPORT from app.scodoc.sco_exceptions import ScoValueError +from app.scodoc import sco_preferences from app.scodoc.sco_utils import ModuleType @@ -133,6 +134,10 @@ class ResultatsSemestreClassic(NotesTableCompat): # --- Classements: self.compute_rangs() + # --- En option, moyennes par matières + if sco_preferences.get_preference("bul_show_matieres", self.formsemestre.id): + self.compute_moyennes_matieres() + def get_etud_mod_moy(self, moduleimpl_id: int, etudid: int) -> float: """La moyenne de l'étudiant dans le moduleimpl Result: valeur float (peut être NaN) ou chaîne "NI" (non inscrit ou DEM) @@ -158,6 +163,16 @@ class ResultatsSemestreClassic(NotesTableCompat): ), } + def compute_moyennes_matieres(self): + """Calcul les moyennes par matière. Doit être appelée au besoin, en fin de compute.""" + self.moyennes_matieres = moy_mat.compute_mat_moys_classic( + self.formsemestre, + self.sem_matrix, + self.ues, + self.modimpl_inscr_df, + self.modimpl_coefs, + ) + def compute_etud_ue_coef(self, etudid: int, ue: UniteEns) -> float: """Détermine le coefficient de l'UE pour cet étudiant. N'est utilisé que pour l'injection des UE capitalisées dans la diff --git a/app/comp/res_common.py b/app/comp/res_common.py index 14042364a..5f652ec5c 100644 --- a/app/comp/res_common.py +++ b/app/comp/res_common.py @@ -39,6 +39,7 @@ class ResultatsSemestre(ResultatsCache): "modimpl_inscr_df", "modimpls_results", "etud_coef_ue_df", + "moyennes_matieres", ) def __init__(self, formsemestre: FormSemestre): @@ -57,6 +58,8 @@ class ResultatsSemestre(ResultatsCache): self.etud_coef_ue_df = None """coefs d'UE effectifs pour chaque étudiant (pour form. classiques)""" self.validations = None + self.moyennes_matieres = {} + """Moyennes de matières, si calculées. { matiere_id : Series, index etudid }""" def compute(self): "Charge les notes et inscriptions et calcule toutes les moyennes" @@ -517,8 +520,9 @@ class NotesTableCompat(ResultatsSemestre): def get_etud_mat_moy(self, matiere_id, etudid): """moyenne d'un étudiant dans une matière (ou NA si pas de notes)""" - # non supporté en 9.2 - return "na" + if not self.moyennes_matieres: + return "nd" + return self.moyennes_matieres[matiere_id][etudid] def get_etud_mod_moy(self, moduleimpl_id: int, etudid: int) -> float: """La moyenne de l'étudiant dans le moduleimpl From d314d47dc5044f351a53f378792dc7cfb8ccf037 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 21 Feb 2022 18:51:45 +0100 Subject: [PATCH 3/3] traitement erreur sur formsemestre_description --- app/scodoc/sco_formsemestre_status.py | 7 ++++--- sco_version.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/scodoc/sco_formsemestre_status.py b/app/scodoc/sco_formsemestre_status.py index d8be56f27..2c8465150 100644 --- a/app/scodoc/sco_formsemestre_status.py +++ b/app/scodoc/sco_formsemestre_status.py @@ -595,11 +595,12 @@ def formsemestre_description_table(formsemestre_id, with_evals=False): """Description du semestre sous forme de table exportable Liste des modules et de leurs coefficients """ - sem = sco_formsemestre.get_formsemestre(formsemestre_id) formsemestre = FormSemestre.query.get_or_404(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) use_ue_coefs = sco_preferences.get_preference("use_ue_coefs", formsemestre_id) - F = sco_formations.formation_list(args={"formation_id": sem["formation_id"]})[0] + F = sco_formations.formation_list(args={"formation_id": formsemestre.formation_id})[ + 0 + ] parcours = sco_codes_parcours.get_parcours_from_code(F["type_parcours"]) Mlist = sco_moduleimpl.moduleimpl_withmodule_list( formsemestre_id=formsemestre_id, sort_by_ue=True @@ -709,7 +710,7 @@ def formsemestre_description_table(formsemestre_id, with_evals=False): titles["coefficient"] = "Coef. éval." titles["evalcomplete_str"] = "Complète" titles["publish_incomplete_str"] = "Toujours Utilisée" - title = "%s %s" % (parcours.SESSION_NAME.capitalize(), sem["titremois"]) + title = "%s %s" % (parcours.SESSION_NAME.capitalize(), formsemestre.titre_mois()) return GenTable( columns_ids=columns_ids, diff --git a/sco_version.py b/sco_version.py index 9e02cffd1..4ac94b210 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.1.61" +SCOVERSION = "9.1.62" SCONAME = "ScoDoc"