forked from ScoDoc/ScoDoc
BUT: Calcul des UEs à valider par parcour. WIP: tets unitaire écrit mais ne passe pas (manque assoc UE à plusieurs parcours)
This commit is contained in:
parent
1a3ac62f24
commit
3a051672c3
@ -16,6 +16,7 @@ from app.comp.res_compat import NotesTableCompat
|
|||||||
from app.comp.bonus_spo import BonusSport
|
from app.comp.bonus_spo import BonusSport
|
||||||
from app.models import ScoDocSiteConfig
|
from app.models import ScoDocSiteConfig
|
||||||
from app.models.moduleimpls import ModuleImpl
|
from app.models.moduleimpls import ModuleImpl
|
||||||
|
from app.models.but_refcomp import ApcParcours, ApcNiveau
|
||||||
from app.models.ues import DispenseUE, UniteEns
|
from app.models.ues import DispenseUE, UniteEns
|
||||||
from app.models.but_validations import ApcValidationAnnee, ApcValidationRCUE
|
from app.models.but_validations import ApcValidationAnnee, ApcValidationRCUE
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
@ -41,6 +42,8 @@ class ResultatsSemestreBUT(NotesTableCompat):
|
|||||||
"""ndarray (etuds x modimpl x ue)"""
|
"""ndarray (etuds x modimpl x ue)"""
|
||||||
self.etuds_parcour_id = None
|
self.etuds_parcour_id = None
|
||||||
"""Parcours de chaque étudiant { etudid : parcour_id }"""
|
"""Parcours de chaque étudiant { etudid : parcour_id }"""
|
||||||
|
self.ues_ids_by_parcour: dict[set[int]] = {}
|
||||||
|
"""{ parcour_id : set }, ue_id de chaque parcours"""
|
||||||
|
|
||||||
if not self.load_cached():
|
if not self.load_cached():
|
||||||
t0 = time.time()
|
t0 = time.time()
|
||||||
@ -259,10 +262,43 @@ class ResultatsSemestreBUT(NotesTableCompat):
|
|||||||
def etud_ues_ids(self, etudid: int) -> list[int]:
|
def etud_ues_ids(self, etudid: int) -> list[int]:
|
||||||
"""Liste des id d'UE auxquelles l'étudiant est inscrit (sans bonus).
|
"""Liste des id d'UE auxquelles l'étudiant est inscrit (sans bonus).
|
||||||
(surchargée ici pour prendre en compte les parcours)
|
(surchargée ici pour prendre en compte les parcours)
|
||||||
|
Ne prend pas en compte les éventuelles DispenseUE (pour le moment ?)
|
||||||
"""
|
"""
|
||||||
s = self.ues_inscr_parcours_df.loc[etudid]
|
s = self.ues_inscr_parcours_df.loc[etudid]
|
||||||
return s.index[s.notna()]
|
return s.index[s.notna()]
|
||||||
|
|
||||||
|
def etud_parcours_ues_ids(self, etudid: int) -> set[int]:
|
||||||
|
"""Ensemble les id des UEs que l'étudiant doit valider dans ce semestre compte tenu
|
||||||
|
du parcours dans lequel il est inscrit.
|
||||||
|
Se base sur le parcours dans ce semestre, et le référentiel de compétences.
|
||||||
|
Note: il n'est pas nécessairement inscrit à toutes ces UEs.
|
||||||
|
Ensemble vide si pas de référentiel.
|
||||||
|
|
||||||
|
La requête est longue, les ue_ids par parcour sont donc cachés.
|
||||||
|
"""
|
||||||
|
parcour_id = self.etuds_parcour_id[etudid]
|
||||||
|
if parcour_id in self.ues_ids_by_parcour: # cache
|
||||||
|
return self.ues_ids_by_parcour[parcour_id]
|
||||||
|
# Hors cache:
|
||||||
|
ref_comp = self.formsemestre.formation.referentiel_competence
|
||||||
|
if ref_comp is None:
|
||||||
|
return set()
|
||||||
|
parcour: ApcParcours = ApcParcours.query.get(parcour_id)
|
||||||
|
annee = (self.formsemestre.semestre_id + 1) // 2
|
||||||
|
niveaux = ApcNiveau.niveaux_annee_de_parcours(parcour, annee, ref_comp)
|
||||||
|
# Les UEs du formsemestre associées à ces niveaux:
|
||||||
|
ues_parcour = self.formsemestre.formation.query_ues_parcour(parcour)
|
||||||
|
ues_ids = set()
|
||||||
|
for niveau in niveaux:
|
||||||
|
ue = ues_parcour.filter_by(niveau_competence=niveau).first()
|
||||||
|
if ue:
|
||||||
|
ues_ids.add(ue.id)
|
||||||
|
|
||||||
|
# memoize
|
||||||
|
self.ues_ids_by_parcour[parcour_id] = ues_ids
|
||||||
|
|
||||||
|
return ues_ids
|
||||||
|
|
||||||
def etud_has_decision(self, etudid):
|
def etud_has_decision(self, etudid):
|
||||||
"""True s'il y a une décision de jury pour cet étudiant émanant de ce formsemestre.
|
"""True s'il y a une décision de jury pour cet étudiant émanant de ce formsemestre.
|
||||||
prend aussi en compte les autorisations de passage.
|
prend aussi en compte les autorisations de passage.
|
||||||
|
@ -125,6 +125,13 @@ class ResultatsSemestre(ResultatsCache):
|
|||||||
# car tous les étudiants sont inscrits à toutes les UE
|
# car tous les étudiants sont inscrits à toutes les UE
|
||||||
return [ue.id for ue in self.ues if ue.type != UE_SPORT]
|
return [ue.id for ue in self.ues if ue.type != UE_SPORT]
|
||||||
|
|
||||||
|
def etud_parcours_ues_ids(self, etudid: int) -> set[int]:
|
||||||
|
"""Ensemble des UEs que l'étudiant "doit" valider.
|
||||||
|
En formations classiques, c'est la même chose (en set) que etud_ues_ids.
|
||||||
|
Surchargée en BUT pour donner les UEs du parcours de l'étudiant.
|
||||||
|
"""
|
||||||
|
return {ue.id for ue in self.ues if ue.type != UE_SPORT}
|
||||||
|
|
||||||
def etud_ues(self, etudid: int) -> Generator[UniteEns]:
|
def etud_ues(self, etudid: int) -> Generator[UniteEns]:
|
||||||
"""Liste des UE auxquelles l'étudiant est inscrit
|
"""Liste des UE auxquelles l'étudiant est inscrit
|
||||||
(sans bonus, en BUT prend en compte le parcours de l'étudiant)."""
|
(sans bonus, en BUT prend en compte le parcours de l'étudiant)."""
|
||||||
|
@ -214,7 +214,6 @@ class ApcReferentielCompetences(db.Model, XMLModel):
|
|||||||
"""
|
"""
|
||||||
parcours_info = {}
|
parcours_info = {}
|
||||||
for parcour in self.parcours:
|
for parcour in self.parcours:
|
||||||
print(f"# Parcours {parcour.code}")
|
|
||||||
descr_parcour = {}
|
descr_parcour = {}
|
||||||
parcours_info[parcour.id] = descr_parcour
|
parcours_info[parcour.id] = descr_parcour
|
||||||
for annee in (1, 2, 3):
|
for annee in (1, 2, 3):
|
||||||
|
@ -676,7 +676,7 @@ class RowRecap(tb.Row):
|
|||||||
# Les moyennes des modules (ou ressources et SAÉs) dans cette UE
|
# Les moyennes des modules (ou ressources et SAÉs) dans cette UE
|
||||||
self.add_ue_modimpls_cols(ue, ue_status["is_capitalized"])
|
self.add_ue_modimpls_cols(ue, ue_status["is_capitalized"])
|
||||||
|
|
||||||
self.nb_ues_etud_parcours = len(res.etud_ues_ids(etud.id))
|
self.nb_ues_etud_parcours = len(res.etud_parcours_ues_ids(etud.id))
|
||||||
ue_valid_txt = (
|
ue_valid_txt = (
|
||||||
ue_valid_txt_html
|
ue_valid_txt_html
|
||||||
) = f"{self.nb_ues_validables}/{self.nb_ues_etud_parcours}"
|
) = f"{self.nb_ues_validables}/{self.nb_ues_etud_parcours}"
|
||||||
|
@ -79,15 +79,44 @@ Formation:
|
|||||||
# S5 Parcours BAT + TP
|
# S5 Parcours BAT + TP
|
||||||
'UE5.1': # Parcours BAT seulement
|
'UE5.1': # Parcours BAT seulement
|
||||||
annee: BUT3
|
annee: BUT3
|
||||||
|
parcours: BAT # + RAPEB, BEC
|
||||||
competence: "Solutions Bâtiment"
|
competence: "Solutions Bâtiment"
|
||||||
'UE5.2': # Parcours TP seulement
|
'UE5.2': # Parcours TP seulement
|
||||||
annee: BUT3
|
annee: BUT3
|
||||||
|
parcours: TP # + BEC
|
||||||
competence: "Solutions TP"
|
competence: "Solutions TP"
|
||||||
|
'UE5.3':
|
||||||
|
annee: BUT3
|
||||||
|
parcours: RAPEB # + BEC
|
||||||
|
competence: "Dimensionner"
|
||||||
'UE5.4':
|
'UE5.4':
|
||||||
annee: BUT3
|
annee: BUT3
|
||||||
|
parcours: BAT # + TP
|
||||||
competence: Organiser
|
competence: Organiser
|
||||||
'UE5.5':
|
'UE5.5':
|
||||||
annee: BUT3
|
annee: BUT3
|
||||||
|
parcours: BAT # + TP
|
||||||
|
competence: Piloter
|
||||||
|
# S6 Parcours BAT + TP
|
||||||
|
'UE6.1': # Parcours BAT seulement
|
||||||
|
annee: BUT3
|
||||||
|
parcours: BAT # + RAPEB, BEC
|
||||||
|
competence: "Solutions Bâtiment"
|
||||||
|
'UE6.2': # Parcours TP seulement
|
||||||
|
annee: BUT3
|
||||||
|
parcours: TP # + BEC
|
||||||
|
competence: "Solutions TP"
|
||||||
|
'UE6.3':
|
||||||
|
annee: BUT3
|
||||||
|
parcours: RAPEB # + BEC
|
||||||
|
competence: "Dimensionner"
|
||||||
|
'UE6.4':
|
||||||
|
annee: BUT3
|
||||||
|
parcours: BAT # + TP
|
||||||
|
competence: Organiser
|
||||||
|
'UE6.5':
|
||||||
|
annee: BUT3
|
||||||
|
parcours: BAT # + TP
|
||||||
competence: Piloter
|
competence: Piloter
|
||||||
|
|
||||||
modules_parcours:
|
modules_parcours:
|
||||||
@ -157,7 +186,7 @@ Etudiants:
|
|||||||
|
|
||||||
S5:
|
S5:
|
||||||
parcours: BAT
|
parcours: BAT
|
||||||
dispense_ues: ['UE5.2']
|
dispense_ues: ['UE5.2', 'UE5.3']
|
||||||
notes_modules:
|
notes_modules:
|
||||||
"R5.01": 15 # toutes UE
|
"R5.01": 15 # toutes UE
|
||||||
"SAÉ 5.BAT.01": 10 # UE5.1
|
"SAÉ 5.BAT.01": 10 # UE5.1
|
||||||
@ -188,7 +217,7 @@ Etudiants:
|
|||||||
|
|
||||||
S5:
|
S5:
|
||||||
parcours: TP
|
parcours: TP
|
||||||
dispense_ues: ['UE5.1']
|
dispense_ues: ['UE5.1', 'UE5.3']
|
||||||
notes_modules:
|
notes_modules:
|
||||||
"R5.01": 15 # toutes UE
|
"R5.01": 15 # toutes UE
|
||||||
"SAÉ 5.BAT.01": 10 # UE5.1
|
"SAÉ 5.BAT.01": 10 # UE5.1
|
||||||
|
@ -24,7 +24,7 @@ from tests.unit import yaml_setup, yaml_setup_but
|
|||||||
|
|
||||||
import app
|
import app
|
||||||
from app.but.jury_but_validation_auto import formsemestre_validation_auto_but
|
from app.but.jury_but_validation_auto import formsemestre_validation_auto_but
|
||||||
from app.models import FormSemestre
|
from app.models import Formation, FormSemestre
|
||||||
from config import TestConfig
|
from config import TestConfig
|
||||||
|
|
||||||
DEPT = TestConfig.DEPT_TEST
|
DEPT = TestConfig.DEPT_TEST
|
||||||
@ -124,3 +124,23 @@ def test_but_jury_GCCD_CY(test_client):
|
|||||||
formsemestres = FormSemestre.query.order_by(
|
formsemestres = FormSemestre.query.order_by(
|
||||||
FormSemestre.date_debut, FormSemestre.semestre_id
|
FormSemestre.date_debut, FormSemestre.semestre_id
|
||||||
).all()
|
).all()
|
||||||
|
|
||||||
|
formation: Formation = formsemestres[0].formation
|
||||||
|
# Vérifie les UEs du parcours BAT
|
||||||
|
parcour_BAT = formation.referentiel_competence.parcours.filter_by(
|
||||||
|
code="BAT"
|
||||||
|
).first()
|
||||||
|
assert parcour_BAT
|
||||||
|
# check le nombre d'UE dans chaque semestre BUT:
|
||||||
|
assert [
|
||||||
|
len(formation.query_ues_parcour(parcour_BAT).filter_by(semestre_idx=i).all())
|
||||||
|
for i in range(1, 7)
|
||||||
|
] == [5, 5, 5, 5, 3, 3]
|
||||||
|
# Vérifie les UEs du parcours TP
|
||||||
|
parcour_TP = formation.referentiel_competence.parcours.filter_by(code="TP").first()
|
||||||
|
assert parcour_TP
|
||||||
|
# check le nombre d'UE dans chaque semestre BUT:
|
||||||
|
assert [
|
||||||
|
len(formation.query_ues_parcour(parcour_TP).filter_by(semestre_idx=i).all())
|
||||||
|
for i in range(1, 7)
|
||||||
|
] == [5, 5, 5, 5, 3, 3]
|
||||||
|
Loading…
Reference in New Issue
Block a user