Améliore tablea indicateurs BUT

This commit is contained in:
Emmanuel Viennet 2022-09-27 08:27:19 +02:00
parent 24695af09c
commit 810e1f6cff
2 changed files with 124 additions and 80 deletions

View File

@ -38,6 +38,7 @@ from app.comp import res_sem
from app.comp.res_compat import NotesTableCompat from app.comp.res_compat import NotesTableCompat
from app.models import FormSemestre from app.models import FormSemestre
from app.models.etudiants import Identite from app.models.etudiants import Identite
from app.models.formsemestre import FormSemestreInscription
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
@ -51,10 +52,15 @@ from app.scodoc.gen_tables import GenTable
# Titres, ordonnés # Titres, ordonnés
INDICATEUR_NAMES = { INDICATEUR_NAMES = {
"nb_inscr": "Inscrits initiaux", "nb_inscr_S1": "Inscrits initiaux S1",
"nb_dem": "Démissions", "nb_dem_S1": "Démissions S1",
"nb_def": "Défaillants", "nb_def_S1": "Défaillants S1",
"nb_actifs": "Inscrits finals", "nb_actifs_S1": "Inscrits finals S1",
"nb_inscr_S2": "Inscrits initiaux S2",
"nb_dem_S2": "Démissions S2",
"nb_def_S2": "Défaillants S2",
"nb_actifs_S2": "Inscrits finals S2",
"nb_no_decision": "Sans décision de jury BUT",
"nb_nar": "NAR", "nb_nar": "NAR",
"nb_passe_manque_rcue": "Passant avec RCUE non validé", "nb_passe_manque_rcue": "Passant avec RCUE non validé",
"nb_red_avec_rcue": "Redoublant avec au moins un RCUE validé", "nb_red_avec_rcue": "Redoublant avec au moins un RCUE validé",
@ -130,56 +136,91 @@ def but_indicateurs_by_bac(formsemestre: FormSemestre) -> dict[str:dict]:
) )
if formsemestre.semestre_id % 2: if formsemestre.semestre_id % 2:
raise ScoValueError("Ce rapport doit être généré à partir d'un semestre PAIR.") raise ScoValueError("Ce rapport doit être généré à partir d'un semestre PAIR.")
# Le semestre suivant (pour compter les passages) # Les semestres suivant/precedent (pour compter les passages et redoublements)
next_sem_idx = formsemestre.semestre_id + 1 next_sem_idx = formsemestre.semestre_id + 1
red_sem_idx = formsemestre.semestre_id - 1
res: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
etuds = formsemestre.get_inscrits(include_demdef=True)
# Ventilation par bac # Ventilation par bac
etuds_by_bac = defaultdict(list) # bac : etuds inscriptions_by_bac = _formsemestre_inscriptions_by_bac(formsemestre)
for etud in etuds:
adm = etud.admission.first()
bac = adm.get_bac().abbrev() if adm else "?"
etuds_by_bac[bac].append(etud)
indicateurs_by_bac = {} indicateurs_by_bac = {}
for bac in etuds_by_bac: decisions_annee_tous = {}
for bac in inscriptions_by_bac:
decisions_annee = { decisions_annee = {
etud.id: jury_but.DecisionsProposeesAnnee(etud, formsemestre) inscr.etud.id: jury_but.DecisionsProposeesAnnee(inscr.etud, formsemestre)
for etud in etuds_by_bac[bac] for inscr in inscriptions_by_bac[bac]
if res.get_etud_etat(etud.id) == scu.INSCRIT
} }
indicateurs_by_bac[bac] = _indicateurs_enquete_but( indicateurs_by_bac[bac] = _indicateurs_enquete_but(
res, etuds_by_bac[bac], decisions_annee, next_sem_idx inscriptions_by_bac[bac], decisions_annee, red_sem_idx, next_sem_idx
) )
decisions_annee_tous.update(decisions_annee)
# refait pour tous # refait pour tous
decisions_annee = {
etud.id: jury_but.DecisionsProposeesAnnee(etud, formsemestre)
for etud in etuds
if res.get_etud_etat(etud.id) == scu.INSCRIT
}
indicateurs_by_bac["Total"] = _indicateurs_enquete_but( indicateurs_by_bac["Total"] = _indicateurs_enquete_but(
res, etuds, decisions_annee, next_sem_idx formsemestre.inscriptions, decisions_annee_tous, red_sem_idx, next_sem_idx
)
# Comptages sur semestre(s) précédent(s)
# en effet, les étudiants de ce semestre pair peuvent venir de
# différents S1
formsemestre_id_precedents = {
deca.formsemestre_impair.id
for deca in decisions_annee_tous.values()
if deca and deca.formsemestre_impair
}
for formsemestre_id_precedent in formsemestre_id_precedents:
formsemestre_impair = FormSemestre.query.get(formsemestre_id_precedent)
suffix = (
f"S{formsemestre_impair.semestre_id}"
if len(formsemestre_id_precedents) == 1
else formsemestre_impair.session_id()
)
indicateurs_by_bac["Total"].update(
_indicateurs_enquete_but_inscrits(formsemestre_impair.inscriptions, suffix)
)
for bac, inscriptions in _formsemestre_inscriptions_by_bac(
formsemestre_impair
).items():
indicateurs_by_bac[bac].update(
_indicateurs_enquete_but_inscrits(inscriptions, suffix)
) )
return indicateurs_by_bac return indicateurs_by_bac
def _formsemestre_inscriptions_by_bac(formsemestre: FormSemestre) -> defaultdict:
"liste d'inscriptions, par type de bac"
inscriptions_by_bac = defaultdict(list) # bac : etuds
for inscr in formsemestre.inscriptions:
adm = inscr.etud.admission.first()
bac = adm.get_bac().abbrev() if adm else "?"
inscriptions_by_bac[bac].append(inscr)
return inscriptions_by_bac
def _indicateurs_enquete_but_inscrits(
inscriptions: list[FormSemestreInscription], suffix: str
) -> dict:
"""Nombre d'incrits, DEM, DEF.
Suffixe les clés avec _suffix"""
if suffix:
suffix = "_" + suffix
return {
"nb_inscr" + suffix: len(inscriptions),
"nb_actifs" + suffix: len([i for i in inscriptions if i.etat == scu.INSCRIT]),
"nb_def" + suffix: len([i for i in inscriptions if i.etat == scu.DEF]),
"nb_dem" + suffix: len([i for i in inscriptions if i.etat == scu.DEMISSION]),
}
def _indicateurs_enquete_but( def _indicateurs_enquete_but(
res: NotesTableCompat, inscriptions: list[FormSemestreInscription],
etuds: list[Identite],
decisions_annee: dict[jury_but.DecisionsProposeesAnnee], decisions_annee: dict[jury_but.DecisionsProposeesAnnee],
red_sem_idx: int,
next_sem_idx: int, next_sem_idx: int,
) -> dict: ) -> dict:
"""Calcule les indicateurs de l'enquête ADIUT 2022""" """Calcule les indicateurs de l'enquête ADIUT 2022"""
indicateurs = { indicateurs = _indicateurs_enquete_but_inscrits(inscriptions, suffix="S2")
"nb_inscr": len(etuds), indicateurs.update(
"nb_actifs": len( {
[etud for etud in etuds if res.get_etud_etat(etud.id) == scu.INSCRIT] "nb_no_decision": len(
), [True for deca in decisions_annee.values() if deca.code_valide is None]
"nb_def": len(
[etud for etud in etuds if res.get_etud_etat(etud.id) == scu.DEF]
),
"nb_dem": len(
[etud for etud in etuds if res.get_etud_etat(etud.id) == scu.DEMISSION]
), ),
"nb_nar": len( "nb_nar": len(
[ [
@ -195,6 +236,7 @@ def _indicateurs_enquete_but(
for deca in decisions_annee.values() for deca in decisions_annee.values()
if (deca.nb_rcue_valides == 0) if (deca.nb_rcue_valides == 0)
and (next_sem_idx not in deca.get_autorisations_passage()) and (next_sem_idx not in deca.get_autorisations_passage())
and (red_sem_idx in deca.get_autorisations_passage())
] ]
), ),
# Redoublants avec au moins une RCUE # Redoublants avec au moins une RCUE
@ -204,6 +246,7 @@ def _indicateurs_enquete_but(
for deca in decisions_annee.values() for deca in decisions_annee.values()
if (deca.nb_rcue_valides > 0) if (deca.nb_rcue_valides > 0)
and (next_sem_idx not in deca.get_autorisations_passage()) and (next_sem_idx not in deca.get_autorisations_passage())
and (red_sem_idx in deca.get_autorisations_passage())
] ]
), ),
# Passant (en BUT2) sans avoir validé tous les RCUE # Passant (en BUT2) sans avoir validé tous les RCUE
@ -224,4 +267,5 @@ def _indicateurs_enquete_but(
] ]
), ),
} }
)
return indicateurs return indicateurs

View File

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