forked from ScoDoc/ScoDoc
Tableaux d'indicateurs de suivi BUT
This commit is contained in:
parent
692d7b5fe0
commit
51cc2ca6a5
@ -126,6 +126,12 @@ def _build_menu_stats(formsemestre_id):
|
||||
"args": {"formsemestre_id": formsemestre_id},
|
||||
"enabled": True,
|
||||
},
|
||||
{
|
||||
"title": "Indicateurs de suivi annuel BUT",
|
||||
"endpoint": "notes.formsemestre_but_indicateurs",
|
||||
"args": {"formsemestre_id": formsemestre_id},
|
||||
"enabled": True,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
|
221
app/scodoc/sco_report_but.py
Normal file
221
app/scodoc/sco_report_but.py
Normal file
@ -0,0 +1,221 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gestion scolarite IUT
|
||||
#
|
||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# Emmanuel Viennet emmanuel.viennet@viennet.net
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
"""Rapport sur réussite en BUT pour enquête 2022
|
||||
- statistiques decisions
|
||||
"""
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
from flask import request
|
||||
|
||||
from app.but import jury_but
|
||||
from app.comp import res_sem
|
||||
from app.comp.res_compat import NotesTableCompat
|
||||
from app.models import FormSemestre
|
||||
from app.models.etudiants import Identite
|
||||
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app.scodoc import html_sco_header
|
||||
from app.scodoc import sco_codes_parcours
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
|
||||
from app.scodoc import sco_preferences
|
||||
import sco_version
|
||||
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_nar": "NAR",
|
||||
"nb_passe_manque_rcue": "Passant avec RCUE non validé",
|
||||
"nb_red_avec_rcue": "Redoublant avec au moins un RCUE validé",
|
||||
"nb_red_sans_rcue": "Redoublant sans avoir validé aucun RCUE",
|
||||
"nb_valide_tt_rcue": "Validant tous les RCUE de l'année",
|
||||
}
|
||||
|
||||
|
||||
def formsemestre_but_indicateurs(formsemestre_id: int, format="html"):
|
||||
"""Page avec tableau indicateurs enquête ADIUT BUT 2022"""
|
||||
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
|
||||
indicateurs_by_bac = but_indicateurs_by_bac(formsemestre)
|
||||
# finalement on fait une table avec en ligne
|
||||
# les indicateurs, et en colonne les bacs
|
||||
bacs = sorted(indicateurs_by_bac.keys())
|
||||
|
||||
rows = []
|
||||
for indicateur, titre_indicateur in INDICATEUR_NAMES.items():
|
||||
row = {bac: indicateurs_by_bac[bac][indicateur] for bac in bacs}
|
||||
row["titre_indicateur"] = titre_indicateur
|
||||
rows.append(row)
|
||||
|
||||
tab = GenTable(
|
||||
titles={bac: bac for bac in bacs},
|
||||
columns_ids=["titre_indicateur"] + bacs,
|
||||
rows=rows,
|
||||
html_sortable=False,
|
||||
preferences=sco_preferences.SemPreferences(formsemestre_id),
|
||||
filename=scu.make_filename(f"Indicateurs_BUT_{formsemestre.titre_annee()}"),
|
||||
origin=f"Généré par {sco_version.SCONAME} le {scu.timedate_human_repr()}",
|
||||
html_caption="Indicateurs BUT annuels.",
|
||||
base_url=f"{request.base_url}?formsemestre_id={formsemestre_id}",
|
||||
)
|
||||
title = "Indicateurs suivi annuel BUT"
|
||||
t = tab.make_page(
|
||||
title=f"""<h2 class="formsemestre">{title}</h2>""",
|
||||
format=format,
|
||||
with_html_headers=False,
|
||||
)
|
||||
if format != "html":
|
||||
return t
|
||||
H = [
|
||||
html_sco_header.sco_header(page_title=title),
|
||||
t,
|
||||
"""<p class="help">
|
||||
</p>""",
|
||||
html_sco_header.sco_footer(),
|
||||
]
|
||||
return "\n".join(H)
|
||||
|
||||
|
||||
def but_indicateurs_by_bac(formsemestre: FormSemestre) -> dict[str:dict]:
|
||||
"""
|
||||
L'enquête ADIUT porte sur le nombre de
|
||||
- inscrits
|
||||
- ayant validé tous les RCUE
|
||||
- passant en BUT2 sans avoir validé tous les RCUE
|
||||
- redoublants avec au moins une RCUE
|
||||
- redoublants sans aucune RCUE
|
||||
- NAR
|
||||
- défaillants
|
||||
- démissionnaires,
|
||||
le tout découpé en FI/FA et suivant le type de bac : général/techno/pro/autre.
|
||||
|
||||
Le semestre est FI ou FA, donc on ne traite pas ce point.
|
||||
On suppose qu'on est sur un semestre PAIR de BUT, dont les décisions de jury
|
||||
ont déjà été saisies.
|
||||
"""
|
||||
if not formsemestre.formation.is_apc():
|
||||
raise ScoValueError(
|
||||
"Ce rapport doit être généré à partir d'une formation par compétences (BUT)."
|
||||
)
|
||||
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)
|
||||
next_sem_idx = formsemestre.semestre_id + 1
|
||||
|
||||
res: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||
etuds = formsemestre.get_inscrits(include_demdef=True)
|
||||
decisions_annee = {
|
||||
etud.id: jury_but.DecisionsProposeesAnnee(etud, formsemestre)
|
||||
for etud in etuds
|
||||
if res.get_etud_etat(etud.id) == scu.INSCRIT
|
||||
}
|
||||
# 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)
|
||||
indicateurs_by_bac = {}
|
||||
for bac in etuds_by_bac:
|
||||
indicateurs_by_bac[bac] = _indicateurs_enquete_but(
|
||||
res, etuds_by_bac[bac], decisions_annee, next_sem_idx
|
||||
)
|
||||
indicateurs_by_bac["Total"] = _indicateurs_enquete_but(
|
||||
res, etuds, decisions_annee, next_sem_idx
|
||||
)
|
||||
return indicateurs_by_bac
|
||||
|
||||
|
||||
def _indicateurs_enquete_but(
|
||||
res: NotesTableCompat,
|
||||
etuds: list[Identite],
|
||||
decisions_annee: dict[jury_but.DecisionsProposeesAnnee],
|
||||
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)
|
||||
]
|
||||
),
|
||||
}
|
||||
return indicateurs
|
@ -128,6 +128,7 @@ from app.scodoc import sco_prepajury
|
||||
from app.scodoc import sco_pvjury
|
||||
from app.scodoc import sco_recapcomplet
|
||||
from app.scodoc import sco_report
|
||||
from app.scodoc import sco_report_but
|
||||
from app.scodoc import sco_saisie_notes
|
||||
from app.scodoc import sco_semset
|
||||
from app.scodoc import sco_synchro_etuds
|
||||
@ -2967,6 +2968,11 @@ sco_publish(
|
||||
sco_report.formsemestre_graph_parcours,
|
||||
Permission.ScoView,
|
||||
)
|
||||
sco_publish(
|
||||
"/formsemestre_but_indicateurs",
|
||||
sco_report_but.formsemestre_but_indicateurs,
|
||||
Permission.ScoView,
|
||||
)
|
||||
sco_publish(
|
||||
"/formsemestre_poursuite_report",
|
||||
sco_poursuite_dut.formsemestre_poursuite_report,
|
||||
|
Loading…
Reference in New Issue
Block a user