forked from ScoDoc/DocScoDoc
recapcomplet sans NotesTable
This commit is contained in:
parent
6b1ccfe400
commit
af48eb8fb8
@ -69,6 +69,8 @@ class ModuleImplResults:
|
||||
"nombre d'inscrits (non DEM) au module"
|
||||
self.evaluations_completes = []
|
||||
"séquence de booléens, indiquant les évals à prendre en compte."
|
||||
self.evaluations_completes_dict = {}
|
||||
"{ evaluation.id : bool } indique si à prendre en compte ou non."
|
||||
self.evaluations_etat = {}
|
||||
"{ evaluation_id: EvaluationEtat }"
|
||||
#
|
||||
@ -122,6 +124,7 @@ class ModuleImplResults:
|
||||
# dataFrame vide, index = tous les inscrits au SEMESTRE
|
||||
evals_notes = pd.DataFrame(index=self.etudids, dtype=float)
|
||||
self.evaluations_completes = []
|
||||
self.evaluations_completes_dict = {}
|
||||
for evaluation in moduleimpl.evaluations:
|
||||
eval_df = self._load_evaluation_notes(evaluation)
|
||||
# is_complete ssi tous les inscrits (non dem) au semestre ont une note
|
||||
@ -131,6 +134,7 @@ class ModuleImplResults:
|
||||
== self.nb_inscrits_module
|
||||
) or evaluation.publish_incomplete # immédiate
|
||||
self.evaluations_completes.append(is_complete)
|
||||
self.evaluations_completes_dict[evaluation.id] = is_complete
|
||||
|
||||
# NULL en base => ABS (= -999)
|
||||
eval_df.fillna(scu.NOTES_ABSENCE, inplace=True)
|
||||
|
@ -60,6 +60,25 @@ class ResultatsSemestreClassic(NotesTableCompat):
|
||||
"""
|
||||
return self.modimpls_results[moduleimpl_id].etuds_moy_module.get(etudid, "NI")
|
||||
|
||||
def get_mod_stats(self, moduleimpl_id: int) -> dict:
|
||||
"""Stats sur les notes obtenues dans un modimpl"""
|
||||
notes_series: pd.Series = self.modimpls_results[moduleimpl_id].etuds_moy_module
|
||||
nb_notes = len(notes_series)
|
||||
if not nb_notes:
|
||||
super().get_mod_stats(moduleimpl_id)
|
||||
return {
|
||||
# Series: Statistical methods from ndarray have been overridden to automatically
|
||||
# exclude missing data (currently represented as NaN)
|
||||
"moy": notes_series.mean(), # donc sans prendre en compte les NaN
|
||||
"max": notes_series.max(),
|
||||
"min": notes_series.min(),
|
||||
"nb_notes": nb_notes,
|
||||
"nb_missing": sum(notes_series.isna()),
|
||||
"nb_valid_evals": sum(
|
||||
self.modimpls_results[moduleimpl_id].evaluations_completes
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def notes_sem_load_matrix(formsemestre: FormSemestre) -> tuple:
|
||||
"""Calcule la matrice des notes du semestre
|
||||
|
@ -9,6 +9,7 @@ from functools import cached_property
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from app.comp.aux import StatsMoyenne
|
||||
from app.comp.moy_mod import ModuleImplResults
|
||||
from app.models import FormSemestre, ModuleImpl
|
||||
from app.scodoc import sco_utils as scu
|
||||
from app.scodoc.sco_cache import ResultatsSemestreCache
|
||||
@ -36,11 +37,12 @@ class ResultatsSemestre:
|
||||
self.formsemestre = formsemestre
|
||||
# BUT ou standard ? (apc == "approche par compétences")
|
||||
self.is_apc = formsemestre.formation.is_apc()
|
||||
# Attributs "virtuels", définis pas les sous-classes
|
||||
# Attributs "virtuels", définis dans les sous-classes
|
||||
# ResultatsSemestreBUT ou ResultatsSemestreStd
|
||||
self.etud_moy_ue = {}
|
||||
self.etud_moy_gen = {}
|
||||
self.etud_moy_gen_ranks = {}
|
||||
self.modimpls_results: ModuleImplResults = None
|
||||
# TODO
|
||||
|
||||
def load_cached(self) -> bool:
|
||||
@ -215,7 +217,7 @@ class NotesTableCompat(ResultatsSemestre):
|
||||
|
||||
def get_etud_moy_gen(self, etudid): # -> float | str
|
||||
"""Moyenne générale de cet etudiant dans ce semestre.
|
||||
Prend en compte les UE capitalisées. (TODO)
|
||||
Prend(ra) en compte les UE capitalisées. (TODO) XXX
|
||||
Si apc, moyenne indicative.
|
||||
Si pas de notes: 'NA'
|
||||
"""
|
||||
@ -241,10 +243,14 @@ class NotesTableCompat(ResultatsSemestre):
|
||||
return (None, 0) # XXX unimplemented TODO
|
||||
|
||||
def get_evals_in_mod(self, moduleimpl_id: int) -> list[dict]:
|
||||
"liste des évaluations valides dans un module"
|
||||
"""Liste d'informations (compat NotesTable) sur évaluations completes
|
||||
de ce module.
|
||||
Évaluation "complete" ssi toutes notes saisies ou en attente.
|
||||
"""
|
||||
modimpl = ModuleImpl.query.get(moduleimpl_id)
|
||||
evals_results = []
|
||||
for e in modimpl.evaluations:
|
||||
if self.modimpls_results[moduleimpl_id].evaluations_completes_dict[e.id]:
|
||||
d = e.to_dict()
|
||||
d["heure_debut"] = e.heure_debut # datetime.time
|
||||
d["heure_fin"] = e.heure_fin
|
||||
@ -252,11 +258,11 @@ class NotesTableCompat(ResultatsSemestre):
|
||||
d["notes"] = {
|
||||
etud.id: {
|
||||
"etudid": etud.id,
|
||||
"value": self.results.modimpls_evals_notes[e.moduleimpl_id][e.id][
|
||||
"value": self.modimpls_evals_notes[e.moduleimpl_id][e.id][
|
||||
etud.id
|
||||
],
|
||||
}
|
||||
for etud in self.results.etuds
|
||||
for etud in self.etuds
|
||||
}
|
||||
evals_results.append(d)
|
||||
return evals_results
|
||||
@ -264,7 +270,10 @@ class NotesTableCompat(ResultatsSemestre):
|
||||
def get_moduleimpls_attente(self):
|
||||
return [] # XXX TODO
|
||||
|
||||
def get_mod_stats(self, moduleimpl_id):
|
||||
def get_mod_stats(self, moduleimpl_id: int) -> dict:
|
||||
"""Stats sur les notes obtenues dans un modimpl
|
||||
Vide en APC
|
||||
"""
|
||||
return {
|
||||
"moy": "-",
|
||||
"max": "-",
|
||||
|
@ -170,6 +170,7 @@ class NotesTable:
|
||||
"""
|
||||
|
||||
def __init__(self, formsemestre_id):
|
||||
# XXX breakpoint()
|
||||
log(f"NotesTable( formsemestre_id={formsemestre_id} )")
|
||||
if not formsemestre_id:
|
||||
raise ValueError("invalid formsemestre_id (%s)" % formsemestre_id)
|
||||
|
@ -303,9 +303,11 @@ def make_formsemestre_recapcomplet(
|
||||
sem = sco_formsemestre.do_formsemestre_list(
|
||||
args={"formsemestre_id": formsemestre_id}
|
||||
)[0]
|
||||
nt = sco_cache.NotesTableCache.get(formsemestre_id)
|
||||
parcours = formsemestre.formation.get_parcours()
|
||||
|
||||
# nt = sco_cache.NotesTableCache.get(formsemestre_id)
|
||||
# XXX EXPERIMENTAL
|
||||
# nt = ResultatsSemestreClassic(formsemestre)
|
||||
nt = ResultatsSemestreClassic(formsemestre)
|
||||
modimpls = nt.get_modimpls_dict()
|
||||
ues = nt.get_ues_stat_dict() # incluant le(s) UE de sport
|
||||
#
|
||||
@ -701,9 +703,7 @@ def make_formsemestre_recapcomplet(
|
||||
idx_col_moy = idx_col_gr + 1
|
||||
cssclass = "recap_col_moy"
|
||||
try:
|
||||
if float(nsn[idx_col_moy]) < (
|
||||
nt.parcours.BARRE_MOY - scu.NOTES_TOLERANCE
|
||||
):
|
||||
if float(nsn[idx_col_moy]) < (parcours.BARRE_MOY - scu.NOTES_TOLERANCE):
|
||||
cssclass = "recap_col_moy_inf"
|
||||
except:
|
||||
pass
|
||||
@ -718,11 +718,11 @@ def make_formsemestre_recapcomplet(
|
||||
|
||||
if (ir < (nblines - 4)) or (ir == nblines - 3):
|
||||
try:
|
||||
if float(nsn[i]) < nt.parcours.get_barre_ue(
|
||||
if float(nsn[i]) < parcours.get_barre_ue(
|
||||
ue["type"]
|
||||
): # NOTES_BARRE_UE
|
||||
cssclass = "recap_col_ue_inf"
|
||||
elif float(nsn[i]) >= nt.parcours.NOTES_BARRE_VALID_UE:
|
||||
elif float(nsn[i]) >= parcours.NOTES_BARRE_VALID_UE:
|
||||
cssclass = "recap_col_ue_val"
|
||||
except:
|
||||
pass
|
||||
@ -732,7 +732,7 @@ def make_formsemestre_recapcomplet(
|
||||
ir == nblines - 3
|
||||
): # si moyenne generale module < barre ue, surligne:
|
||||
try:
|
||||
if float(nsn[i]) < nt.parcours.get_barre_ue(ue["type"]):
|
||||
if float(nsn[i]) < parcours.get_barre_ue(ue["type"]):
|
||||
cssclass = "recap_col_moy_inf"
|
||||
except:
|
||||
pass
|
||||
|
Loading…
Reference in New Issue
Block a user