1
0
forked from ScoDoc/ScoDoc

calcul et affiche les rangs / moy gen BUT

This commit is contained in:
Emmanuel Viennet 2021-12-12 10:17:02 +01:00
parent 80b8956af5
commit 711ca9c220
4 changed files with 61 additions and 23 deletions

View File

@ -34,6 +34,7 @@ class ResultatsSemestreBUT:
"modimpls_evals_poids",
"modimpls_evals_notes",
"etud_moy_gen",
"etud_moy_gen_ranks",
)
def __init__(self, formsemestre):
@ -94,6 +95,7 @@ class ResultatsSemestreBUT:
self.etud_moy_gen = moy_sem.compute_sem_moys(
self.etud_moy_ue, self.modimpl_coefs_df
)
self.etud_moy_gen_ranks = moy_sem.comp_ranks_series(self.etud_moy_gen)
def etud_ue_mod_results(self, etud, ue, modimpls) -> dict:
"dict synthèse résultats dans l'UE pour les modules indiqués"
@ -227,8 +229,8 @@ class ResultatsSemestreBUT:
"max": fmt_note(self.etud_moy_gen.max()),
},
"rang": { # classement wrt moyenne général, indicatif
"value": None, # XXX TODO
"total": None,
"value": self.etud_moy_gen_ranks[etud.id],
"total": len(self.etuds),
},
"absences": { # XXX TODO
"injustifie": 1,

View File

@ -44,3 +44,36 @@ def compute_sem_moys(etud_moy_ue_df, modimpl_coefs_df):
axis=1
) / modimpl_coefs_df.values.sum()
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
"""
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
N = len(notes)
nb_ex = 0 # nb d'ex-aequo consécutifs en cours
notes_i = notes.iat
for i, etudid in enumerate(notes.index):
# test ex-aequo
if i < (N - 1):
next = notes_i[i + 1]
else:
next = None
val = notes_i[i]
if nb_ex:
srang = "%d ex" % (i + 1 - nb_ex)
if val == next:
nb_ex += 1
else:
nb_ex = 0
else:
if val == next:
srang = "%d ex" % (i + 1 - nb_ex)
nb_ex = 1
else:
srang = "%d" % (i + 1)
rangs[etudid] = srang
return rangs

View File

@ -200,9 +200,7 @@ class NotesTable(object):
self.inscrlist.sort(key=itemgetter("nomp"))
# { etudid : rang dans l'ordre alphabetique }
rangalpha = {}
for i in range(len(self.inscrlist)):
rangalpha[self.inscrlist[i]["etudid"]] = i
self.rang_alpha = {e["etudid"]: i for i, e in enumerate(self.inscrlist)}
self.bonus = scu.DictDefault(defaultvalue=0)
# Notes dans les modules { moduleimpl_id : { etudid: note_moyenne_dans_ce_module } }
@ -264,7 +262,7 @@ class NotesTable(object):
self._ues.sort(key=lambda u: u["numero"])
T = []
# XXX self.comp_ue_coefs(cnx)
self.moy_gen = {} # etudid : moy gen (avec UE capitalisées)
self.moy_ue = {} # ue_id : { etudid : moy ue } (valeur numerique)
self.etud_moy_infos = {} # etudid : resultats de comp_etud_moy_gen()
@ -305,21 +303,11 @@ class NotesTable(object):
#
t.append(etudid)
T.append(t)
self.T = T
# tri par moyennes décroissantes,
# en laissant les demissionnaires a la fin, par ordre alphabetique
def row_key(x):
"""clé de tri par moyennes décroissantes,
en laissant les demissionnaires a la fin, par ordre alphabetique.
(moy_gen, rang_alpha)
"""
try:
moy = -float(x[0])
except (ValueError, TypeError):
moy = 1000.0
return (moy, rangalpha[x[-1]])
T.sort(key=row_key)
self.T = T
self.T.sort(key=self._row_key)
if len(valid_moy):
self.moy_min = min(valid_moy)
@ -349,7 +337,7 @@ class NotesTable(object):
ue_eff = len(
[x for x in val_ids if isinstance(x[0], float)]
) # nombre d'étudiants avec une note dans l'UE
val_ids.sort(key=row_key)
val_ids.sort(key=self._row_key)
ue_rangs[ue_id] = (
comp_ranks(val_ids),
ue_eff,
@ -360,13 +348,24 @@ class NotesTable(object):
for modimpl in self._modimpls:
vals = self._modmoys[modimpl["moduleimpl_id"]]
val_ids = [(vals[etudid], etudid) for etudid in vals.keys()]
val_ids.sort(key=row_key)
val_ids.sort(key=self._row_key)
self.mod_rangs[modimpl["moduleimpl_id"]] = (comp_ranks(val_ids), len(vals))
#
self.compute_moy_moy()
#
log(f"NotesTable( formsemestre_id={formsemestre_id} ) done.")
def _row_key(self, x):
"""clé de tri par moyennes décroissantes,
en laissant les demissionnaires a la fin, par ordre alphabetique.
(moy_gen, rang_alpha)
"""
try:
moy = -float(x[0])
except (ValueError, TypeError):
moy = 1000.0
return (moy, self.rang_alpha[x[-1]])
def get_etudids(self, sorted=False):
if sorted:
# Tri par moy. generale décroissante
@ -1338,7 +1337,7 @@ class NotesTable(object):
]
def apc_recompute_moyennes(self):
"""recalule les moyennes en APC (BUT)
"""recalcule les moyennes en APC (BUT)
et modifie en place le tableau T.
XXX Raccord provisoire avant refonte de cette classe.
"""
@ -1355,3 +1354,7 @@ class NotesTable(object):
for i, ue in enumerate(ues, start=1):
if ue["type"] != UE_SPORT:
t[i] = results.etud_moy_ue[ue["id"]][etudid]
# re-trie selon la nouvelle moyenne générale:
self.T.sort(key=self._row_key)
# Remplace aussi le rang:
self.rangs = results.etud_moy_gen_ranks

View File

@ -1121,7 +1121,7 @@ def formsemestre_tableau_modules(
[f"{ue_acro}: {co}" for ue_acro, co in mod.ue_coefs_descr()]
)
if coef_descr:
mod_descr += "coefs: " + coef_descr
mod_descr += " Coefs: " + coef_descr
else:
mod_descr += " (pas de coefficients) "
else: