1
0
forked from ScoDoc/ScoDoc

WIP: recap but avec UEs

This commit is contained in:
Emmanuel Viennet 2022-01-08 19:56:09 +01:00
parent 0e930d5fe4
commit a467ef27db
3 changed files with 41 additions and 5 deletions

View File

@ -11,6 +11,7 @@ import pandas as pd
from app.comp.aux import StatsMoyenne from app.comp.aux import StatsMoyenne
from app.comp.moy_mod import ModuleImplResults from app.comp.moy_mod import ModuleImplResults
from app.models import FormSemestre, ModuleImpl from app.models import FormSemestre, ModuleImpl
from app.models.ues import UniteEns
from app.scodoc import sco_utils as scu from app.scodoc import sco_utils as scu
from app.scodoc.sco_cache import ResultatsSemestreCache from app.scodoc.sco_cache import ResultatsSemestreCache
from app.scodoc.sco_codes_parcours import UE_SPORT, ATT, DEF from app.scodoc.sco_codes_parcours import UE_SPORT, ATT, DEF
@ -38,8 +39,9 @@ class ResultatsSemestre:
# BUT ou standard ? (apc == "approche par compétences") # BUT ou standard ? (apc == "approche par compétences")
self.is_apc = formsemestre.formation.is_apc() self.is_apc = formsemestre.formation.is_apc()
# Attributs "virtuels", définis dans les sous-classes # Attributs "virtuels", définis dans les sous-classes
# ResultatsSemestreBUT ou ResultatsSemestreStd # ResultatsSemestreBUT ou ResultatsSemestreClassic
self.etud_moy_ue = {} self.etud_moy_ue = {}
"etud_moy_ue: DataFrame columns UE, rows etudid"
self.etud_moy_gen = {} self.etud_moy_gen = {}
self.etud_moy_gen_ranks = {} self.etud_moy_gen_ranks = {}
self.modimpls_results: ModuleImplResults = None self.modimpls_results: ModuleImplResults = None
@ -78,7 +80,7 @@ class ResultatsSemestre:
return {e.id: idx for idx, e in enumerate(self.etuds)} return {e.id: idx for idx, e in enumerate(self.etuds)}
@cached_property @cached_property
def ues(self): def ues(self) -> list:
"Liste des UE du semestre" "Liste des UE du semestre"
return self.formsemestre.query_ues().all() return self.formsemestre.query_ues().all()
@ -114,6 +116,21 @@ class ResultatsSemestre:
"Liste des SAÉs du semestre, triées par numéro de module" "Liste des SAÉs du semestre, triées par numéro de module"
return [m for m in self.modimpls if m.module.module_type == scu.ModuleType.SAE] return [m for m in self.modimpls if m.module.module_type == scu.ModuleType.SAE]
@cached_property
def ue_validables(self) -> list:
"""Liste des UE du semestre qui doivent être validées
(toutes sauf le sport)
"""
return self.formsemestre.query_ues().filter(UniteEns.type != UE_SPORT).all()
@cached_property
def ue_au_dessus(self, seuil=10.0) -> pd.DataFrame:
"""DataFrame columns UE, rows etudid, valeurs: bool
Par exemple, pour avoir le nombre d'UE au dessus de 10 pour l'étudiant etudid
nb_ues_ok = sum(res.ue_au_dessus().loc[etudid])
"""
return self.etud_moy_ue > (seuil - scu.NOTES_TOLERANCE)
# Pour raccorder le code des anciens codes qui attendent une NoteTable # Pour raccorder le code des anciens codes qui attendent une NoteTable
class NotesTableCompat(ResultatsSemestre): class NotesTableCompat(ResultatsSemestre):

View File

@ -5,6 +5,7 @@ from app import db
from app.comp import df_cache from app.comp import df_cache
from app.models import SHORT_STR_LEN from app.models import SHORT_STR_LEN
from app.models.modules import Module from app.models.modules import Module
from app.models.ues import UniteEns
from app.scodoc import notesdb as ndb from app.scodoc import notesdb as ndb
from app.scodoc import sco_cache from app.scodoc import sco_cache
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
@ -130,8 +131,14 @@ class Formation(db.Model):
db.session.add(mod) db.session.add(mod)
change = True change = True
# --- Numéros de modules # --- Numéros de modules
if Module.query.filter_by(formation_id=220, numero=None).count() > 0: if Module.query.filter_by(formation_id=self.id, numero=None).count() > 0:
scu.objects_renumber(db, self.modules.all()) scu.objects_renumber(db, self.modules.all())
# --- Types d'UE (avant de rendre le type non nullable)
ues_sans_type = UniteEns.query.filter_by(formation_id=self.id, type=None)
if ues_sans_type.count() > 0:
for ue in ues_sans_type:
ue.type = 0
db.session.add(ue)
db.session.commit() db.session.commit()
if change: if change:

View File

@ -38,6 +38,7 @@ from flask import make_response
from app import log from app import log
from app.but import bulletin_but from app.but import bulletin_but
from app.comp import res_sem from app.comp import res_sem
from app.comp.res_common import NotesTableCompat
from app.models import FormSemestre from app.models import FormSemestre
from app.models.etudiants import Identite from app.models.etudiants import Identite
@ -307,7 +308,7 @@ def make_formsemestre_recapcomplet(
# nt = sco_cache.NotesTableCache.get(formsemestre_id) # nt = sco_cache.NotesTableCache.get(formsemestre_id)
# XXX EXPERIMENTAL # XXX EXPERIMENTAL
nt = res_sem.load_formsemestre_result(formsemestre) nt: NotesTableCompat = res_sem.load_formsemestre_result(formsemestre)
modimpls = nt.get_modimpls_dict() modimpls = nt.get_modimpls_dict()
ues = nt.get_ues_stat_dict() # incluant le(s) UE de sport ues = nt.get_ues_stat_dict() # incluant le(s) UE de sport
# #
@ -460,6 +461,10 @@ def make_formsemestre_recapcomplet(
for partition in partitions: for partition in partitions:
l.append(rang_gr[partition["partition_id"]]) l.append(rang_gr[partition["partition_id"]])
# Nombre d'UE au dessus de 10
nb_ue_ok = sum(
[t[i] > 10 for i, ue in enumerate(ues, start=1) if ue["type"] != UE_SPORT]
)
for i, ue in enumerate(ues, start=1): for i, ue in enumerate(ues, start=1):
if ue["type"] != UE_SPORT: if ue["type"] != UE_SPORT:
l.append( l.append(
@ -656,7 +661,9 @@ def make_formsemestre_recapcomplet(
if disable_etudlink: if disable_etudlink:
etudlink = "%(name)s" etudlink = "%(name)s"
else: else:
etudlink = '<a href="formsemestre_bulletinetud?formsemestre_id=%(formsemestre_id)s&etudid=%(etudid)s&version=selectedevals" id="%(etudid)s" class="etudinfo">%(name)s</a>' etudlink = """<a
href="formsemestre_bulletinetud?formsemestre_id=%(formsemestre_id)s&etudid=%(etudid)s&version=selectedevals"
id="%(etudid)s" class="etudinfo">%(name)s</a>"""
ir = 0 ir = 0
nblines = len(F) - 1 nblines = len(F) - 1
for l in F[1:]: for l in F[1:]:
@ -790,6 +797,11 @@ def make_formsemestre_recapcomplet(
for cod in cods: for cod in cods:
H.append("<tr><td>%s</td><td>%d</td></tr>" % (cod, codes_nb[cod])) H.append("<tr><td>%s</td><td>%d</td></tr>" % (cod, codes_nb[cod]))
H.append("</table>") H.append("</table>")
# Avertissements
if formsemestre.formation.is_apc():
H.append(
"""<p class="help">Pour les formations par compétences (comme le BUT), la moyenne générale est purement indicative et ne devrait pas être communiquée aux étudiants.</p>"""
)
return "\n".join(H), "", "html" return "\n".join(H), "", "html"
elif format == "csv": elif format == "csv":
CSV = scu.CSV_LINESEP.join( CSV = scu.CSV_LINESEP.join(