forked from ScoDoc/ScoDoc
comptes croisés: ajout nb RCUE et code annuel
This commit is contained in:
parent
1c30d4d926
commit
692d7b5fe0
@ -296,6 +296,10 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
[rcue for rcue in rcues_avec_niveau if rcue.est_validable()]
|
[rcue for rcue in rcues_avec_niveau if rcue.est_validable()]
|
||||||
)
|
)
|
||||||
"le nombre de comp. validables (éventuellement par compensation)"
|
"le nombre de comp. validables (éventuellement par compensation)"
|
||||||
|
self.nb_rcue_valides = len(
|
||||||
|
[rcue for rcue in rcues_avec_niveau if rcue.code_valide()]
|
||||||
|
)
|
||||||
|
"le nombre de niveaux validés (déc. jury prise)"
|
||||||
self.nb_rcues_under_8 = len(
|
self.nb_rcues_under_8 = len(
|
||||||
[rcue for rcue in rcues_avec_niveau if not rcue.est_suffisant()]
|
[rcue for rcue in rcues_avec_niveau if not rcue.est_suffisant()]
|
||||||
)
|
)
|
||||||
@ -393,7 +397,7 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
|
|
||||||
<li>RCUEs: {html.escape(str(self.rcues_annee))}</li>
|
<li>RCUEs: {html.escape(str(self.rcues_annee))}</li>
|
||||||
<li>nb_competences: {getattr(self, "nb_competences", "-")}</li>
|
<li>nb_competences: {getattr(self, "nb_competences", "-")}</li>
|
||||||
<li>nb_nb_validables: {getattr(self, "nb_validables", "-")}</li>
|
<li>nb_validables: {getattr(self, "nb_validables", "-")}</li>
|
||||||
<li>codes: {self.codes}</li>
|
<li>codes: {self.codes}</li>
|
||||||
<li>explanation: {self.explanation}</li>
|
<li>explanation: {self.explanation}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -299,7 +299,7 @@ class NotesTableCompat(ResultatsSemestre):
|
|||||||
return sum([d.get("ects", 0.0) for d in decisions_ues.values()])
|
return sum([d.get("ects", 0.0) for d in decisions_ues.values()])
|
||||||
|
|
||||||
def get_etud_decision_sem(self, etudid: int) -> dict:
|
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.
|
"""Decision du jury semestre prise pour cet etudiant, ou None s'il n'y en pas eu.
|
||||||
{ 'code' : None|ATT|..., 'assidu' : 0|1, 'event_date' : , compense_formsemestre_id }
|
{ 'code' : None|ATT|..., 'assidu' : 0|1, 'event_date' : , compense_formsemestre_id }
|
||||||
Si état défaillant, force le code a DEF
|
Si état défaillant, force le code a DEF
|
||||||
"""
|
"""
|
||||||
|
@ -196,8 +196,8 @@ class RegroupementCoherentUE:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def est_validable(self) -> bool:
|
def est_validable(self) -> bool:
|
||||||
"""Vrai si ce RCU satisfait les conditions pour être validé
|
"""Vrai si ce RCUE satisfait les conditions pour être validé,
|
||||||
Pour cela, il suffit que la moyenne des UE qui le constitue soit > 10
|
c'est à dire que la moyenne des UE qui le constituent soit > 10
|
||||||
"""
|
"""
|
||||||
return (self.moy_rcue is not None) and (
|
return (self.moy_rcue is not None) and (
|
||||||
self.moy_rcue > sco_codes.BUT_BARRE_RCUE
|
self.moy_rcue > sco_codes.BUT_BARRE_RCUE
|
||||||
|
@ -610,7 +610,7 @@ def log_unknown_etud():
|
|||||||
log(f"unknown student: args={etud_args}")
|
log(f"unknown student: args={etud_args}")
|
||||||
|
|
||||||
|
|
||||||
def get_etud_info(etudid=False, code_nip=False, filled=False) -> list:
|
def get_etud_info(etudid=False, code_nip=False, filled=False) -> list[dict]:
|
||||||
"""infos sur un etudiant (API). If not found, returns empty list.
|
"""infos sur un etudiant (API). If not found, returns empty list.
|
||||||
On peut spécifier etudid ou code_nip
|
On peut spécifier etudid ou code_nip
|
||||||
ou bien cherche dans les arguments de la requête courante:
|
ou bien cherche dans les arguments de la requête courante:
|
||||||
|
@ -167,9 +167,9 @@ def _formsemestre_enrich(sem):
|
|||||||
sem["semestre_id"],
|
sem["semestre_id"],
|
||||||
) # eg "DUT Informatique semestre 2"
|
) # eg "DUT Informatique semestre 2"
|
||||||
|
|
||||||
sem["dateord"] = ndb.DateDMYtoISO(sem["date_debut"])
|
|
||||||
sem["date_debut_iso"] = ndb.DateDMYtoISO(sem["date_debut"])
|
sem["date_debut_iso"] = ndb.DateDMYtoISO(sem["date_debut"])
|
||||||
sem["date_fin_iso"] = ndb.DateDMYtoISO(sem["date_fin"])
|
sem["date_fin_iso"] = ndb.DateDMYtoISO(sem["date_fin"])
|
||||||
|
sem["dateord"] = sem["date_debut_iso"] # pour les tris
|
||||||
try:
|
try:
|
||||||
mois_debut, annee_debut = sem["date_debut"].split("/")[1:]
|
mois_debut, annee_debut = sem["date_debut"].split("/")[1:]
|
||||||
except:
|
except:
|
||||||
|
@ -39,12 +39,14 @@ from operator import itemgetter
|
|||||||
from flask import url_for, g, request
|
from flask import url_for, g, request
|
||||||
import pydot
|
import pydot
|
||||||
|
|
||||||
|
from app.but import jury_but
|
||||||
from app.comp import res_sem
|
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, ScolarAutorisationInscription
|
from app.models import FormSemestre, ScolarAutorisationInscription
|
||||||
|
from app.models import FormationModalite
|
||||||
|
from app.models.etudiants import Identite
|
||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.models import FormationModalite
|
|
||||||
from app.scodoc import notesdb as ndb
|
from app.scodoc import notesdb as ndb
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_codes_parcours
|
from app.scodoc import sco_codes_parcours
|
||||||
@ -52,6 +54,7 @@ from app.scodoc import sco_etud
|
|||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
from app.scodoc import sco_formsemestre_inscriptions
|
from app.scodoc import sco_formsemestre_inscriptions
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
|
from app.scodoc import sco_pvjury
|
||||||
import sco_version
|
import sco_version
|
||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
from app import log
|
from app import log
|
||||||
@ -59,17 +62,28 @@ from app.scodoc.sco_codes_parcours import code_semestre_validant
|
|||||||
|
|
||||||
MAX_ETUD_IN_DESCR = 20
|
MAX_ETUD_IN_DESCR = 20
|
||||||
|
|
||||||
|
LEGENDES_CODES_BUT = {
|
||||||
|
"Nb_rcue_valides": "nb RCUE validés",
|
||||||
|
"decision_annee": "code jury annuel BUT",
|
||||||
|
}
|
||||||
|
|
||||||
def formsemestre_etuds_stats(sem, only_primo=False):
|
|
||||||
|
def formsemestre_etuds_stats(sem: dict, only_primo=False):
|
||||||
"""Récupère liste d'etudiants avec etat et decision."""
|
"""Récupère liste d'etudiants avec etat et decision."""
|
||||||
formsemestre = FormSemestre.query.get_or_404(sem["formsemestre_id"])
|
formsemestre: FormSemestre = FormSemestre.query.get_or_404(sem["formsemestre_id"])
|
||||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||||
|
|
||||||
T = nt.get_table_moyennes_triees()
|
T = nt.get_table_moyennes_triees()
|
||||||
|
|
||||||
|
# Décisions de jury BUT pour les semestres pairs seulement
|
||||||
|
jury_but_mode = (
|
||||||
|
formsemestre.formation.is_apc() and formsemestre.semestre_id % 2 == 0
|
||||||
|
)
|
||||||
# Construit liste d'étudiants du semestre avec leur decision
|
# Construit liste d'étudiants du semestre avec leur decision
|
||||||
etuds = []
|
etuds = []
|
||||||
for t in T:
|
for t in T:
|
||||||
etudid = t[-1]
|
etudid = t[-1]
|
||||||
|
etudiant: Identite = Identite.query.get(etudid)
|
||||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
||||||
decision = nt.get_etud_decision_sem(etudid)
|
decision = nt.get_etud_decision_sem(etudid)
|
||||||
if decision:
|
if decision:
|
||||||
@ -87,6 +101,11 @@ def formsemestre_etuds_stats(sem, only_primo=False):
|
|||||||
autorisations.sort()
|
autorisations.sort()
|
||||||
autorisations_str = ", ".join(autorisations)
|
autorisations_str = ", ".join(autorisations)
|
||||||
etud["devenir"] = autorisations_str
|
etud["devenir"] = autorisations_str
|
||||||
|
# Décisions de jury BUT (APC)
|
||||||
|
if jury_but_mode:
|
||||||
|
deca = jury_but.DecisionsProposeesAnnee(etudiant, formsemestre)
|
||||||
|
etud["nb_rcue_valides"] = deca.nb_rcue_valides
|
||||||
|
etud["decision_annee"] = deca.code_valide
|
||||||
# Ajout clé 'bac-specialite'
|
# Ajout clé 'bac-specialite'
|
||||||
bs = []
|
bs = []
|
||||||
if etud["bac"]:
|
if etud["bac"]:
|
||||||
@ -100,13 +119,22 @@ def formsemestre_etuds_stats(sem, only_primo=False):
|
|||||||
return etuds
|
return etuds
|
||||||
|
|
||||||
|
|
||||||
def is_primo_etud(etud, sem):
|
def is_primo_etud(etud: dict, sem: dict):
|
||||||
"""Determine si un (filled) etud a ete inscrit avant ce semestre.
|
"""Determine si un (filled) etud a été inscrit avant ce semestre.
|
||||||
Regarde la liste des semestres dans lesquels l'étudiant est inscrit
|
Regarde la liste des semestres dans lesquels l'étudiant est inscrit.
|
||||||
|
Si semestre pair, considère comme primo-entrants ceux qui étaient
|
||||||
|
primo dans le précédent (S_{2n-1}).
|
||||||
"""
|
"""
|
||||||
now = sem["dateord"]
|
debut_cur = sem["date_debut_iso"]
|
||||||
|
# si semestre impair et sem. précédent contigu, recule date debut
|
||||||
|
if (
|
||||||
|
(len(etud["sems"]) > 1)
|
||||||
|
and (sem["semestre_id"] % 2 == 0)
|
||||||
|
and (etud["sems"][1]["semestre_id"] == (sem["semestre_id"] - 1))
|
||||||
|
):
|
||||||
|
debut_cur = etud["sems"][1]["date_debut_iso"]
|
||||||
for s in etud["sems"]: # le + recent d'abord
|
for s in etud["sems"]: # le + recent d'abord
|
||||||
if s["dateord"] < now:
|
if s["date_debut_iso"] < debut_cur:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -176,21 +204,20 @@ def _results_by_category(
|
|||||||
|
|
||||||
# ajout titre ligne:
|
# ajout titre ligne:
|
||||||
for (cat, l) in zip(categories, C):
|
for (cat, l) in zip(categories, C):
|
||||||
l["row_title"] = cat or "?"
|
l["row_title"] = cat if cat is not None else "?"
|
||||||
|
|
||||||
#
|
#
|
||||||
codes.append("sum")
|
codes.append("sum")
|
||||||
codes.append("sumpercent")
|
codes.append("sumpercent")
|
||||||
|
|
||||||
# on veut { ADM : ADM, ... }, était peu elegant en python 2.3:
|
# on veut { ADM : ADM, ... }
|
||||||
# titles = {}
|
|
||||||
# map( lambda x,titles=titles: titles.__setitem__(x[0],x[1]), zip(codes,codes) )
|
|
||||||
# Version moderne:
|
|
||||||
titles = {x: x for x in codes}
|
titles = {x: x for x in codes}
|
||||||
|
# sauf pour
|
||||||
|
titles.update(LEGENDES_CODES_BUT)
|
||||||
titles["sum"] = "Total"
|
titles["sum"] = "Total"
|
||||||
titles["sumpercent"] = "%"
|
titles["sumpercent"] = "%"
|
||||||
titles["DEM"] = "Dém." # démissions
|
titles["DEM"] = "Dém." # démissions
|
||||||
titles["row_title"] = category_name
|
titles["row_title"] = titles.get(category_name, category_name)
|
||||||
return GenTable(
|
return GenTable(
|
||||||
titles=titles,
|
titles=titles,
|
||||||
columns_ids=codes,
|
columns_ids=codes,
|
||||||
@ -234,14 +261,11 @@ def formsemestre_report(
|
|||||||
#
|
#
|
||||||
tab.filename = scu.make_filename("stats " + sem["titreannee"])
|
tab.filename = scu.make_filename("stats " + sem["titreannee"])
|
||||||
|
|
||||||
tab.origin = (
|
tab.origin = f"Généré par {sco_version.SCONAME} le {scu.timedate_human_repr()}"
|
||||||
"Généré par %s le " % sco_version.SCONAME + scu.timedate_human_repr() + ""
|
tab.caption = (
|
||||||
|
f"Répartition des résultats par {category_name}, semestre {sem['titreannee']}"
|
||||||
)
|
)
|
||||||
tab.caption = "Répartition des résultats par %s, semestre %s" % (
|
tab.html_caption = f"Répartition des résultats par {category_name}."
|
||||||
category_name,
|
|
||||||
sem["titreannee"],
|
|
||||||
)
|
|
||||||
tab.html_caption = "Répartition des résultats par %s." % category_name
|
|
||||||
tab.base_url = "%s?formsemestre_id=%s" % (request.base_url, formsemestre_id)
|
tab.base_url = "%s?formsemestre_id=%s" % (request.base_url, formsemestre_id)
|
||||||
if only_primo:
|
if only_primo:
|
||||||
tab.base_url += "&only_primo=on"
|
tab.base_url += "&only_primo=on"
|
||||||
@ -265,17 +289,32 @@ def formsemestre_report(
|
|||||||
|
|
||||||
|
|
||||||
def formsemestre_report_counts(
|
def formsemestre_report_counts(
|
||||||
formsemestre_id,
|
formsemestre_id: int,
|
||||||
format="html",
|
format="html",
|
||||||
category="bac",
|
category: str = "bac",
|
||||||
result="codedecision",
|
result: str = None,
|
||||||
allkeys=False,
|
allkeys: bool = False,
|
||||||
only_primo=False,
|
only_primo: bool = False,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Tableau comptage avec choix des categories
|
Tableau comptage avec choix des categories
|
||||||
|
category: attribut en lignes
|
||||||
|
result: attribut en colonnes
|
||||||
|
only_primo: restreint aux primo-entrants (= non redoublants)
|
||||||
|
allkeys: pour le menu du choix de l'attribut en colonnes:
|
||||||
|
si vrai, toutes les valeurs présentes dans les données
|
||||||
|
sinon liste prédéfinie (voir ci-dessous)
|
||||||
"""
|
"""
|
||||||
|
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||||
|
# Décisions de jury BUT pour les semestres pairs seulement
|
||||||
|
jury_but_mode = (
|
||||||
|
formsemestre.formation.is_apc() and formsemestre.semestre_id % 2 == 0
|
||||||
|
)
|
||||||
|
|
||||||
|
if result is None:
|
||||||
|
result = "statut" if formsemestre.formation.is_apc() else "codedecision"
|
||||||
|
|
||||||
category_name = category.capitalize()
|
category_name = category.capitalize()
|
||||||
title = "Comptages " + category_name
|
title = "Comptages " + category_name
|
||||||
etuds = formsemestre_etuds_stats(sem, only_primo=only_primo)
|
etuds = formsemestre_etuds_stats(sem, only_primo=only_primo)
|
||||||
@ -311,6 +350,8 @@ def formsemestre_report_counts(
|
|||||||
"type_admission",
|
"type_admission",
|
||||||
"boursier_prec",
|
"boursier_prec",
|
||||||
]
|
]
|
||||||
|
if jury_but_mode:
|
||||||
|
keys += ["nb_rcue_valides", "decision_annee"]
|
||||||
keys.sort(key=scu.heterogeneous_sorting_key)
|
keys.sort(key=scu.heterogeneous_sorting_key)
|
||||||
F = [
|
F = [
|
||||||
"""<form name="f" method="get" action="%s"><p>
|
"""<form name="f" method="get" action="%s"><p>
|
||||||
@ -322,7 +363,10 @@ def formsemestre_report_counts(
|
|||||||
selected = "selected"
|
selected = "selected"
|
||||||
else:
|
else:
|
||||||
selected = ""
|
selected = ""
|
||||||
F.append('<option value="%s" %s>%s</option>' % (k, selected, k))
|
F.append(
|
||||||
|
'<option value="%s" %s>%s</option>'
|
||||||
|
% (k, selected, LEGENDES_CODES_BUT.get(k, k))
|
||||||
|
)
|
||||||
F.append("</select>")
|
F.append("</select>")
|
||||||
F.append(' Lignes: <select name="category" onchange="document.f.submit()">')
|
F.append(' Lignes: <select name="category" onchange="document.f.submit()">')
|
||||||
for k in keys:
|
for k in keys:
|
||||||
@ -330,7 +374,10 @@ def formsemestre_report_counts(
|
|||||||
selected = "selected"
|
selected = "selected"
|
||||||
else:
|
else:
|
||||||
selected = ""
|
selected = ""
|
||||||
F.append('<option value="%s" %s>%s</option>' % (k, selected, k))
|
F.append(
|
||||||
|
'<option value="%s" %s>%s</option>'
|
||||||
|
% (k, selected, LEGENDES_CODES_BUT.get(k, k))
|
||||||
|
)
|
||||||
F.append("</select>")
|
F.append("</select>")
|
||||||
if only_primo:
|
if only_primo:
|
||||||
checked = 'checked="1"'
|
checked = 'checked="1"'
|
||||||
|
Loading…
Reference in New Issue
Block a user