2024-01-20 09:31:02 +01:00
# -*- mode: python -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# Gestion scolarite IUT
#
# Copyright (c) 1999 - 2024 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
#
##############################################################################
##############################################################################
# Module "Avis de poursuite d'étude"
# conçu et développé par Cléo Baras (IUT de Grenoble)
##############################################################################
"""
Created on 17 / 01 / 2024
@author : barasc
"""
2024-01-25 17:17:01 +01:00
import app . pe . pe_comp as pe_comp
2024-01-20 09:31:02 +01:00
from app . models import FormSemestre , Identite
2024-01-25 17:17:01 +01:00
from app . pe . pe_comp import pe_print
2024-01-20 09:31:02 +01:00
class EtudiantsJuryPE :
""" Classe centralisant la gestion des étudiants à prendre en compte dans un jury de PE """
2024-01-23 18:44:44 +01:00
def __init__ ( self , annee_diplome : int ) :
"""
Args :
annee_diplome : L ' année de diplomation
"""
self . annee_diplome = annee_diplome
2024-01-20 09:31:02 +01:00
2024-01-21 18:55:21 +01:00
" Les identités des étudiants traités pour le jury "
2024-01-20 09:31:02 +01:00
self . identites = { } # ex. ETUDINFO_DICT
2024-01-24 15:37:50 +01:00
" Les cursus (semestres suivis, abandons) des étudiants "
2024-01-20 09:31:02 +01:00
self . cursus = { }
2024-01-23 09:05:52 +01:00
""" Les aggrégats des semestres suivis (par ex: 3S=S1+S2+S3 à prendre en compte avec d ' éventuels redoublements) des étudiants """
2024-01-24 15:37:50 +01:00
self . trajectoires = { }
2024-01-21 18:55:21 +01:00
" Les etudids des étudiants à considérer au jury (ceux qui seront effectivement diplômés) "
2024-01-24 19:37:45 +01:00
self . etudiants_diplomes = { }
2024-01-23 09:05:52 +01:00
self . diplomes_ids = { }
2024-01-24 19:37:45 +01:00
2024-01-21 18:55:21 +01:00
" Les etudids des étudiants dont il faut calculer les moyennes/classements (même si d ' éventuels abandons) "
2024-01-20 09:31:02 +01:00
self . etudiants_ids = { }
2024-01-25 21:54:22 +01:00
""" Les étudiants inscrits dans les co-semestres (ceux du jury mais aussi d ' autres ayant été réorientés ou ayant abandonnés) """
self . cosemestres : dict [ int , FormSemestre ] = None
" Les cosemestres donnant lieu à même année de diplome "
2024-01-21 18:55:21 +01:00
2024-01-23 18:44:44 +01:00
def find_etudiants ( self , formation_id : int ) :
2024-01-20 09:31:02 +01:00
""" Liste des étudiants à prendre en compte dans le jury PE, en les recherchant
de manière automatique par rapport à leur année de diplomation ` ` annee_diplome ` `
2024-01-25 21:54:22 +01:00
dans la formation ` ` formation_id ` ` . XXX TODO voir si on garde formation_id qui n ' est pas utilisé ici
2024-01-20 09:31:02 +01:00
Les données obtenues sont stockées dans les attributs de EtudiantsJuryPE .
2024-01-23 18:44:44 +01:00
2024-01-21 18:55:21 +01:00
formation_id : L ' identifiant de la formation (inutilisé)
2024-01-20 09:31:02 +01:00
* Remarque * : ex : JuryPE . get_etudiants_in_jury ( )
"""
2024-01-25 17:17:01 +01:00
cosemestres = pe_comp . get_cosemestres_diplomants ( self . annee_diplome , None )
2024-01-23 09:54:30 +01:00
self . cosemestres = cosemestres
2024-01-20 09:31:02 +01:00
2024-01-25 21:54:22 +01:00
pe_comp . pe_print ( f " 1) Recherche des coSemestres -> { len ( cosemestres ) } trouvés " )
2024-01-25 17:17:01 +01:00
pe_comp . pe_print ( " 2) Liste des étudiants dans les différents co-semestres " )
2024-01-21 18:55:21 +01:00
self . etudiants_ids = get_etudiants_dans_semestres ( cosemestres )
2024-01-25 17:17:01 +01:00
pe_comp . pe_print (
2024-01-21 18:55:21 +01:00
" => %d étudiants trouvés dans les cosemestres " % len ( self . etudiants_ids )
)
2024-01-20 09:31:02 +01:00
2024-01-25 21:54:22 +01:00
""" Analyse des parcours étudiants pour déterminer leur année effective de diplome
2024-01-21 18:55:21 +01:00
avec prise en compte des redoublements , des abandons , . . . . """
2024-01-25 17:17:01 +01:00
pe_comp . pe_print ( " 3) Analyse des parcours individuels des étudiants " )
2024-01-20 09:31:02 +01:00
no_etud = 0
2024-01-20 16:34:38 +01:00
for no_etud , etudid in enumerate ( self . etudiants_ids ) :
2024-01-21 18:55:21 +01:00
""" L ' identité de l ' étudiant """
identite = Identite . get_etud ( etudid )
self . identites [ etudid ] = identite
""" L ' analyse de son cursus """
self . analyse_etat_etudiant ( etudid , cosemestres )
""" L ' analyse de son parcours pour atteindre chaque semestre de la formation """
2024-01-24 15:37:50 +01:00
self . structure_cursus_etudiant ( etudid )
2024-01-21 18:55:21 +01:00
2024-01-20 09:31:02 +01:00
if ( no_etud + 1 ) % 10 == 0 :
2024-01-25 19:54:39 +01:00
pe_comp . pe_print ( f " { no_etud + 1 } " )
2024-01-20 09:31:02 +01:00
no_etud + = 1
2024-01-25 17:17:01 +01:00
pe_comp . pe_print ( )
2024-01-20 09:31:02 +01:00
""" Les étudiants à prendre dans le diplôme, étudiants ayant abandonnés non compris """
2024-01-24 19:37:45 +01:00
self . etudiants_diplomes = self . get_etudiants_diplomes ( )
self . diplomes_ids = set ( self . etudiants_diplomes . keys ( ) )
2024-01-20 09:31:02 +01:00
""" Les étudiants dont il faut calculer les moyennes """
2024-01-23 09:54:30 +01:00
self . etudiants_ids = { etudid for etudid in self . identites }
2024-01-20 09:31:02 +01:00
""" Les formsemestres (des étudiants) dont il faut calculer les moyennes """
2024-01-24 15:37:50 +01:00
self . formsemestres_jury_ids = self . get_formsemestres ( )
2024-01-20 09:31:02 +01:00
# Synthèse
2024-01-25 17:17:01 +01:00
pe_comp . pe_print (
2024-01-24 19:37:45 +01:00
f " => { len ( self . etudiants_diplomes ) } étudiants à diplômer en { self . annee_diplome } "
2024-01-20 16:34:38 +01:00
)
2024-01-24 19:37:45 +01:00
nbre_abandons = len ( self . etudiants_ids ) - len ( self . etudiants_diplomes )
2024-01-25 17:17:01 +01:00
pe_comp . pe_print ( f " => { nbre_abandons } étudiants éliminer pour abandon " )
pe_comp . pe_print (
2024-01-23 18:44:44 +01:00
f " => { len ( self . formsemestres_jury_ids ) } semestres dont il faut calculer la moyenne "
)
2024-01-25 17:17:01 +01:00
pe_comp . pe_print (
2024-01-20 16:34:38 +01:00
f " => quelques étudiants futurs diplômés : "
2024-01-24 19:37:45 +01:00
+ " , " . join ( [ str ( etudid ) for etudid in list ( self . etudiants_diplomes ) [ : 10 ] ] )
2024-01-20 16:34:38 +01:00
)
2024-01-25 17:17:01 +01:00
pe_comp . pe_print (
2024-01-20 16:34:38 +01:00
f " => semestres dont il faut calculer les moyennes : "
+ " , " . join ( [ str ( fid ) for fid in list ( self . formsemestres_jury_ids ) ] )
)
2024-01-23 18:44:44 +01:00
# Les abandons :
2024-01-25 21:54:22 +01:00
self . abandons = sorted (
[
self . cursus [ etudid ] [ " nom " ]
for etudid in self . cursus
if etudid not in self . diplomes_ids
]
)
2024-01-20 09:31:02 +01:00
2024-01-23 18:44:44 +01:00
def get_etudiants_diplomes ( self ) - > dict [ int , Identite ] :
2024-01-20 16:34:38 +01:00
""" Identités des étudiants (sous forme d ' un dictionnaire ` { etudid: Identite(etudid)}`
qui vont être à traiter au jury PE pour
l ' année de diplômation donnée et n ' ayant ni été réorienté , ni abandonné .
Returns :
Un dictionnaire ` { etudid : Identite ( etudid ) } `
"""
2024-01-21 18:55:21 +01:00
etudids = [
etudid
for etudid in self . cursus
2024-01-23 18:44:44 +01:00
if self . cursus [ etudid ] [ " diplome " ] == self . annee_diplome
2024-01-23 09:54:30 +01:00
and self . cursus [ etudid ] [ " abandon " ] == False
2024-01-21 18:55:21 +01:00
]
etudiants = { etudid : self . identites [ etudid ] for etudid in etudids }
2024-01-20 16:34:38 +01:00
return etudiants
2024-01-23 09:54:30 +01:00
def analyse_etat_etudiant ( self , etudid : int , cosemestres : dict [ int , FormSemestre ] ) :
2024-01-21 18:55:21 +01:00
""" Analyse le cursus d ' un étudiant pouvant être :
* l ' un de ceux sur lesquels le jury va statuer (année de diplômation du jury considéré)
* un étudiant qui ne sera pas considéré dans le jury mais qui a participé dans sa scolarité
à un ( ou plusieurs ) semestres communs aux étudiants du jury ( et impactera les classements )
2024-01-20 09:31:02 +01:00
2024-01-21 18:55:21 +01:00
L ' analyse consiste :
2024-01-20 09:31:02 +01:00
2024-01-21 18:55:21 +01:00
* à insérer une entrée dans ` ` self . cursus ` ` pour mémoriser son identité ,
2024-01-20 09:31:02 +01:00
avec son nom , prénom , etc . . .
* à analyser son parcours , pour déterminer s ' il n ' a ( ou non ) abandonné l ' IUT en cours de
route ( cf . clé abandon )
Args :
etudid : L ' etudid d ' un étudiant , à ajouter à ceux traiter par le jury
2024-01-21 18:55:21 +01:00
cosemestres : Dictionnaire { fid : Formsemestre ( fid ) } donnant accès aux cosemestres
de même année de diplomation
2024-01-20 09:31:02 +01:00
"""
identite = Identite . get_etud ( etudid )
2024-01-26 09:42:41 +01:00
# Le cursus global de l'étudiant (restreint aux semestres APC)
2024-01-25 17:17:01 +01:00
formsemestres = identite . get_formsemestres ( )
2024-01-20 09:31:02 +01:00
semestres_etudiant = {
2024-01-20 16:34:38 +01:00
frmsem . formsemestre_id : frmsem
2024-01-25 17:17:01 +01:00
for frmsem in formsemestres
2024-01-20 16:34:38 +01:00
if frmsem . formation . is_apc ( )
}
2024-01-20 09:31:02 +01:00
self . cursus [ etudid ] = {
" etudid " : etudid , # les infos sur l'étudiant
" etat_civil " : identite . etat_civil , # Ajout à la table jury
2024-01-23 09:54:30 +01:00
" nom " : identite . nom ,
2024-01-25 21:54:22 +01:00
" entree " : formsemestres [ - 1 ] . date_debut . year , # La date d'entrée à l'IUT
2024-01-20 09:31:02 +01:00
" diplome " : annee_diplome ( identite ) , # Le date prévisionnelle de son diplôme
2024-01-20 16:34:38 +01:00
" formsemestres " : semestres_etudiant , # les semestres de l'étudiant
2024-01-25 21:54:22 +01:00
" nb_semestres " : len (
semestres_etudiant
) , # le nombre de semestres de l'étudiant
2024-01-23 09:54:30 +01:00
" abandon " : False , # va être traité en dessous
2024-01-20 09:31:02 +01:00
}
2024-01-26 09:42:41 +01:00
# Est-il réorienté / démissionnaire ou a-t-il arrêté volontairement sa formation ?
2024-01-20 16:34:38 +01:00
self . cursus [ etudid ] [ " abandon " ] = arret_de_formation ( identite , cosemestres )
2024-01-20 09:31:02 +01:00
2024-01-24 15:37:50 +01:00
def get_semestres_significatifs ( self , etudid : int ) :
""" Ensemble des semestres d ' un étudiant, qui l ' auraient amené à être diplomé
l ' année visée (supprime les semestres qui conduisent à une diplomation
postérieure à celle du jury visé )
2024-01-21 18:55:21 +01:00
2024-01-24 15:37:50 +01:00
Args :
etudid : L ' identifiant d ' un étudiant
2024-01-21 18:55:21 +01:00
2024-01-24 15:37:50 +01:00
Returns :
Un dictionnaire ` ` { fid : FormSemestre ( fid ) ` ` dans lequel les semestres
amènent à une diplomation avant l ' annee de diplomation du jury
2024-01-21 18:55:21 +01:00
"""
2024-01-24 15:37:50 +01:00
semestres_etudiant = self . cursus [ etudid ] [ " formsemestres " ]
2024-01-23 18:44:44 +01:00
semestres_significatifs = { }
for fid in semestres_etudiant :
semestre = semestres_etudiant [ fid ]
2024-01-25 17:17:01 +01:00
if pe_comp . get_annee_diplome_semestre ( semestre ) < = self . annee_diplome :
2024-01-23 18:44:44 +01:00
semestres_significatifs [ fid ] = semestre
2024-01-24 15:37:50 +01:00
return semestres_significatifs
2024-01-23 18:44:44 +01:00
2024-01-24 15:37:50 +01:00
def structure_cursus_etudiant ( self , etudid : int ) :
""" Structure les informations sur les semestres suivis par un
étudiant , pour identifier les semestres qui seront pris en compte lors de ses calculs
de moyennes PE .
Cette structuration s ' appuie sur les numéros de semestre: pour chaque Si, stocke :
le dernier semestre ( en date ) de numéro i qu ' il a suivi (1 ou 0 si pas encore suivi). Ce semestre influera les
interclassement par semestre dans la promo .
"""
semestres_significatifs = self . get_semestres_significatifs ( etudid )
2024-01-23 09:54:30 +01:00
2024-01-23 09:05:52 +01:00
""" Tri des semestres par numéro de semestre """
2024-01-25 17:17:01 +01:00
for nom_sem in pe_comp . TOUS_LES_SEMESTRES :
2024-01-21 18:55:21 +01:00
i = int ( nom_sem [ 1 ] ) # le n° du semestre
2024-01-20 16:34:38 +01:00
semestres_i = {
2024-01-23 18:44:44 +01:00
fid : semestres_significatifs [ fid ]
for fid in semestres_significatifs
if semestres_significatifs [ fid ] . semestre_id == i
2024-01-20 16:34:38 +01:00
} # les semestres de n°i de l'étudiant
2024-01-24 15:37:50 +01:00
self . cursus [ etudid ] [ nom_sem ] = semestres_i
def get_trajectoire ( self , etudid : int , formsemestre_final : FormSemestre ) :
""" Ensemble des semestres parcourus par
un étudiant pour l ' amener à un semestre terminal.
Par ex : si formsemestre_terminal est un S3 , ensemble des S1 ,
S2 , S3 suivi pour l ' amener au S3 (il peut y avoir plusieurs S1,
ou S2 , ou S3 s ' il a redoublé).
Les semestres parcourus sont antérieurs ( en terme de date de fin )
au formsemestre_terminal .
Args :
etudid : L ' identifiant de l ' étudiant
formsemestre_final : le semestre final visé
"""
numero_semestre_terminal = formsemestre_final . semestre_id
semestres_significatifs = self . get_semestres_significatifs ( etudid )
""" Semestres de n° inférieur (pax ex: des S1, S2, S3 pour un S3 terminal) et qui lui sont antérieurs """
semestres_aggreges = { }
for fid in semestres_significatifs :
semestre = semestres_significatifs [ fid ]
if (
semestre . semestre_id < = numero_semestre_terminal
and semestre . date_fin < = formsemestre_final . date_fin
) :
semestres_aggreges [ fid ] = semestre
return semestres_aggreges
2024-01-21 18:55:21 +01:00
def get_formsemestres_terminaux_aggregat ( self , aggregat : str ) :
2024-01-23 18:44:44 +01:00
""" Pour un aggrégat donné, ensemble des formsemestres terminaux possibles pour l ' aggrégat
( pour l ' aggrégat ' 3 S ' incluant S1+S2+S3, a pour semestre terminal S3).
Ces formsemestres traduisent :
2024-01-21 18:55:21 +01:00
* les différents parcours des étudiants liés par exemple au choix de modalité ( par ex : S1 FI + S2 FI + S3 FI
ou S1 FI + S2 FI + S3 UFA ) , en renvoyant les formsemestre_id du S3 FI et du S3 UFA .
* les éventuelles situations de redoublement ( par ex pour 1 étudiant ayant redoublé sa 2 ème année :
S1 + S2 + S3 ( 1 ère session ) et S1 + S2 + S3 + S4 + S3 ( 2 ème session ) , en renvoyant les formsemestre_id du
S3 ( 1 ère session ) et du S3 ( 2 ème session )
Args :
aggregat : L ' aggrégat
Returns :
2024-01-24 15:37:50 +01:00
Un dictionnaire ` ` { fid : FormSemestre ( fid ) } ` `
2024-01-21 18:55:21 +01:00
"""
formsemestres_terminaux = { }
2024-01-24 15:37:50 +01:00
for etudid in self . trajectoires :
if self . trajectoires [ etudid ] [ aggregat ] :
trajectoire = self . trajectoires [ etudid ] [ aggregat ]
""" Le semestre terminal de l ' étudiant de l ' aggrégat """
fid = trajectoire . semestre_final . formsemestre_id
formsemestres_terminaux [ fid ] = trajectoire . semestre_final
2024-01-21 18:55:21 +01:00
return formsemestres_terminaux
2024-01-24 15:37:50 +01:00
def get_formsemestres ( self , semestres_recherches = None ) :
2024-01-20 09:31:02 +01:00
""" Ayant connaissance des étudiants dont il faut calculer les moyennes pour
2024-01-24 15:37:50 +01:00
le jury PE ( attribut ` self . etudiant_ids ) et de leur cursus ( semestres
parcourus ) ,
renvoie un dictionnaire ` ` { fid : FormSemestre ( fid ) } ` `
contenant l ' ensemble des formsemestres de leurs cursus, dont il faudra calculer
la moyenne .
Les formsemestres sont limités à ceux indiqués dans ` ` semestres_recherches ` ` .
2024-01-20 16:34:38 +01:00
Args :
semestres_recherches : Une liste ou une chaine de caractères parmi :
* None : pour obtenir tous les formsemestres du jury
* ' Si ' : pour obtenir les semestres de n ° i ( par ex . ' S1 ' )
* ' iA ' : pour obtenir les semestres de l ' année i (par ex. ' 1 A ' donne [ ' S1 , ' S2 ' ] )
* ' 3S ' , ' 4S ' : pour obtenir les combinaisons de semestres définies par les aggrégats
2024-01-20 09:31:02 +01:00
Returns :
2024-01-24 15:37:50 +01:00
Un dictionnaire de la forme ` ` { fid : FormSemestre ( fid ) } ` `
2024-01-20 16:34:38 +01:00
Remarque :
2024-01-24 15:37:50 +01:00
Une liste de la forme ` ` [ ' Si ' , ' iA ' , . . . ] ` ` ( combinant les formats précédents ) est possible .
2024-01-20 09:31:02 +01:00
"""
2024-01-20 16:34:38 +01:00
if semestres_recherches is None :
""" Appel récursif pour obtenir tous les semestres (validants) """
2024-01-25 17:17:01 +01:00
semestres = self . get_formsemestres ( pe_comp . AGGREGAT_DIPLOMANT )
2024-01-20 16:34:38 +01:00
return semestres
elif isinstance ( semestres_recherches , list ) :
""" Appel récursif sur tous les éléments de la liste """
semestres = { }
for elmt in semestres_recherches :
2024-01-24 15:37:50 +01:00
semestres_elmt = self . get_formsemestres ( elmt )
2024-01-20 16:34:38 +01:00
semestres = semestres | semestres_elmt
return semestres
elif (
isinstance ( semestres_recherches , str )
2024-01-25 17:17:01 +01:00
and semestres_recherches in pe_comp . TOUS_LES_AGGREGATS
2024-01-20 16:34:38 +01:00
) :
""" Cas d ' un aggrégat avec appel récursif sur toutes les entrées de l ' aggrégat """
2024-01-24 15:37:50 +01:00
semestres = self . get_formsemestres (
2024-01-25 17:17:01 +01:00
pe_comp . PARCOURS [ semestres_recherches ] [ " aggregat " ]
2024-01-20 16:34:38 +01:00
)
return semestres
elif (
isinstance ( semestres_recherches , str )
2024-01-25 17:17:01 +01:00
and semestres_recherches in pe_comp . TOUS_LES_SEMESTRES
2024-01-20 16:34:38 +01:00
) :
""" semestres_recherches est un nom de semestre de type S1,
pour une recherche parmi les étudiants à prendre en compte
dans le jury ( diplômé et redoublants non diplômé )
"""
nom_sem = semestres_recherches
semestres = { }
for etudid in self . etudiants_ids :
2024-01-24 15:37:50 +01:00
if self . cursus [ etudid ] [ nom_sem ] :
semestres = semestres | self . cursus [ etudid ] [ nom_sem ]
2024-01-20 16:34:38 +01:00
return semestres
else :
2024-01-24 15:37:50 +01:00
raise ValueError ( " Probleme de paramètres d ' appel dans get_formsemestreids " )
2024-01-20 09:31:02 +01:00
2024-01-25 17:17:01 +01:00
def nbre_etapes_max_diplomes ( self ) :
""" Connaissant les étudiants diplomes du jury PE,
nombre de semestres ( étapes ) maximum suivis par les étudiants du jury .
"""
nbres_semestres = [ ]
for etudid in self . diplomes_ids :
2024-01-25 21:54:22 +01:00
nbres_semestres . append ( self . cursus [ etudid ] [ " nb_semestres " ] )
2024-01-25 17:17:01 +01:00
return max ( nbres_semestres )
2024-01-20 09:31:02 +01:00
2024-01-24 15:37:50 +01:00
def get_etudiants_dans_semestres ( semestres : dict [ int , FormSemestre ] ) - > set :
2024-01-20 09:31:02 +01:00
""" Ensemble d ' identifiants des étudiants (identifiés via leur ``etudid``)
inscrits à l ' un des semestres de la liste de ``semestres``.
Remarque : Les ` ` cosemestres ` ` sont généralement obtenus avec ` ` sco_formsemestre . do_formsemestre_list ( ) ` `
Args :
2024-01-24 15:37:50 +01:00
semestres : Un dictionnaire ` ` { fid : Formsemestre ( fid ) } ` ` donnant un
2024-01-20 09:31:02 +01:00
ensemble d ' identifiant de semestres
Returns :
Un ensemble d ` ` etudid ` `
"""
etudiants_ids = set ( )
2024-01-20 16:34:38 +01:00
for fid , sem in semestres . items ( ) : # pour chacun des semestres de la liste
2024-01-20 09:31:02 +01:00
etudiants_du_sem = { ins . etudid for ins in sem . inscriptions }
pe_print ( f " --> { sem } : { len ( etudiants_du_sem ) } etudiants " )
etudiants_ids = (
etudiants_ids | etudiants_du_sem
) # incluant la suppression des doublons
return etudiants_ids
def annee_diplome ( identite : Identite ) - > int :
2024-01-26 09:42:41 +01:00
""" L ' année de diplôme prévue d ' un étudiant en fonction de ses semestres d ' inscription (pour un BUT).
Les semestres utilisés pour le calcul sont limités à ceux d ' une formation apc.
2024-01-20 09:31:02 +01:00
Args :
identite : L ' identité d ' un étudiant
Returns :
L ' année prévue de sa diplômation
"""
2024-01-26 09:42:41 +01:00
formsemestres_apc = get_semestres_apc ( identite )
2024-01-26 07:13:09 +01:00
2024-01-26 09:42:41 +01:00
if formsemestres_apc :
dates_possibles_diplome : int = [ ]
""" Années de diplômation prédites en fonction des semestres (d ' une formation APC) d ' un étudiant """
for sem_base in formsemestres_apc :
2024-01-26 07:13:09 +01:00
annee = pe_comp . get_annee_diplome_semestre ( sem_base )
if annee :
2024-01-26 09:42:41 +01:00
dates_possibles_diplome . append ( annee )
2024-01-26 07:13:09 +01:00
if dates_possibles_diplome :
return max ( dates_possibles_diplome )
2024-01-26 09:42:41 +01:00
return None
def get_semestres_apc ( identite : Identite ) - > list :
""" Liste des semestres d ' un étudiant qui corresponde à une formation APC.
Args :
identite : L ' identité d ' un étudiant
Returns :
Liste de ` ` FormSemestre ` ` correspondant à une formation APC
"""
semestres = identite . get_formsemestres ( )
semestres_apc = [ ]
for sem in semestres :
if sem . formation . is_apc ( ) :
semestres_apc . append ( sem )
return semestres_apc
2024-01-20 09:31:02 +01:00
2024-01-26 09:42:41 +01:00
def arret_de_formation ( identite : Identite , cosemestres : dict [ int , FormSemestre ] ) - > bool :
2024-01-23 09:05:52 +01:00
""" Détermine si un étudiant a arrêté sa formation. Il peut s ' agir :
* d ' une réorientation à l ' initiative du jury de semestre ou d ' une démission (on pourrait
utiliser les code NAR pour réorienté & DEM pour démissionnaire des résultats du jury renseigné dans la BDD ,
mais pas nécessaire ici )
* d ' un arrêt volontaire : l ' étudiant disparait des listes d ' inscrits (sans pour autant avoir été indiqué NAR ou DEM).
Dans les cas , on considérera que l ' étudiant a arrêté sa formation s ' il n ' est pas dans l ' un des " derniers " cosemestres
( semestres conduisant à la même année de diplômation ) connu dans Scodoc .
2024-01-20 09:31:02 +01:00
2024-01-23 09:05:52 +01:00
Par ex : au moment du jury PE en fin de S5 ( pas de S6 renseigné dans Scodoc ) , l ' étudiant doit appartenir à une
instance des S5 qui conduisent à la diplomation dans l ' année visée. S ' il n ' est que dans un S4, il a sans doute
arrêté . A moins qu ' il ne soit parti à l ' étranger et là , pas de notes .
TODO : : Cas de l ' étranger, à coder/tester
2024-01-20 09:31:02 +01:00
2024-01-23 09:05:52 +01:00
* * Attention * * : Cela suppose que toutes les instances d ' un semestre donné (par ex: toutes les instances de S6
accueillant un étudiant soient créées ; sinon les étudiants non inscrits dans un S6 seront considérés comme
ayant abandonnés )
TODO : : Peut - être à mettre en regard avec les propositions d ' inscriptions d ' étudiants dans un nouveau semestre
Pour chaque étudiant , recherche son dernier semestre en date ( validé ou non ) et
regarde s ' il n ' existe pas parmi les semestres existants dans Scodoc un semestre :
* dont les dates sont postérieures ( en terme de date de début )
* de n ° au moins égal à celui de son dernier semestre valide ( S5 - > S5 ou S5 - > S6 )
dans lequel il aurait pu s ' inscrire mais ne l ' a pas fait .
2024-01-20 09:31:02 +01:00
Args :
identite : L ' identité d ' un étudiant
cosemestres : Les semestres donnant lieu à diplômation ( sans redoublement ) en date du jury
Returns :
Est - il réorienté , démissionnaire ou a - t - il arrêté de son propre chef sa formation ?
2024-01-23 09:05:52 +01:00
TODO : : A reprendre pour le cas des étudiants à l ' étranger
2024-01-23 09:54:30 +01:00
TODO : : A reprendre si BUT avec semestres décalés
2024-01-20 09:31:02 +01:00
"""
2024-01-26 09:42:41 +01:00
# Les semestres APC de l'étudiant
semestres = get_semestres_apc ( identite )
semestres_apc = { sem . semestre_id : sem for sem in semestres }
if not semestres_apc :
return True
# Son dernier semestre APC en date
dernier_formsemestre = get_dernier_semestre_en_date ( semestres_apc )
2024-01-23 09:05:52 +01:00
numero_dernier_formsemestre = dernier_formsemestre . semestre_id
2024-01-26 09:42:41 +01:00
# Les numéro de semestres possible dans lesquels il pourrait s'incrire
## semestre impair => passage de droit en semestre pair suivant (effet de l'annualisation)
2024-01-23 09:54:30 +01:00
if numero_dernier_formsemestre % 2 == 1 :
numeros_possibles = list (
2024-01-25 17:17:01 +01:00
range ( numero_dernier_formsemestre + 1 , pe_comp . NBRE_SEMESTRES_DIPLOMANT )
2024-01-23 09:54:30 +01:00
)
2024-01-26 09:42:41 +01:00
## semestre pair => passage en année supérieure ou redoublement
2024-01-23 09:54:30 +01:00
else : #
numeros_possibles = list (
range (
max ( numero_dernier_formsemestre - 1 , 1 ) ,
2024-01-25 17:17:01 +01:00
pe_comp . NBRE_SEMESTRES_DIPLOMANT ,
2024-01-23 09:54:30 +01:00
)
)
2024-01-20 09:31:02 +01:00
2024-01-26 09:42:41 +01:00
# Y-a-t-il des cosemestres dans lesquels il aurait pu s'incrire ?
2024-01-20 09:31:02 +01:00
formsestres_superieurs_possibles = [ ]
for fid , sem in cosemestres . items ( ) : # Les semestres ayant des inscrits
if (
2024-01-23 09:54:30 +01:00
fid != dernier_formsemestre . formsemestre_id
and sem . semestre_id in numeros_possibles
2024-01-20 09:31:02 +01:00
and sem . date_debut . year > = dernier_formsemestre . date_debut . year
) : # date de debut des semestres possibles postérieur au dernier semestre de l'étudiant et de niveau plus élevé que le dernier semestre valide de l'étudiant
formsestres_superieurs_possibles . append ( fid )
if len ( formsestres_superieurs_possibles ) > 0 :
return True
return False
2024-01-20 16:34:38 +01:00
2024-01-25 17:17:01 +01:00
def get_dernier_semestre_en_date ( semestres : dict [ int , FormSemestre ] ) - > FormSemestre :
2024-01-24 15:37:50 +01:00
""" Renvoie le dernier semestre en **date de fin** d ' un dictionnaire
2024-01-25 17:17:01 +01:00
de semestres ( potentiellement non trié ) de la forme ` ` { fid : FormSemestre ( fid ) } ` ` .
2024-01-20 16:34:38 +01:00
Args :
semestres : Un dictionnaire de semestres
Return :
2024-01-24 15:37:50 +01:00
Le FormSemestre du semestre le plus récent
2024-01-20 16:34:38 +01:00
"""
if semestres :
fid_dernier_semestre = list ( semestres . keys ( ) ) [ 0 ]
2024-01-24 15:37:50 +01:00
dernier_semestre : FormSemestre = semestres [ fid_dernier_semestre ]
2024-01-20 16:34:38 +01:00
for fid in semestres :
2024-01-24 15:37:50 +01:00
if semestres [ fid ] . date_fin > dernier_semestre . date_fin :
dernier_semestre = semestres [ fid ]
2024-01-20 16:34:38 +01:00
return dernier_semestre
else :
2024-01-24 15:37:50 +01:00
return None