WIP: reorganisation des calculs

This commit is contained in:
Emmanuel Viennet 2022-01-16 23:47:52 +01:00
parent a7324ac634
commit 02989e6c88
18 changed files with 169 additions and 87 deletions

View File

@ -147,6 +147,7 @@ class BulletinBUT(ResultatsSemestreBUT):
def bulletin_etud(self, etud, formsemestre) -> dict:
"""Le bulletin de l'étudiant dans ce semestre"""
etat_inscription = etud.etat_inscription(formsemestre.id)
nb_inscrits = self.get_inscriptions_counts()[scu.INSCRIT]
d = {
"version": "0",
"type": "BUT",
@ -189,7 +190,7 @@ class BulletinBUT(ResultatsSemestreBUT):
},
"rang": { # classement wrt moyenne général, indicatif
"value": self.etud_moy_gen_ranks[etud.id],
"total": len(self.etuds),
"total": nb_inscrits,
},
},
)
@ -212,7 +213,7 @@ class BulletinBUT(ResultatsSemestreBUT):
"moy": "",
"max": "",
},
"rang": {"value": "DEM", "total": len(self.etuds)},
"rang": {"value": "DEM", "total": nb_inscrits},
}
)
d.update(

View File

@ -69,10 +69,11 @@ def bulletin_but_xml_compat(
% (formsemestre_id, etudid)
)
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
etud = Identite.query.get_or_404(etudid)
etud: Identite = Identite.query.get_or_404(etudid)
results = bulletin_but.ResultatsSemestreBUT(formsemestre)
nb_inscrits = len(results.etuds)
etat_inscription = etud.etat_inscription(formsemestre.id)
nb_inscrits = results.get_inscriptions_counts()[scu.INSCRIT]
# etat_inscription = etud.etat_inscription(formsemestre.id)
etat_inscription = results.formsemestre.etuds_inscriptions[etudid].etat
if (not formsemestre.bul_hide_xml) or force_publishing:
published = 1
else:

View File

@ -16,13 +16,13 @@ from app import models
#
def df_load_modimpl_inscr(formsemestre) -> pd.DataFrame:
"""Charge la matrice des inscriptions aux modules du semestre
rows: etudid
rows: etudid (inscrits au semestre, avec DEM et DEF)
columns: moduleimpl_id (en chaîne)
value: bool (0/1 inscrit ou pas)
"""
# méthode la moins lente: une requete par module, merge les dataframes
moduleimpl_ids = [m.id for m in formsemestre.modimpls]
etudids = [i.etudid for i in formsemestre.get_inscrits(include_dem=False)]
etudids = [inscr.etudid for inscr in formsemestre.inscriptions]
df = pd.DataFrame(index=etudids, dtype=int)
for moduleimpl_id in moduleimpl_ids:
ins_df = pd.read_sql_query(

View File

@ -75,7 +75,7 @@ class ModuleImplResults:
"{ evaluation_id: EvaluationEtat }"
#
self.evals_notes = None
"""DataFrame, colonnes: EVALS, Lignes: etudid
"""DataFrame, colonnes: EVALS, Lignes: etudid (inscrits au SEMESTRE)
valeur: notes brutes, float ou NOTES_ATTENTE, NOTES_NEUTRALISE,
NOTES_ABSENCE.
Les NaN désignent les notes manquantes (non saisies).
@ -105,7 +105,7 @@ class ModuleImplResults:
Évaluation "complete" (prise en compte dans les calculs) si:
- soit tous les étudiants inscrits au module ont des notes
- soit elle a été déclarée "à prise ne compte immédiate" (publish_incomplete)
- soit elle a été déclarée "à prise en compte immédiate" (publish_incomplete)
Évaluation "attente" (prise en compte dans les calculs, mais il y
manque des notes) ssi il y a des étudiants inscrits au semestre et au module
@ -178,14 +178,12 @@ class ModuleImplResults:
return eval_df
def _etudids(self):
"""L'index du dataframe est la liste des étudiants inscrits au semestre,
sans les démissionnaires.
"""
"""L'index du dataframe est la liste de tous les étudiants inscrits au semestre"""
return [
e.etudid
for e in ModuleImpl.query.get(self.moduleimpl_id).formsemestre.get_inscrits(
include_dem=False
)
inscr.etudid
for inscr in ModuleImpl.query.get(
self.moduleimpl_id
).formsemestre.inscriptions
]
def get_evaluations_coefs(self, moduleimpl: ModuleImpl) -> np.array:

View File

@ -31,8 +31,10 @@ import numpy as np
import pandas as pd
def compute_sem_moys_apc(etud_moy_ue_df, modimpl_coefs_df):
"""Calcule la moyenne générale indicative
def compute_sem_moys_apc(
etud_moy_ue_df: pd.DataFrame, modimpl_coefs_df: pd.DataFrame
) -> pd.Series:
"""Calcule les moyennes générales indicatives de tous les étudiants
= moyenne des moyennes d'UE, pondérée par la somme de leurs coefs
etud_moy_ue_df: DataFrame, colonnes ue_id, lignes etudid
@ -46,10 +48,11 @@ def compute_sem_moys_apc(etud_moy_ue_df, modimpl_coefs_df):
return moy_gen
def comp_ranks_series(notes: pd.Series):
"""Calcul rangs à partir d'une séries ("vecteur") de notes (index etudid, valeur numérique)
en tenant compte des ex-aequos
Le resultat est: { etudid : rang } rang est une chaine decrivant le rang
def comp_ranks_series(notes: pd.Series) -> dict[int, str]:
"""Calcul rangs à partir d'une séries ("vecteur") de notes (index etudid, valeur
numérique) en tenant compte des ex-aequos.
Result: { etudid : rang:str } rang est une chaine decrivant le rang.
"""
notes = notes.sort_values(ascending=False) # Serie, tri par ordre décroissant
rangs = pd.Series(index=notes.index, dtype=str) # le rang est une chaîne

View File

@ -140,9 +140,14 @@ def notes_sem_assemble_cube(modimpls_notes: list[pd.DataFrame]) -> np.ndarray:
def notes_sem_load_cube(formsemestre: FormSemestre) -> tuple:
"""Calcule le cube des notes du semestre
(charge toutes les notes, calcule les moyenne des modules
et assemble le cube)
"""Construit le "cube" (tenseur) des notes du semestre.
Charge toutes les notes (sql), calcule les moyennes des modules
et assemble le cube.
etuds: tous les inscrits au semestre (avec dem. et def.)
modimpls: _tous_ les modimpls de ce semestre
UEs: X?X voir quelles sont les UE considérées ici
Resultat:
sem_cube : ndarray (etuds x modimpls x UEs)
modimpls_evals_poids dict { modimpl.id : evals_poids }
@ -181,7 +186,7 @@ def compute_ue_moys_apc(
sem_cube: notes moyennes aux modules
ndarray (etuds x modimpls x UEs)
(floats avec des NaN)
etuds : listes des étudiants (dim. 0 du cube)
etuds : liste des étudiants (dim. 0 du cube)
modimpls : liste des modules à considérer (dim. 1 du cube)
ues : liste des UE (dim. 2 du cube)
modimpl_inscr_df: matrice d'inscription du semestre (etud x modimpl)
@ -235,7 +240,7 @@ def compute_ue_moys_classic(
ues: list,
modimpl_inscr_df: pd.DataFrame,
modimpl_coefs: np.array,
) -> tuple:
) -> tuple[pd.Series, pd.DataFrame, pd.DataFrame]:
"""Calcul de la moyenne d'UE en mode classique.
La moyenne d'UE est un nombre (note/20), ou NI ou NA ou ERR
NI non inscrit à (au moins un) module de cette UE
@ -253,6 +258,9 @@ def compute_ue_moys_classic(
Résultat:
- moyennes générales: pd.Series, index etudid
- moyennes d'UE: DataFrame columns UE, rows etudid
- coefficients d'UE: DataFrame, columns UE, rows etudid
les coefficients effectifs de chaque UE pour chaque étudiant
(sommes de coefs de modules pris en compte)
"""
nb_etuds, nb_modules = sem_matrix.shape
assert len(modimpl_coefs) == nb_modules
@ -293,4 +301,9 @@ def compute_ue_moys_classic(
etud_moy_ue_df = pd.DataFrame(
etud_moy_ue, index=modimpl_inscr_df.index, columns=[ue.id for ue in ues]
)
return etud_moy_gen_s, etud_moy_ue_df
etud_coef_ue_df = pd.DataFrame(
coefs.sum(axis=2).T,
index=modimpl_inscr_df.index, # etudids
columns=[ue.id for ue in ues],
)
return etud_moy_gen_s, etud_moy_ue_df, etud_coef_ue_df

View File

@ -6,6 +6,7 @@
"""Résultats semestres BUT
"""
import pandas as pd
from app.comp import moy_ue, moy_sem, inscr_mod
from app.comp.res_common import NotesTableCompat
@ -49,6 +50,10 @@ class ResultatsSemestreBUT(NotesTableCompat):
self.modimpl_inscr_df,
self.modimpl_coefs_df,
)
# Les coefficients d'UE ne sont pas utilisés en APC
self.etud_coef_ue_df = pd.DataFrame(
1.0, index=self.etud_moy_ue.index, columns=self.etud_moy_ue.columns
)
self.etud_moy_gen = moy_sem.compute_sem_moys_apc(
self.etud_moy_ue, self.modimpl_coefs_df
)

View File

@ -8,6 +8,7 @@
"""
import numpy as np
import pandas as pd
from app.comp import moy_mod, moy_ue, moy_sem, inscr_mod
from app.comp.res_common import NotesTableCompat
from app.models.formsemestre import FormSemestre
@ -45,7 +46,11 @@ class ResultatsSemestreClassic(NotesTableCompat):
self.modimpl_idx = {m.id: i for i, m in enumerate(self.formsemestre.modimpls)}
"l'idx de la colonne du mod modimpl.id est modimpl_idx[modimpl.id]"
self.etud_moy_gen, self.etud_moy_ue = moy_ue.compute_ue_moys_classic(
(
self.etud_moy_gen,
self.etud_moy_ue,
self.etud_coef_ue_df,
) = moy_ue.compute_ue_moys_classic(
self.formsemestre,
self.sem_matrix,
self.ues,

View File

@ -4,13 +4,13 @@
# See LICENSE
##############################################################################
from collections import defaultdict
from collections import defaultdict, Counter
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.models import FormSemestre, Identite, ModuleImpl
from app.models.ues import UniteEns
from app.scodoc import sco_utils as scu
from app.scodoc.sco_cache import ResultatsSemestreCache
@ -32,6 +32,7 @@ class ResultatsSemestre:
"etud_moy_ue",
"modimpl_inscr_df",
"modimpls_results",
"etud_coef_ue_df",
)
def __init__(self, formsemestre: FormSemestre):
@ -45,7 +46,10 @@ class ResultatsSemestre:
self.etud_moy_gen = {}
self.etud_moy_gen_ranks = {}
self.modimpls_results: ModuleImplResults = None
# TODO
self.etud_coef_ue_df = None
"""coefs d'UE effectifs pour chaque etudiant (pour form. classiques)"""
# TODO ?
def load_cached(self) -> bool:
"Load cached dataframes, returns False si pas en cache"
@ -68,24 +72,34 @@ class ResultatsSemestre:
# voir ce qui est chargé / calculé ici et dans les sous-classes
raise NotImplementedError()
@cached_property
def etuds(self):
"Liste des inscrits au semestre, sans les démissionnaires"
# nb: si la liste des inscrits change, ResultatsSemestre devient invalide
return self.formsemestre.get_inscrits(include_dem=False)
def get_inscriptions_counts(self) -> Counter:
"""Nombre d'inscrits, défaillants, démissionnaires.
Exemple: res.get_inscriptions_counts()[scu.INSCRIT]
Result: a collections.Counter instance
"""
return Counter(ins.etat for ins in self.formsemestre.inscriptions)
@cached_property
def etud_index(self):
def etuds(self) -> list[Identite]:
"Liste des inscrits au semestre, avec les démissionnaires et les défaillants"
# nb: si la liste des inscrits change, ResultatsSemestre devient invalide
return self.formsemestre.get_inscrits(include_demdef=True)
@cached_property
def etud_index(self) -> dict[int, int]:
"dict { etudid : indice dans les inscrits }"
return {e.id: idx for idx, e in enumerate(self.etuds)}
@cached_property
def etuds_dict(self):
"dict { etudid : Identite } inscrits au semestre, sans les démissionnaires"
def etuds_dict(self) -> dict[int, Identite]:
"""dict { etudid : Identite } inscrits au semestre,
avec les démissionnaires et defs."""
return {etud.id: etud for etud in self.etuds}
@cached_property
def ues(self) -> list:
def ues(self) -> list[UniteEns]:
"""Liste des UEs du semestre
(indices des DataFrames)
"""
@ -153,6 +167,7 @@ class NotesTableCompat(ResultatsSemestre):
def __init__(self, formsemestre: FormSemestre):
super().__init__(formsemestre)
nb_etuds = len(self.etuds)
self.bonus = defaultdict(lambda: 0.0) # XXX TODO
self.ue_rangs = {u.id: (defaultdict(lambda: 0.0), nb_etuds) for u in self.ues}
@ -178,12 +193,18 @@ class NotesTableCompat(ResultatsSemestre):
return [x["etudid"] for x in self.inscrlist]
@cached_property
def sem(self) -> dict:
"""le formsemestre, comme un dict (nt.sem)"""
return self.formsemestre.to_dict()
@cached_property
def inscrlist(self) -> list[dict]: # utilisé par PE seulement
"""Liste de dict etud, avec démissionnaires
"""Liste des inscrits au semestre (avec DEM et DEF),
sous forme de dict etud,
classée dans l'ordre alphabétique de noms.
"""
etuds = self.formsemestre.get_inscrits(include_dem=True)
etuds = self.formsemestre.get_inscrits(include_demdef=True)
etuds.sort(key=lambda e: e.sort_key)
return [e.to_dict_scodoc7() for e in etuds]
@ -256,9 +277,12 @@ class NotesTableCompat(ResultatsSemestre):
raise NotImplementedError() # virtual method
def get_etud_ue_status(self, etudid: int, ue_id: int):
coef_ue = self.etud_coef_ue_df[ue_id][etudid]
return {
"cur_moy_ue": self.etud_moy_ue[ue_id][etudid],
"moy": self.etud_moy_ue[ue_id][etudid],
"is_capitalized": False, # XXX TODO
"coef_ue": coef_ue, # XXX TODO
}
def get_etud_rang(self, etudid: int):
@ -277,18 +301,20 @@ class NotesTableCompat(ResultatsSemestre):
for e in modimpl.evaluations:
if self.modimpls_results[moduleimpl_id].evaluations_completes_dict[e.id]:
d = e.to_dict()
moduleimpl_results = self.modimpls_results[e.moduleimpl_id]
d["heure_debut"] = e.heure_debut # datetime.time
d["heure_fin"] = e.heure_fin
d["jour"] = e.jour # datetime
d["notes"] = {
etud.id: {
"etudid": etud.id,
"value": self.modimpls_evals_notes[e.moduleimpl_id][e.id][
etud.id
],
"value": moduleimpl_results.evals_notes[e.id][etud.id],
}
for etud in self.etuds
}
d["etat"] = {
"evalattente": moduleimpl_results.evaluations_etat[e.id].nb_attente,
}
evals_results.append(d)
return evals_results

View File

@ -117,11 +117,18 @@ class FormSemestre(db.Model):
d.pop("_sa_instance_state", None)
# ScoDoc7 output_formators: (backward compat)
d["formsemestre_id"] = self.id
d["date_debut"] = (
self.date_debut.strftime("%d/%m/%Y") if self.date_debut else ""
)
d["date_fin"] = self.date_fin.strftime("%d/%m/%Y") if self.date_fin else ""
if self.date_debut:
d["date_debut"] = self.date_debut.strftime("%d/%m/%Y")
d["date_debut_iso"] = self.date_debut.isoformat()
else:
d["date_debut"] = d["date_debut_iso"] = ""
if self.date_fin:
d["date_fin"] = self.date_fin.strftime("%d/%m/%Y")
d["date_fin_iso"] = self.date_fin.isoformat()
else:
d["date_fin"] = d["date_fin_iso"] = ""
d["responsables"] = [u.id for u in self.responsables]
return d
def query_ues(self, with_sport=False) -> flask_sqlalchemy.BaseQuery:
@ -271,18 +278,19 @@ class FormSemestre(db.Model):
etudid, self.date_debut.isoformat(), self.date_fin.isoformat()
)
def get_inscrits(self, include_dem=False) -> list[Identite]:
def get_inscrits(self, include_demdef=False) -> list[Identite]:
"""Liste des étudiants inscrits à ce semestre
Si all, tous les étudiants, avec les démissionnaires.
Si include_demdef, tous les étudiants, avec les démissionnaires
et défaillants.
"""
if include_dem:
if include_demdef:
return [ins.etud for ins in self.inscriptions]
else:
return [ins.etud for ins in self.inscriptions if ins.etat == scu.INSCRIT]
@cached_property
def etuds_inscriptions(self) -> dict:
"""Map { etudid : inscription }"""
"""Map { etudid : inscription } (incluant DEM et DEF)"""
return {ins.etud.id: ins for ins in self.inscriptions}

View File

@ -62,7 +62,7 @@ Pour modifier les moyennes d'UE:
La valeur retournée est:
- formations classiques: ajoutée à la moyenne générale
- BUT: ajoutée à chaque UE si le coef XXX
- BUT: valeur multipliée par la somme des coefs modules sport ajoutée à chaque UE.
"""

View File

@ -171,6 +171,7 @@ class NotesTable:
def __init__(self, formsemestre_id):
log(f"NotesTable( formsemestre_id={formsemestre_id} )")
# raise NotImplementedError() # XXX
if not formsemestre_id:
raise ValueError("invalid formsemestre_id (%s)" % formsemestre_id)
self.formsemestre_id = formsemestre_id
@ -409,7 +410,7 @@ class NotesTable:
return ""
def get_etud_etat_html(self, etudid):
etat = self.inscrdict[etudid]["etat"]
if etat == "I":
return ""
elif etat == "D":

View File

@ -48,6 +48,9 @@ import app.scodoc.sco_utils as scu
from app.scodoc.sco_utils import ModuleType
import app.scodoc.notesdb as ndb
from app import log
from app.comp import res_sem
from app.comp.res_common import NotesTableCompat
from app.models import FormSemestre
from app.scodoc.sco_permissions import Permission
from app.scodoc.sco_exceptions import AccessDenied, ScoValueError
from app.scodoc import html_sco_header
@ -136,7 +139,9 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"):
raise ValueError("invalid version code !")
prefs = sco_preferences.SemPreferences(formsemestre_id)
nt = sco_cache.NotesTableCache.get(formsemestre_id) # > toutes notes
# nt = sco_cache.NotesTableCache.get(formsemestre_id) # > toutes notes
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
nt: NotesTableCompat = res_sem.load_formsemestre_result(formsemestre)
if not nt.get_etud_etat(etudid):
raise ScoValueError("Etudiant non inscrit à ce semestre")
I = scu.DictDefault(defaultvalue="")
@ -191,7 +196,9 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"):
I["decision_sem"] = ""
I.update(infos)
I["etud_etat_html"] = nt.get_etud_etat_html(etudid)
I["etud_etat_html"] = _get_etud_etat_html(
formsemestre.etuds_inscriptions[etudid].etat
)
I["etud_etat"] = nt.get_etud_etat(etudid)
I["filigranne"] = ""
I["demission"] = ""
@ -261,17 +268,18 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"):
# notes en attente dans ce semestre
rang = scu.RANG_ATTENTE_STR
rang_gr = scu.DictDefault(defaultvalue=scu.RANG_ATTENTE_STR)
inscriptions_counts = nt.get_inscriptions_counts()
I["rang"] = rang
I["rang_gr"] = rang_gr
I["gr_name"] = gr_name
I["ninscrits_gr"] = ninscrits_gr
I["nbetuds"] = len(nt.etud_moy_gen_ranks)
I["nb_demissions"] = nt.nb_demissions
I["nb_defaillants"] = nt.nb_defaillants
I["nb_demissions"] = inscriptions_counts[scu.DEMISSION]
I["nb_defaillants"] = inscriptions_counts[scu.DEF]
if prefs["bul_show_rangs"]:
I["rang_nt"] = "%s / %d" % (
rang,
I["nbetuds"] - nt.nb_demissions - nt.nb_defaillants,
inscriptions_counts[scu.INSCRIT],
)
I["rang_txt"] = "Rang " + I["rang_nt"]
else:
@ -379,7 +387,8 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"):
I["ues"].append(u) # ne montre pas les UE si non inscrit
# Accès par matieres
I["matieres_modules"].update(_sort_mod_by_matiere(modules, nt, etudid))
# voir si on supporte encore cela en #sco92 XXX
# I["matieres_modules"].update(_sort_mod_by_matiere(modules, nt, etudid))
#
C = make_context_dict(I["sem"], I["etud"])
@ -389,6 +398,18 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"):
return C
def _get_etud_etat_html(etat: str) -> str:
"""chaine html représentant l'état (backward compat sco7)"""
if etat == scu.INSCRIT: # "I"
return ""
elif etat == scu.DEMISSION: # "D"
return ' <font color="red">(DEMISSIONNAIRE)</font> '
elif etat == scu.DEF: # "DEF"
return ' <font color="red">(DEFAILLANT)</font> '
else:
return ' <font color="red">(%s)</font> ' % etat
def _sort_mod_by_matiere(modlist, nt, etudid):
matmod = {} # { matiere_id : [] }
for mod in modlist:

View File

@ -1433,18 +1433,19 @@ def create_etapes_partition(formsemestre_id, partition_name="apo_etapes"):
def do_evaluation_listeetuds_groups(
evaluation_id, groups=None, getallstudents=False, include_dems=False
evaluation_id, groups=None, getallstudents=False, include_demdef=False
):
"""Donne la liste des etudids inscrits a cette evaluation dans les
groupes indiqués.
Si getallstudents==True, donne tous les etudiants inscrits a cette
evaluation.
Si include_dems, compte aussi les etudiants démissionnaires
Si include_demdef, compte aussi les etudiants démissionnaires et défaillants
(sinon, par défaut, seulement les 'I')
Résultat: [ (etudid, etat) ], etat='I', 'D', 'DEF'
"""
# nb: pour notes_table / do_evaluation_etat, getallstudents est vrai et include_dems faux
# nb: pour notes_table / do_evaluation_etat, getallstudents est vrai et
# include_demdef faux
fromtables = [
"notes_moduleimpl_inscription Im",
"notes_formsemestre_inscription Isem",
@ -1476,7 +1477,7 @@ def do_evaluation_listeetuds_groups(
and E.id = %(evaluation_id)s
"""
)
if not include_dems:
if not include_demdef:
req += " and Isem.etat='I'"
req += r
cnx = ndb.GetDBConnexion()

View File

@ -309,7 +309,7 @@ def _make_table_notes(
anonymous_lst_key = "etudid"
etudid_etats = sco_groups.do_evaluation_listeetuds_groups(
E["evaluation_id"], groups, include_dems=True
E["evaluation_id"], groups, include_demdef=True
)
for etudid, etat in etudid_etats:
css_row_class = None

View File

@ -307,7 +307,7 @@ class PlacementRunner:
self.evaluation_id,
self.groups,
getallstudents=get_all_students,
include_dems=True,
include_demdef=True,
)
listetud = [] # liste de couples (nom,prenom)
for etudid, etat in etudid_etats:

View File

@ -306,8 +306,8 @@ def make_formsemestre_recapcomplet(
)[0]
parcours = formsemestre.formation.get_parcours()
# nt = sco_cache.NotesTableCache.get(formsemestre_id)
# XXX EXPERIMENTAL
# nt = sco_cache.NotesTableCache.get(formsemestre_id) # sco91
# sco92 :
nt: NotesTableCompat = res_sem.load_formsemestre_result(formsemestre)
modimpls = nt.get_modimpls_dict()
ues = nt.get_ues_stat_dict() # incluant le(s) UE de sport
@ -434,7 +434,6 @@ def make_formsemestre_recapcomplet(
e["admission"] = {}
if not hidebac:
if etud_etat == scu.INSCRIT:
e["admission"] = nt.etuds_dict[etudid].admission.first()
if e["admission"]:
bac = nt.etuds_dict[etudid].admission[0].get_bac()

View File

@ -310,7 +310,7 @@ def do_evaluation_set_missing(evaluation_id, value, dialog_confirmed=False):
#
NotesDB = sco_evaluation_db.do_evaluation_get_all_notes(evaluation_id)
etudid_etats = sco_groups.do_evaluation_listeetuds_groups(
evaluation_id, getallstudents=True, include_dems=False
evaluation_id, getallstudents=True, include_demdef=False
)
notes = []
for etudid, _ in etudid_etats: # pour tous les inscrits
@ -482,7 +482,7 @@ def notes_add(
inscrits = {
x[0]
for x in sco_groups.do_evaluation_listeetuds_groups(
evaluation_id, getallstudents=True, include_dems=True
evaluation_id, getallstudents=True, include_demdef=True
)
}
for (etudid, value) in notes:
@ -833,7 +833,7 @@ def feuille_saisie_notes(evaluation_id, group_ids=[]):
etudids = [
x[0]
for x in sco_groups.do_evaluation_listeetuds_groups(
evaluation_id, groups, getallstudents=getallstudents, include_dems=True
evaluation_id, groups, getallstudents=getallstudents, include_demdef=True
)
]
@ -1079,7 +1079,7 @@ def _form_saisie_notes(E, M, group_ids, destination=""):
etudids = [
x[0]
for x in sco_groups.do_evaluation_listeetuds_groups(
evaluation_id, getallstudents=True, include_dems=True
evaluation_id, getallstudents=True, include_demdef=True
)
]
if not etudids: