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.models import FormSemestre
from app.models.etudiants import Identite
from app.models.formsemestre import FormSemestreInscription
import app.scodoc.sco_utils as scu
from app.scodoc import html_sco_header
@ -51,10 +52,15 @@ from app.scodoc.gen_tables import GenTable
# Titres, ordonnés
INDICATEUR_NAMES = {
"nb_inscr": "Inscrits initiaux",
"nb_dem": "Démissions",
"nb_def": "Défaillants",
"nb_actifs": "Inscrits finals",
"nb_inscr_S1": "Inscrits initiaux S1",
"nb_dem_S1": "Démissions S1",
"nb_def_S1": "Défaillants S1",
"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_passe_manque_rcue": "Passant avec RCUE non validé",
"nb_red_avec_rcue": "Redoublant avec au moins un RCUE validé",
@ -130,98 +136,136 @@ def but_indicateurs_by_bac(formsemestre: FormSemestre) -> dict[str:dict]:
)
if formsemestre.semestre_id % 2:
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
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
etuds_by_bac = defaultdict(list) # bac : etuds
for etud in etuds:
adm = etud.admission.first()
bac = adm.get_bac().abbrev() if adm else "?"
etuds_by_bac[bac].append(etud)
inscriptions_by_bac = _formsemestre_inscriptions_by_bac(formsemestre)
indicateurs_by_bac = {}
for bac in etuds_by_bac:
decisions_annee_tous = {}
for bac in inscriptions_by_bac:
decisions_annee = {
etud.id: jury_but.DecisionsProposeesAnnee(etud, formsemestre)
for etud in etuds_by_bac[bac]
if res.get_etud_etat(etud.id) == scu.INSCRIT
inscr.etud.id: jury_but.DecisionsProposeesAnnee(inscr.etud, formsemestre)
for inscr in inscriptions_by_bac[bac]
}
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
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(
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
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(
res: NotesTableCompat,
etuds: list[Identite],
inscriptions: list[FormSemestreInscription],
decisions_annee: dict[jury_but.DecisionsProposeesAnnee],
red_sem_idx: int,
next_sem_idx: int,
) -> dict:
"""Calcule les indicateurs de l'enquête ADIUT 2022"""
indicateurs = {
"nb_inscr": len(etuds),
"nb_actifs": len(
[etud for etud in etuds if res.get_etud_etat(etud.id) == scu.INSCRIT]
),
"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(
[
True
for deca in decisions_annee.values()
if deca.code_valide == sco_codes_parcours.NAR
]
),
# Redoublants sans aucune RCUE
"nb_red_sans_rcue": len(
[
True
for deca in decisions_annee.values()
if (deca.nb_rcue_valides == 0)
and (next_sem_idx not in deca.get_autorisations_passage())
]
),
# Redoublants avec au moins une RCUE
"nb_red_avec_rcue": len(
[
True
for deca in decisions_annee.values()
if (deca.nb_rcue_valides > 0)
and (next_sem_idx not in deca.get_autorisations_passage())
]
),
# Passant (en BUT2) sans avoir validé tous les RCUE
"nb_passe_manque_rcue": len(
[
True
for deca in decisions_annee.values()
if (deca.nb_rcue_valides < deca.nb_competences)
and (next_sem_idx in deca.get_autorisations_passage())
]
),
# Ayant validé tous les RCUE
"nb_valide_tt_rcue": len(
[
True
for deca in decisions_annee.values()
if (deca.nb_rcue_valides >= deca.nb_competences)
]
),
}
indicateurs = _indicateurs_enquete_but_inscrits(inscriptions, suffix="S2")
indicateurs.update(
{
"nb_no_decision": len(
[True for deca in decisions_annee.values() if deca.code_valide is None]
),
"nb_nar": len(
[
True
for deca in decisions_annee.values()
if deca.code_valide == sco_codes_parcours.NAR
]
),
# Redoublants sans aucune RCUE
"nb_red_sans_rcue": len(
[
True
for deca in decisions_annee.values()
if (deca.nb_rcue_valides == 0)
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
"nb_red_avec_rcue": len(
[
True
for deca in decisions_annee.values()
if (deca.nb_rcue_valides > 0)
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
"nb_passe_manque_rcue": len(
[
True
for deca in decisions_annee.values()
if (deca.nb_rcue_valides < deca.nb_competences)
and (next_sem_idx in deca.get_autorisations_passage())
]
),
# Ayant validé tous les RCUE
"nb_valide_tt_rcue": len(
[
True
for deca in decisions_annee.values()
if (deca.nb_rcue_valides >= deca.nb_competences)
]
),
}
)
return indicateurs

View File

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