FIX: calcul notes moyennes avec rattrapages ou session 2 + test unitaire

This commit is contained in:
Emmanuel Viennet 2022-11-13 14:22:47 +01:00
parent 643598e5d2
commit 3bc60c268a
2 changed files with 97 additions and 12 deletions

View File

@ -35,14 +35,15 @@ moyenne générale d'une UE.
"""
import dataclasses
from dataclasses import dataclass
import numpy as np
import pandas as pd
from app import db
from app.models import ModuleImpl, Evaluation, EvaluationUEPoids
from app.models import Evaluation, EvaluationUEPoids, ModuleImpl
from app.scodoc import sco_cache
from app.scodoc import sco_utils as scu
from app.scodoc.sco_codes_parcours import UE_SPORT
from app.scodoc import sco_cache
from app.scodoc.sco_exceptions import ScoBugCatcher
from app.scodoc.sco_utils import ModuleType
@ -217,12 +218,19 @@ class ModuleImplResults:
]
def get_evaluations_coefs(self, moduleimpl: ModuleImpl) -> np.array:
"""Coefficients des évaluations, met à zéro ceux des évals incomplètes.
"""Coefficients des évaluations.
Les coefs des évals incomplètes et non "normales" (session 2, rattrapage)
sont zéro.
Résultat: 2d-array of floats, shape (nb_evals, 1)
"""
return (
np.array(
[e.coefficient for e in moduleimpl.evaluations],
[
e.coefficient
if e.evaluation_type == scu.EVALUATION_NORMALE
else 0.0
for e in moduleimpl.evaluations
],
dtype=float,
)
* self.evaluations_completes
@ -236,8 +244,8 @@ class ModuleImplResults:
]
def get_eval_notes_sur_20(self, moduleimpl: ModuleImpl) -> np.array:
"""Les notes des évaluations,
remplace les ATT, EXC, ABS, NaN par zéro et mets les notes sur 20.
"""Les notes de toutes les évaluations du module, complètes ou non.
Remplace les ATT, EXC, ABS, NaN par zéro et mets les notes sur 20.
Résultat: 2d array of floats, shape nb_etuds x nb_evaluations
"""
return np.where(
@ -368,7 +376,7 @@ class ModuleImplResultsAPC(ModuleImplResults):
etuds_moy_module = np.where(
etuds_use_rattrapage, notes_rat_ues, etuds_moy_module
)
# Serie indiquant que l'étudiant utilise une note de rattarage sur l'une des UE:
# Serie indiquant que l'étudiant utilise une note de rattrapage sur l'une des UE:
self.etuds_use_rattrapage = pd.Series(
etuds_use_rattrapage.any(axis=1), index=self.evals_notes.index
)

View File

@ -1,15 +1,22 @@
"""Test calculs rattrapages
"""
from config import TestConfig
from tests.unit import sco_fake_gen
from flask import g
import app
from app.scodoc import sco_bulletins
from app.scodoc import sco_formsemestre
from app.but.bulletin_but import *
from app.comp import res_sem
from app.comp.res_but import ResultatsSemestreBUT
from app.models import ModuleImpl
from app.scodoc import (
sco_bulletins,
sco_evaluation_db,
sco_formsemestre,
sco_saisie_notes,
)
from app.scodoc import sco_utils as scu
from config import TestConfig
from tests.unit import sco_fake_gen
DEPT = TestConfig.DEPT_TEST
@ -70,6 +77,19 @@ def test_notes_rattrapage(test_client):
etud = etuds[0]
_, _, _ = G.create_note(evaluation=e, etud=etud, note=12.0)
_, _, _ = G.create_note(evaluation=e_rat, etud=etud, note=11.0)
# --- Vérifications internes structures ScoDoc
formsemestre = FormSemestre.query.get(formsemestre_id)
res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre)
mod_res = res.modimpls_results[moduleimpl_id]
moduleimpl = ModuleImpl.query.get(moduleimpl_id)
# retrouve l'éval. de rattrapage:
eval_rat = mod_res.get_evaluation_rattrapage(moduleimpl)
assert eval_rat.id == e_rat["id"]
# Les deux évaluations sont considérées comme complètes:
assert len(mod_res.get_evaluations_completes(moduleimpl)) == 2
# --- Vérification sur bulletin
b = sco_bulletins.formsemestre_bulletinetud_dict(
sem["formsemestre_id"], etud["etudid"]
)
@ -99,3 +119,60 @@ def test_notes_rattrapage(test_client):
sem["formsemestre_id"], etud["etudid"]
)
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(10.0)
# Supprime toutes les notes de l'évaluation de rattrapage:
sco_saisie_notes.evaluation_suppress_alln(e_rat["id"], dialog_confirmed=True)
b = sco_bulletins.formsemestre_bulletinetud_dict(
sem["formsemestre_id"], etud["etudid"]
)
# Vérifie structure du bulletin:
assert b["etudid"] == etud["etudid"]
assert len(b["ues"][0]["modules"][0]["evaluations"]) == 1 # reste une eval normale
assert len(b["ues"][0]["modules"]) == 1
# Note moyenne: reviens à 10/20
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(10.0)
# Supprime l'évaluation de rattrapage:
sco_evaluation_db.do_evaluation_delete(e_rat["id"])
b = sco_bulletins.formsemestre_bulletinetud_dict(
sem["formsemestre_id"], etud["etudid"]
)
assert len(b["ues"][0]["modules"][0]["evaluations"]) == 1 # reste une eval normale
# Création évaluation session 2:
e_session2 = G.create_evaluation(
moduleimpl_id=moduleimpl_id,
jour="02/01/2020",
description="evaluation session 2",
coefficient=1.0,
evaluation_type=scu.EVALUATION_SESSION2,
)
res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre)
mod_res = res.modimpls_results[moduleimpl_id]
# retrouve l'éval. de session 2:
eval_session2 = mod_res.get_evaluation_session2(moduleimpl)
assert eval_session2.id == e_session2["id"]
# Les deux évaluations sont considérées comme complètes:
assert len(mod_res.get_evaluations_completes(moduleimpl)) == 2
# Saisie note session 2:
_, _, _ = G.create_note(evaluation=e_session2, etud=etud, note=5.0)
b = sco_bulletins.formsemestre_bulletinetud_dict(
sem["formsemestre_id"], etud["etudid"]
)
# Note moyenne: utilise session 2 même si inférieure
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(5.0)
_, _, _ = G.create_note(evaluation=e_session2, etud=etud, note=20.0)
b = sco_bulletins.formsemestre_bulletinetud_dict(
sem["formsemestre_id"], etud["etudid"]
)
# Note moyenne: utilise session 2 même si inférieure
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(20.0)
_, _, _ = G.create_note(evaluation=e_session2, etud=etud, note=None)
b = sco_bulletins.formsemestre_bulletinetud_dict(
sem["formsemestre_id"], etud["etudid"]
)
# Note moyenne: revient à note normale
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(10.0)