1
0
forked from ScoDoc/ScoDoc

Calcul ECTS/parcours. Fix #437

This commit is contained in:
Emmanuel Viennet 2022-07-18 17:48:10 +02:00
parent 6eef66e482
commit 1967273220
7 changed files with 40 additions and 10 deletions

View File

@ -321,8 +321,8 @@ class BulletinBUT:
}
decisions_ues = self.res.get_etud_decision_ues(etud.id) or {}
if self.prefs["bul_show_ects"]:
ects_tot = sum([ue.ects or 0 for ue in res.ues]) if res.ues else 0.0
ects_acquis = sum([d.get("ects", 0) for d in decisions_ues.values()])
ects_tot = res.etud_ects_tot_sem(etud.id)
ects_acquis = res.get_etud_ects_valides(etud.id, decisions_ues)
semestre_infos["ECTS"] = {"acquis": ects_acquis, "total": ects_tot}
if sco_preferences.get_preference("bul_show_decision", formsemestre.id):
semestre_infos.update(

View File

@ -395,6 +395,18 @@ def get_table_jury_but(
row.add_ue_cells(deca.decisions_ues[rcue.ue_1.id])
row.add_ue_cells(deca.decisions_ues[rcue.ue_2.id])
row.add_rcue_cells(dec_rcue)
# --- Les ECTS validés
ects_valides = 0.0
if deca.res_impair:
ects_valides += deca.res_impair.get_etud_ects_valides(etudid)
if deca.res_pair:
ects_valides += deca.res_pair.get_etud_ects_valides(etudid)
row.add_cell(
"ects_annee",
"ECTS",
f"""{int(ects_valides)}""",
"col_code_annee",
)
# --- Le code annuel existant
row.add_cell(
"code_annee",

View File

@ -55,7 +55,9 @@ class ValidationsSemestre(ResultatsCache):
"""Cherche les decisions du jury pour le semestre (pas les UE).
Calcule les attributs:
decisions_jury = { etudid : { 'code' : None|ATT|..., 'assidu' : 0|1 }}
decision_jury_ues={ etudid : { ue_id : { 'code' : Note|ADM|CMP, 'event_date' }}}
decision_jury_ues={ etudid :
{ ue_id : { 'code' : Note|ADM|CMP, 'event_date' : "d/m/y", 'ects' : x }}
}
Si la décision n'a pas été prise, la clé etudid n'est pas présente.
Si l'étudiant est défaillant, pas de décisions d'UE.
"""

View File

@ -6,7 +6,6 @@
"""Résultats semestres BUT
"""
from collections.abc import Generator
from re import U
import time
import numpy as np
@ -235,7 +234,3 @@ class ResultatsSemestreBUT(NotesTableCompat):
"""
s = self.ues_inscr_parcours_df.loc[etudid]
return s.index[s.notna()]
def etud_ues(self, etudid: int) -> Generator[UniteEns]:
"""Liste des UE auxquelles l'étudiant est inscrit."""
return (UniteEns.query.get(ue_id) for ue_id in self.etud_ues_ids(etudid))

View File

@ -8,6 +8,7 @@
"""
from collections import Counter
from collections.abc import Generator
from functools import cached_property
import numpy as np
import pandas as pd
@ -120,6 +121,15 @@ class ResultatsSemestre(ResultatsCache):
# car tous les étudiants sont inscrits à toutes les UE
return [ue.id for ue in self.ues if ue.type != UE_SPORT]
def etud_ues(self, etudid: int) -> Generator[UniteEns]:
"""Liste des UE auxquelles l'étudiant est inscrit."""
return (UniteEns.query.get(ue_id) for ue_id in self.etud_ues_ids(etudid))
def etud_ects_tot_sem(self, etudid: int) -> float:
"""Le total des ECTS associées à ce semestre (que l'étudiant peut ou non valider)"""
etud_ues = self.etud_ues(etudid)
return sum([ue.ects or 0 for ue in etud_ues]) if etud_ues else 0.0
def modimpl_notes(self, modimpl_id: int, ue_id: int) -> np.ndarray:
"""Les notes moyennes des étudiants du sem. à ce modimpl dans cette ue.
Utile pour stats bottom tableau recap.

View File

@ -278,7 +278,7 @@ class NotesTableCompat(ResultatsSemestre):
def get_etud_decision_ues(self, etudid: int) -> dict:
"""Decisions du jury pour les UE de cet etudiant, ou None s'il n'y en pas eu.
Ne tient pas compte des UE capitalisées.
{ ue_id : { 'code' : ADM|CMP|AJ, 'event_date' : }
{ ue_id : { 'code' : ADM|CMP|AJ, 'event_date' : "d/m/y", 'ects' : x }
Ne renvoie aucune decision d'UE pour les défaillants
"""
if self.get_etud_etat(etudid) == DEF:
@ -290,6 +290,17 @@ class NotesTableCompat(ResultatsSemestre):
)
return self.validations.decisions_jury_ues.get(etudid, None)
def get_etud_ects_valides(self, etudid: int, decisions_ues: dict = False) -> 0:
"""Le total des ECTS validés (et enregistrés) par l'étudiant dans ce semestre.
NB: avant jury, rien d'enregistré, donc zéro ECTS.
Optimisation: si decisions_ues est passé, l'utilise, sinon appelle get_etud_decision_ues()
"""
if decisions_ues is False:
decisions_ues = self.get_etud_decision_ues(etudid)
if not decisions_ues:
return 0.0
return sum([d.get("ects", 0.0) for d in decisions_ues.values()])
def get_etud_decision_sem(self, etudid: int) -> dict:
"""Decision du jury prise pour cet etudiant, ou None s'il n'y en pas eu.
{ 'code' : None|ATT|..., 'assidu' : 0|1, 'event_date' : , compense_formsemestre_id }

View File

@ -1,7 +1,7 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
SCOVERSION = "9.3.21"
SCOVERSION = "9.3.22"
SCONAME = "ScoDoc"