Module PE pour 9.1.50 - ok (à peu près) mais totalement inefficace/inutilisable.

This commit is contained in:
Emmanuel Viennet 2022-02-11 23:12:40 +01:00
parent e5b212a6e6
commit 7923921777
7 changed files with 89 additions and 81 deletions

View File

@ -6,9 +6,11 @@
"""Résultats semestres BUT
"""
import time
import numpy as np
import pandas as pd
from app import log
from app.comp import moy_ue, moy_sem, inscr_mod
from app.comp.res_common import NotesTableCompat
from app.comp.bonus_spo import BonusSport
@ -30,8 +32,14 @@ class ResultatsSemestreBUT(NotesTableCompat):
super().__init__(formsemestre)
if not self.load_cached():
t0 = time.time()
self.compute()
t1 = time.time()
self.store()
t2 = time.time()
log(
f"ResultatsSemestreBUT: cached formsemestre_id={formsemestre.id} ({(t1-t0):g}s +{(t2-t1):g}s)"
)
def compute(self):
"Charge les notes et inscriptions et calcule les moyennes d'UE et gen."

View File

@ -6,7 +6,7 @@
"""Résultats semestres classiques (non APC)
"""
import time
import numpy as np
import pandas as pd
from sqlalchemy.sql import text
@ -40,8 +40,14 @@ class ResultatsSemestreClassic(NotesTableCompat):
super().__init__(formsemestre)
if not self.load_cached():
t0 = time.time()
self.compute()
t1 = time.time()
self.store()
t2 = time.time()
log(
f"ResultatsSemestreClassic: cached formsemestre_id={formsemestre.id} ({(t1-t0):g}s +{(t2-t1):g}s)"
)
# recalculé (aussi rapide que de les cacher)
self.moy_min = self.etud_moy_gen.min()
self.moy_max = self.etud_moy_gen.max()

View File

@ -213,9 +213,10 @@ class ResultatsSemestre(ResultatsCache):
def get_etud_ue_status(self, etudid: int, ue_id: int) -> dict:
"""L'état de l'UE pour cet étudiant.
L'UE doit être du semestre.
Result: dict.
Result: dict, ou None si l'UE n'est pas dans ce semestre.
"""
if not ue_id in self.etud_moy_ue:
return None
if not self.validations:
self.validations = res_sem.load_formsemestre_validations(self.formsemestre)
ue = UniteEns.query.get(ue_id) # TODO cacher nos UEs ?
@ -333,8 +334,8 @@ class NotesTableCompat(ResultatsSemestre):
@cached_property
def sem(self) -> dict:
"""le formsemestre, comme un dict (nt.sem)"""
return self.formsemestre.to_dict()
"""le formsemestre, comme un gros et gras dict (nt.sem)"""
return self.formsemestre.get_infos_dict()
@cached_property
def inscrlist(self) -> list[dict]: # utilisé par PE seulement

View File

@ -25,7 +25,7 @@ def load_formsemestre_results(formsemestre: FormSemestre) -> ResultatsSemestre:
"""
# --- Try local cache (within the same request context)
if not hasattr(g, "formsemestre_results_cache"):
g.formsemestre_results_cache = {} # pylint: disable=C0237
g.formsemestre_results_cache = {}
else:
if formsemestre.id in g.formsemestre_results_cache:
return g.formsemestre_results_cache[formsemestre.id]

View File

@ -1133,7 +1133,7 @@ class JuryPE(object):
def get_cache_notes_d_un_semestre(self, formsemestre_id: int) -> NotesTableCompat:
"""Charge la table des notes d'un formsemestre"""
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
return res_sem.load_formsemestre_results(formsemestre)
# ------------------------------------------------------------------------------------------------------------------

View File

@ -40,6 +40,7 @@ from app import log
from app.comp import res_sem
from app.comp.res_common import NotesTableCompat
from app.models import FormSemestre
from app.models.moduleimpls import ModuleImpl
from app.models.ues import UniteEns
from app.scodoc import sco_codes_parcours
@ -55,7 +56,7 @@ class SemestreTag(pe_tagtable.TableTag):
- nt: le tableau de notes du semestre considéré
- nt.inscrlist: étudiants inscrits à ce semestre, par ordre alphabétique (avec demissions)
- nt.identdict: { etudid : ident }
- nt._modimpls : liste des moduleimpl { ... 'module_id', ...}
- liste des moduleimpl { ... 'module_id', ...}
Attributs supplémentaires :
- inscrlist/identdict: étudiants inscrits hors démissionnaires ou défaillants
@ -100,7 +101,11 @@ class SemestreTag(pe_tagtable.TableTag):
self.nt = notetable
# Les attributs hérités : la liste des étudiants
self.inscrlist = [etud for etud in self.nt.inscrlist if etud["etat"] == "I"]
self.inscrlist = [
etud
for etud in self.nt.inscrlist
if self.nt.get_etud_etat(etud["etudid"]) == "I"
]
self.identdict = {
etudid: ident
for (etudid, ident) in self.nt.identdict.items()
@ -110,12 +115,15 @@ class SemestreTag(pe_tagtable.TableTag):
# Les modules pris en compte dans le calcul des moyennes par tag => ceux des UE standards
self.modimpls = [
modimpl
for modimpl in self.nt._modimpls
if modimpl["ue"]["type"] == sco_codes_parcours.UE_STANDARD
for modimpl in self.nt.formsemestre.modimpls_sorted
if modimpl.module.ue.type == sco_codes_parcours.UE_STANDARD
] # la liste des modules (objet modimpl)
# self._modimpl_ids = [modimpl['moduleimpl_id'] for modimpl in self._modimpls] # la liste de id des modules (modimpl_id)
self.somme_coeffs = sum(
[modimpl["module"]["coefficient"] for modimpl in self.modimpls]
[
modimpl.module.coefficient
for modimpl in self.modimpls
if modimpl.module.coefficient is not None
]
)
# -----------------------------------------------------------------------------
@ -159,9 +167,9 @@ class SemestreTag(pe_tagtable.TableTag):
tagdict = {}
for modimpl in self.modimpls:
modimpl_id = modimpl["moduleimpl_id"]
modimpl_id = modimpl.id
# liste des tags pour le modimpl concerné:
tags = sco_tag_module.module_tag_list(modimpl["module_id"])
tags = sco_tag_module.module_tag_list(modimpl.module.id)
for (
tag
@ -175,17 +183,13 @@ class SemestreTag(pe_tagtable.TableTag):
# Ajout du modimpl au tagname considéré
tagdict[tagname][modimpl_id] = {
"module_id": modimpl["module_id"], # les données sur le module
"coeff": modimpl["module"][
"coefficient"
], # le coeff du module dans le semestre
"module_id": modimpl.module.id, # les données sur le module
"coeff": modimpl.module.coefficient, # le coeff du module dans le semestre
"ponderation": ponderation, # la pondération demandée pour le tag sur le module
"module_code": modimpl["module"][
"code"
], # le code qui doit se retrouver à l'identique dans des ue capitalisee
"ue_id": modimpl["ue"]["ue_id"], # les données sur l'ue
"ue_code": modimpl["ue"]["ue_code"],
"ue_acronyme": modimpl["ue"]["acronyme"],
"module_code": modimpl.module.code, # le code qui doit se retrouver à l'identique dans des ue capitalisee
"ue_id": modimpl.module.ue.id, # les données sur l'ue
"ue_code": modimpl.module.ue.ue_code,
"ue_acronyme": modimpl.module.ue.acronyme,
}
return tagdict
@ -221,7 +225,9 @@ class SemestreTag(pe_tagtable.TableTag):
def get_moyennes_DUT(self):
"""Lit les moyennes DUT du semestre pour tous les étudiants
et les renvoie au même format que comp_MoyennesTag"""
return [(self.nt.moy_gen[etudid], 1.0, etudid) for etudid in self.get_etudids()]
return [
(self.nt.etud_moy_gen[etudid], 1.0, etudid) for etudid in self.get_etudids()
]
# -----------------------------------------------------------------------------
def get_noteEtCoeff_modimpl(self, modimpl_id, etudid, profondeur=2):
@ -233,7 +239,7 @@ class SemestreTag(pe_tagtable.TableTag):
"""
(note, coeff_norm) = (None, None)
modimpl = get_moduleimpl(self.nt, modimpl_id) # Le module considéré
modimpl = get_moduleimpl(modimpl_id) # Le module considéré
if modimpl == None or profondeur < 0:
return (None, None)
@ -241,14 +247,14 @@ class SemestreTag(pe_tagtable.TableTag):
ue_capitalisees = self.get_ue_capitalisees(
etudid
) # les ue capitalisées des étudiants
ue_capitalisees_id = [
ue.id for ue in ue_capitalisees
] # les id des ue capitalisées
ue_capitalisees_id = {
ue_cap["ue_id"] for ue_cap in ue_capitalisees
} # les id des ue capitalisées
# Si le module ne fait pas partie des UE capitalisées
if modimpl["module"]["ue_id"] not in ue_capitalisees_id:
if modimpl.module.ue.id not in ue_capitalisees_id:
note = self.nt.get_etud_mod_moy(modimpl_id, etudid) # lecture de la note
coeff = modimpl["module"]["coefficient"] # le coeff
coeff = modimpl.module.coefficient # le coeff
coeff_norm = (
coeff / self.somme_coeffs if self.somme_coeffs != 0 else 0
) # le coeff normalisé
@ -259,12 +265,10 @@ class SemestreTag(pe_tagtable.TableTag):
self.nt, etudid, modimpl_id
) # la moyenne actuelle
# A quel semestre correspond l'ue capitalisée et quelles sont ses notes ?
# fid_prec = [ ue['formsemestre_id'] for ue in ue_capitalisees if ue['ue_id'] == modimpl['module']['ue_id'] ][0]
# semestre_id = modimpl['module']['semestre_id']
fids_prec = [
ue["formsemestre_id"]
for ue in ue_capitalisees
if ue.ue_code == modimpl["ue"]["ue_code"]
ue_cap["formsemestre_id"]
for ue_cap in ue_capitalisees
if ue_cap["ue_code"] == modimpl.module.ue.ue_code
] # and ue['semestre_id'] == semestre_id]
if len(fids_prec) > 0:
# => le formsemestre_id du semestre dont vient la capitalisation
@ -277,13 +281,14 @@ class SemestreTag(pe_tagtable.TableTag):
)
# Y-a-t-il un module équivalent c'est à dire correspondant au même code (le module_id n'étant pas significatif en cas de changement de PPN)
modimpl_prec = [
module
for module in nt_prec._modimpls
if module["module"]["code"] == modimpl["module"]["code"]
modi
for modi in nt_prec.formsemestre.modimpls_sorted
if modi.module.code == modimpl.module.code
]
if len(modimpl_prec) > 0: # si une correspondance est trouvée
modprec_id = modimpl_prec[0]["moduleimpl_id"]
modprec_id = modimpl_prec[0].id
moy_ue_capitalisee = get_moy_ue_from_nt(nt_prec, etudid, modprec_id)
if (
moy_ue_capitalisee is None
@ -291,7 +296,7 @@ class SemestreTag(pe_tagtable.TableTag):
note = self.nt.get_etud_mod_moy(
modimpl_id, etudid
) # lecture de la note
coeff = modimpl["module"]["coefficient"] # le coeff
coeff = modimpl.module.coefficient # le coeff
coeff_norm = (
coeff / self.somme_coeffs if self.somme_coeffs != 0 else 0
) # le coeff normalisé
@ -305,13 +310,11 @@ class SemestreTag(pe_tagtable.TableTag):
return (note, coeff_norm)
# -----------------------------------------------------------------------------
def get_ue_capitalisees(self, etudid) -> list[UniteEns]:
"""Renvoie la liste des ue_id effectivement capitalisées par un étudiant"""
ue_ids = [
ue_id
for ue_id in self.nt.validations.ue_capitalisees.loc[[etudid]]["ue_id"]
]
return [UniteEns.query.get(ue_id) for ue_id in ue_ids]
def get_ue_capitalisees(self, etudid) -> list[dict]:
"""Renvoie la liste des capitalisation effectivement capitalisées par un étudiant"""
if etudid in self.nt.validations.ue_capitalisees.index:
return self.nt.validations.ue_capitalisees.loc[[etudid]].to_dict("records")
return []
# -----------------------------------------------------------------------------
def get_listesNotesEtCoeffsTagEtudiant(self, tag, etudid):
@ -477,37 +480,27 @@ def comp_coeff_pond(coeffs, ponderations):
# -----------------------------------------------------------------------------
def get_moduleimpl(nt, modimpl_id):
"""Renvoie l'objet modimpl dont l'id est modimpl_id fourni dans la note table nt,
en utilisant l'attribut nt._modimpls"""
modimplids = [
modimpl["moduleimpl_id"] for modimpl in nt._modimpls
] # la liste de id des modules (modimpl_id)
if modimpl_id not in modimplids:
def get_moduleimpl(modimpl_id) -> dict:
"""Renvoie l'objet modimpl dont l'id est modimpl_id"""
modimpl = ModuleImpl.query.get(modimpl_id)
if modimpl:
return modimpl
if SemestreTag.DEBUG:
log(
"SemestreTag.get_moduleimpl( %s ) : le modimpl recherche n'existe pas"
% (modimpl_id)
)
return None
return nt._modimpls[modimplids.index(modimpl_id)]
# **********************************************
def get_moy_ue_from_nt(nt, etudid, modimpl_id):
"""Renvoie la moyenne de l'UE d'un etudid dans laquelle se trouve le module de modimpl_id
en partant du note table nt"""
mod = get_moduleimpl(nt, modimpl_id) # le module
indice = 0
while indice < len(nt._ues):
if (
nt._ues[indice]["ue_id"] == mod["module"]["ue_id"]
): # si les ue_id correspond
data = [
ligne for ligne in nt.T if ligne[-1] == etudid
] # les notes de l'étudiant
if data:
return data[0][indice + 1] # la moyenne à l'ue
else:
indice += 1
return None # si non trouvé
def get_moy_ue_from_nt(nt, etudid, modimpl_id) -> float:
"""Renvoie la moyenne de l'UE d'un etudid dans laquelle se trouve
le module de modimpl_id
"""
# ré-écrit
modimpl = get_moduleimpl(modimpl_id) # le module
ue_status = nt.get_etud_ue_status(etudid, modimpl.module.ue.id)
if ue_status is None:
return None
return ue_status["moy"]

View File

@ -68,7 +68,7 @@ class TableTag(object):
self.taglist = []
self.resultats = {}
self.etud_moy_gen_ranks = {}
self.rangs = {}
self.statistiques = {}
# *****************************************************************************************************************