forked from ScoDoc/ScoDoc
Calcul moyennes BUT: prise en compte des inscriptions aux modules optionnels.
This commit is contained in:
parent
fa896b77ab
commit
8647203f43
@ -136,8 +136,8 @@ def compute_ue_moys(
|
||||
etuds: list,
|
||||
modimpls: list,
|
||||
ues: list,
|
||||
module_inscr_df: pd.DataFrame,
|
||||
module_coefs_df: pd.DataFrame,
|
||||
modimpl_inscr_df: pd.DataFrame,
|
||||
modimpl_coefs_df: pd.DataFrame,
|
||||
) -> pd.DataFrame:
|
||||
"""Calcul de la moyenne d'UE
|
||||
La moyenne d'UE est un nombre (note/20), ou NI ou NA ou ERR
|
||||
@ -160,20 +160,33 @@ def compute_ue_moys(
|
||||
assert len(etuds) == nb_etuds
|
||||
assert len(modimpls) == nb_modules
|
||||
assert len(ues) == nb_ues
|
||||
assert module_inscr_df.shape[0] == nb_etuds
|
||||
assert module_inscr_df.shape[1] == nb_modules
|
||||
assert module_coefs_df.shape[0] == nb_ues
|
||||
assert module_coefs_df.shape[1] == nb_modules
|
||||
module_inscr = module_inscr_df.values
|
||||
modules_coefs = module_coefs_df.values
|
||||
#
|
||||
# version non vectorisée sur les etuds:
|
||||
etud_moy_ue = np.zeros((nb_etuds, nb_ues))
|
||||
for i in range(nb_etuds):
|
||||
coefs = module_inscr[i] * modules_coefs
|
||||
etud_moy_ue[i] = (sem_cube[i].transpose() * coefs).sum(axis=1) / coefs.sum(
|
||||
axis=1
|
||||
)
|
||||
return pd.DataFrame(
|
||||
etud_moy_ue, index=module_inscr_df.index, columns=module_coefs_df.index
|
||||
assert modimpl_inscr_df.shape[0] == nb_etuds
|
||||
assert modimpl_inscr_df.shape[1] == nb_modules
|
||||
assert modimpl_coefs_df.shape[0] == nb_ues
|
||||
assert modimpl_coefs_df.shape[1] == nb_modules
|
||||
modimpl_inscr = modimpl_inscr_df.values
|
||||
modimpl_coefs = modimpl_coefs_df.values
|
||||
# Duplique les inscriptions sur les UEs:
|
||||
modimpl_inscr_stacked = np.stack([modimpl_inscr] * nb_ues, axis=2)
|
||||
|
||||
# Enlève les NaN du numérateur:
|
||||
# si on veut prendre en compte les module avec notes neutralisées ?
|
||||
# sem_cube_no_nan = np.nan_to_num(sem_cube, nan=0.0)
|
||||
|
||||
# Ne prend pas en compte les notes des étudiants non inscrits au module:
|
||||
# Annule les notes:
|
||||
sem_cube_inscrits = np.where(modimpl_inscr_stacked, sem_cube, 0.0)
|
||||
# Annule les coefs des modules où l'étudiant n'est pas inscrit:
|
||||
modimpl_coefs_etuds = np.where(
|
||||
modimpl_inscr_stacked, np.stack([modimpl_coefs.T] * nb_etuds), 0.0
|
||||
)
|
||||
|
||||
#
|
||||
# Version vectorisée
|
||||
#
|
||||
etud_moy_ue = np.sum(modimpl_coefs_etuds * sem_cube_inscrits, axis=1) / np.sum(
|
||||
modimpl_coefs_etuds, axis=1
|
||||
)
|
||||
return pd.DataFrame(
|
||||
etud_moy_ue, index=modimpl_inscr_df.index, columns=modimpl_coefs_df.index
|
||||
)
|
||||
|
@ -2,20 +2,21 @@
|
||||
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 app.models.etudiants import Identite
|
||||
|
||||
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 Evaluation, formsemestre
|
||||
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_exceptions
|
||||
|
||||
|
||||
def test_ue_moy(test_client):
|
||||
@ -34,9 +35,9 @@ def test_ue_moy(test_client):
|
||||
) = setup.build_modules_with_evaluations(ue_coefs=ue_coefs, nb_mods=nb_mods)
|
||||
assert len(evaluation_ids) == nb_mods
|
||||
formsemestre_id = sem["formsemestre_id"]
|
||||
formsemestre = models.FormSemestre.query.get(formsemestre_id)
|
||||
evaluation1 = models.Evaluation.query.get(evaluation_ids[0])
|
||||
evaluation2 = models.Evaluation.query.get(evaluation_ids[1])
|
||||
formsemestre = FormSemestre.query.get(formsemestre_id)
|
||||
evaluation1 = Evaluation.query.get(evaluation_ids[0])
|
||||
evaluation2 = Evaluation.query.get(evaluation_ids[1])
|
||||
etud = G.create_etud(nom="test")
|
||||
G.inscrit_etudiant(sem, etud)
|
||||
etudid = etud["etudid"]
|
||||
@ -78,9 +79,46 @@ def test_ue_moy(test_client):
|
||||
# Cas simple: 1 eval / module, notes normales,
|
||||
# coefs non nuls.
|
||||
n1, n2 = 5.0, 13.0 # notes aux 2 evals (1 dans chaque module)
|
||||
etud_moy_ue = change_notes(5.0, 13.0)
|
||||
etud_moy_ue = change_notes(n1, n2)
|
||||
assert etud_moy_ue.shape == (1, nb_ues) # 1 étudiant
|
||||
assert etud_moy_ue[ue1.id][etudid] == (n1 + n2) / 2
|
||||
assert etud_moy_ue[ue2.id][etudid] == (n1 + n2) / 2
|
||||
assert etud_moy_ue[ue3.id][etudid] == (n1 + n2) / 2
|
||||
#
|
||||
# ABS à un module (note comptée comme 0)
|
||||
n1, n2 = None, 13.0 # notes aux 2 evals (1 dans chaque module)
|
||||
etud_moy_ue = change_notes(n1, n2)
|
||||
assert etud_moy_ue[ue1.id][etudid] == n2 / 2 # car n1 est zéro
|
||||
assert etud_moy_ue[ue2.id][etudid] == n2 / 2
|
||||
assert etud_moy_ue[ue3.id][etudid] == n2 / 2
|
||||
# EXC à un module
|
||||
n1, n2 = 5.0, NOTES_NEUTRALISE
|
||||
etud_moy_ue = change_notes(n1, n2)
|
||||
# Pour le moment, une note NEUTRALISE var entrainer le non calcul
|
||||
# des moyennes.
|
||||
assert np.isnan(etud_moy_ue.values).all()
|
||||
# Désinscrit l'étudiant du module 2:
|
||||
inscr = ModuleImplInscription.query.filter_by(
|
||||
moduleimpl_id=evaluation2.moduleimpl.id, etudid=etudid
|
||||
).first()
|
||||
db.session.delete(inscr)
|
||||
db.session.commit()
|
||||
modimpl_inscr_df = inscr_mod.df_load_modimpl_inscr(formsemestre_id)
|
||||
assert (modimpl_inscr_df.values == np.array([[1, 0]])).all()
|
||||
n1, n2 = 5.0, NOTES_NEUTRALISE
|
||||
# On ne doit pas pouvoir saisir de note sans être inscrit:
|
||||
exception_raised = False
|
||||
try:
|
||||
etud_moy_ue = change_notes(n1, n2)
|
||||
except sco_exceptions.NoteProcessError:
|
||||
exception_raised = True
|
||||
assert exception_raised
|
||||
# Recalcule les notes:
|
||||
sem_cube = moy_ue.notes_sem_load_cube(formsemestre_id)
|
||||
etuds = formsemestre.etuds.all()
|
||||
etud_moy_ue = moy_ue.compute_ue_moys(
|
||||
sem_cube, etuds, modimpls, ues, modimpl_inscr_df, modimpl_coefs_df
|
||||
)
|
||||
assert etud_moy_ue[ue1.id][etudid] == n1
|
||||
assert etud_moy_ue[ue2.id][etudid] == n1
|
||||
assert etud_moy_ue[ue3.id][etudid] == n1
|
||||
|
Loading…
Reference in New Issue
Block a user