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
"""
import app . pe . pe_tools as pe_tools
from app . models import FormSemestre , Identite
from app . pe . pe_tools import pe_print
from app . scodoc import (
sco_etud ,
codes_cursus ,
sco_formsemestre ,
sco_formsemestre_inscriptions ,
sco_report ,
)
import datetime
class EtudiantsJuryPE :
""" Classe centralisant la gestion des étudiants à prendre en compte dans un jury de PE """
def __init__ ( self ) :
""" """
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-23 09:05:52 +01:00
" Les cursus (semestres suivis, abandons, dernier S1, S2, ...) 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 """
self . aggregats = { }
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-23 09:05:52 +01:00
self . diplomes_ids = { }
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-21 18:55:21 +01:00
" Les formsemestres dont il faut calculer les moyennes par tag "
2024-01-20 09:31:02 +01:00
self . formsemestres_jury_ids = { }
def find_etudiants ( self , annee_diplome : int , formation_id : int ) :
""" 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 ` `
dans la formation ` ` formation_id ` ` .
Les données obtenues sont stockées dans les attributs de EtudiantsJuryPE .
Args :
annee_diplome : L ' année de diplomation
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 ( )
"""
" Les cosemestres donnant lieu à même année de diplome "
2024-01-21 18:55:21 +01:00
cosemestres = pe_tools . get_cosemestres_diplomants ( annee_diplome , None )
2024-01-23 09:54:30 +01:00
self . cosemestres = cosemestres
2024-01-20 09:31:02 +01:00
pe_tools . pe_print (
" 1) Recherche des coSemestres -> %d trouvés " % len ( cosemestres )
)
""" Les étudiants inscrits dans les co-semestres (ceux du jury mais aussi d ' autres ayant été réorientés ou ayant abandonnés) """
pe_tools . 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 )
pe_tools . pe_print (
" => %d étudiants trouvés dans les cosemestres " % len ( self . etudiants_ids )
)
2024-01-20 09:31:02 +01:00
2024-01-21 18:55:21 +01:00
""" Analyse des parcours étudiants pour déterminer leur année effective de diplome
avec prise en compte des redoublements , des abandons , . . . . """
2024-01-20 09:31:02 +01:00
pe_tools . pe_print ( " 3) Analyse des parcours individuels des étudiants " )
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 """
self . analyse_parcours_etudiant_dans_semestres ( etudid )
2024-01-20 09:31:02 +01:00
if ( no_etud + 1 ) % 10 == 0 :
pe_tools . pe_print ( ( no_etud + 1 ) , " " , end = " " )
no_etud + = 1
pe_tools . pe_print ( )
""" Les étudiants à prendre dans le diplôme, étudiants ayant abandonnés non compris """
2024-01-23 09:05:52 +01:00
self . diplomes_ids = self . get_etudiants ( annee_diplome )
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 """
self . formsemestres_jury_ids = self . get_formsemestres_jury ( )
# Synthèse
2024-01-20 16:34:38 +01:00
pe_tools . pe_print (
2024-01-23 09:05:52 +01:00
f " => { len ( self . diplomes_ids ) } étudiants à diplômer en { annee_diplome } "
2024-01-20 16:34:38 +01:00
)
2024-01-23 09:54:30 +01:00
nbre_abandons = len ( self . etudiants_ids ) - len ( self . diplomes_ids )
2024-01-20 09:31:02 +01:00
pe_tools . pe_print ( f " => { nbre_abandons } étudiants éliminer pour abandon " )
2024-01-23 09:54:30 +01:00
pe_tools . pe_print ( f " => { len ( self . formsemestres_jury_ids ) } semestres dont il faut calculer la moyenne " )
2024-01-20 16:34:38 +01:00
pe_tools . pe_print (
f " => quelques étudiants futurs diplômés : "
2024-01-23 09:05:52 +01:00
+ " , " . join ( [ str ( etudid ) for etudid in list ( self . diplomes_ids ) [ : 10 ] ] )
2024-01-20 16:34:38 +01:00
)
pe_tools . pe_print (
f " => semestres dont il faut calculer les moyennes : "
+ " , " . join ( [ str ( fid ) for fid in list ( self . formsemestres_jury_ids ) ] )
)
2024-01-20 09:31:02 +01:00
2024-01-21 18:55:21 +01:00
def get_etudiants ( self , annee_diplome : int ) - > dict [ 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é .
Args :
annee_diplome : Année de diplomation visée pour le jury
Returns :
Un dictionnaire ` { etudid : Identite ( etudid ) } `
"""
2024-01-21 18:55:21 +01:00
etudids = [
etudid
for etudid in self . cursus
2024-01-23 09:54:30 +01:00
if self . cursus [ etudid ] [ " diplome " ] == annee_diplome
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-20 16:34:38 +01:00
""" Le cursus global de l ' étudiant (restreint aux semestres APC) """
2024-01-20 09:31:02 +01:00
semestres_etudiant = {
2024-01-20 16:34:38 +01:00
frmsem . formsemestre_id : frmsem
for frmsem in identite . get_formsemestres ( )
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-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-23 09:54:30 +01:00
" abandon " : False , # va être traité en dessous
2024-01-20 09:31:02 +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-21 18:55:21 +01:00
def analyse_parcours_etudiant_dans_semestres ( self , etudid ) :
""" 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 .
2024-01-23 09:05:52 +01:00
Cette structuration ( cf . attribut self . cursus ) 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 .
2024-01-21 18:55:21 +01:00
2024-01-23 09:05:52 +01:00
Elle calcule également sur les aggrégats ( cf . attribut self . aggregats ) :
* pour un semestre de type Si , elle stocke le ( ou les ) formsemestres de numéro i qu ' a suivi un étudiant
( 2 si redoublant ) dans self . aggregats
* pour des aggrégats de type iS ou iA ( par ex , 3 A = S1 + S2 + S3 ) , elle identifie les semestres que l ' étudiant
a suivi pour l ' amener jusqu ' au semestre terminal de l ' aggrégat. Ce parcours peut être :
* * S1 + S2 + S1 + S2 + S3 si redoublement de la 1 ère année
* * S1 + S2 + ( année de césure ) + S3 si césure , . . .
2024-01-21 18:55:21 +01:00
"""
semestres_etudiant = self . cursus [ etudid ] [ " formsemestres " ]
2024-01-23 09:54:30 +01:00
self . aggregats [ etudid ] = { }
2024-01-23 09:05:52 +01:00
""" Tri des semestres par numéro de semestre """
2024-01-20 09:31:02 +01:00
for nom_sem in pe_tools . 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 = {
fid : semestres_etudiant [ fid ]
for fid in semestres_etudiant
if semestres_etudiant [ fid ] . semestre_id == i
} # les semestres de n°i de l'étudiant
2024-01-23 09:05:52 +01:00
self . aggregats [ etudid ] [ nom_sem ] = semestres_i
self . cursus [ etudid ] [ nom_sem ] = get_dernier_semestre ( semestres_i )
2024-01-21 18:55:21 +01:00
""" Tri des semestres par aggrégat et par semestre terminal """
for aggregat in pe_tools . TOUS_LES_AGGREGATS :
2024-01-23 09:54:30 +01:00
self . aggregats [ etudid ] [ aggregat ] = { }
2024-01-23 09:05:52 +01:00
2024-01-21 18:55:21 +01:00
""" L ' aggrégat considéré (par ex: 3S), son nom de son semestre terminal (par ex: S3) et son numéro (par ex: 3) """
noms_semestre_de_aggregat = pe_tools . PARCOURS [ aggregat ] [ " aggregat " ]
nom_semestre_terminal = noms_semestre_de_aggregat [ - 1 ]
numero_semestre_terminal = int ( nom_semestre_terminal [ - 1 ] )
2024-01-23 09:05:52 +01:00
""" Le formsemestre terminal de l ' aggrégat (par ex: son dernier S3 en date) """
dernier_formsemestre_terminal = self . cursus [ etudid ] [ nom_semestre_terminal ]
2024-01-21 18:55:21 +01:00
# for formsem_id_term in formsemestres_terminal:
2024-01-23 09:54:30 +01:00
if dernier_formsemestre_terminal : # ne considérant que le dernier
2024-01-21 18:55:21 +01:00
formsem_id_term = list ( dernier_formsemestre_terminal . keys ( ) ) [ 0 ]
2024-01-23 09:54:30 +01:00
formsemestre_terminal = self . cursus [ etudid ] [ " formsemestres " ] [
formsem_id_term
]
2024-01-21 18:55:21 +01:00
""" 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 self . cursus [ etudid ] [ " formsemestres " ] :
semestre = self . cursus [ etudid ] [ " formsemestres " ] [ fid ]
if (
semestre . semestre_id < = numero_semestre_terminal
and semestre . date_fin < = formsemestre_terminal . date_fin
) :
semestres_aggreges [ fid ] = semestre
2024-01-23 09:54:30 +01:00
self . aggregats [ etudid ] [ aggregat ] [ formsem_id_term ] = semestres_aggreges
""" Vérifications """
dernier_semestre_aggregat = get_dernier_semestre ( semestres_aggreges )
assert dernier_semestre_aggregat == dernier_formsemestre_terminal
2024-01-21 18:55:21 +01:00
def get_formsemestres_terminaux_aggregat ( self , aggregat : str ) :
""" Pour un aggrégat donné, ensemble des formsemestres terminaux possibles pour l ' aggrégat (pour l ' aggrégat ' 3S '
incluant S1 + S2 + S3 , a pour semestre terminal S3 ) . Ces formsemestres traduisent :
* 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 :
Un dictionnaire { fid : FormSemestre ( fid ) }
"""
formsemestres_terminaux = { }
for etudid in self . cursus :
""" Les formsemestre_id des semestres terminaux """
fids = self . cursus [ etudid ] [ aggregat ] . keys ( )
""" Pour chaque identifiant de semestre terminal, récupère le formsemestre associé """
for fid in fids :
if fid not in formsemestres_terminaux :
formsemestres_terminaux [ fid ] = self . cursus [ etudid ] [ aggregat ] [ fid ] [
fid
]
return formsemestres_terminaux
def get_semestres_a_aggreger ( self , aggregat : str , formsemestre_id_terminal : int ) :
""" Pour un aggrégat donné associé à un formsemestre terminal cible, renvoie l ' ensemble des semestres à
prendre en compte dans l ' aggrégat sous la forme d ' un dictionnaire { fid : FormSemestre ( fid ) } .
Fusionne les cursus individuels des étudiants , dont le cursus correspond à l ' aggrégat visé.
Args :
aggregat : Un aggrégat ( par ex . 1 A , 2 A , 3 S , 6 S )
formsemestre_id_terminal : L ' identifiant du formsemestre terminal de l ' aggrégat , devant correspondre au
dernier semestre de l ' aggrégat
"""
noms_semestres_aggreges = pe_tools . PARCOURS [ aggregat ] [ " aggregat " ]
formsemestres = { }
for etudid in self . cursus :
cursus_etudiant = self . cursus [ etudid ] [ aggregat ]
if formsemestre_id_terminal in cursus_etudiant :
formsemestres_etudiant = cursus_etudiant [ formsemestre_id_terminal ]
formsemestres = formsemestres | formsemestres_etudiant
return formsemestres
2024-01-20 09:31:02 +01:00
2024-01-20 16:34:38 +01:00
def get_formsemestres_jury ( 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-20 16:34:38 +01:00
le jury PE ( attribut ` self . etudiant_ids ) et de leur cursus ,
renvoie un dictionnaire ` { fid : FormSemestre ( fid ) } `
contenant l ' ensemble des formsemestres de leur cursus, dont il faudra calculer
la moyenne . Les formsemestres sont limités à ceux indiqués dans ` ` semestres_recherches ` ` .
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-20 16:34:38 +01:00
Un dictionnaire de la forme { fid : FormSemestre ( fid ) }
Remarque :
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) """
semestres = self . get_formsemestres_jury ( pe_tools . AGGREGAT_DIPLOMANT )
return semestres
elif isinstance ( semestres_recherches , list ) :
""" Appel récursif sur tous les éléments de la liste """
semestres = { }
for elmt in semestres_recherches :
semestres_elmt = self . get_formsemestres_jury ( elmt )
semestres = semestres | semestres_elmt
return semestres
elif (
isinstance ( semestres_recherches , str )
and semestres_recherches in pe_tools . TOUS_LES_AGGREGATS
) :
""" Cas d ' un aggrégat avec appel récursif sur toutes les entrées de l ' aggrégat """
semestres = self . get_formsemestres_jury (
pe_tools . PARCOURS [ semestres_recherches ] [ " aggregat " ]
)
return semestres
elif (
isinstance ( semestres_recherches , str )
and semestres_recherches in pe_tools . TOUS_LES_SEMESTRES
) :
""" 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-23 09:54:30 +01:00
semestres = semestres | self . aggregats [ etudid ] [ nom_sem ]
2024-01-20 16:34:38 +01:00
return semestres
else :
raise ValueError (
" Probleme de paramètres d ' appel dans get_formsemestreids_du_jury "
)
2024-01-20 09:31:02 +01:00
def get_etudiants_dans_semestres ( semestres : dict [ FormSemestre ] ) - > set :
""" 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 :
semestres : Un dictionnaire { fid : Formsemestre ( fid ) } donnant un
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 :
""" L ' année de diplôme prévue d ' un étudiant en fonction de ses semestres
d ' inscription (pour un BUT).
Args :
identite : L ' identité d ' un étudiant
Returns :
L ' année prévue de sa diplômation
NOTE : Pourrait être déplacé dans app . models . etudiants . Identite
"""
formsemestres = identite . get_formsemestres ( )
if formsemestres :
return max (
[
pe_tools . get_annee_diplome_semestre ( sem_base )
for sem_base in formsemestres
]
)
else :
return None
def arret_de_formation ( identite : Identite , cosemestres : list [ 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
"""
etudid = identite . etudid
2024-01-23 09:05:52 +01:00
""" Son dernier semestre en date """
2024-01-20 09:31:02 +01:00
dernier_formsemestre = identite . get_formsemestres ( ) [ 0 ]
2024-01-23 09:05:52 +01:00
numero_dernier_formsemestre = dernier_formsemestre . semestre_id
""" Les numéro de semestres possible dans lesquels il pourrait s ' incrire """
2024-01-23 09:54:30 +01:00
# semestre impair => passage de droit en semestre pair suivant (effet de l'annualisation)
if numero_dernier_formsemestre % 2 == 1 :
numeros_possibles = list (
range ( numero_dernier_formsemestre + 1 , pe_tools . NBRE_SEMESTRES_DIPLOMANT )
)
# semestre pair => passage en année supérieure ou redoublement
else : #
numeros_possibles = list (
range (
max ( numero_dernier_formsemestre - 1 , 1 ) ,
pe_tools . NBRE_SEMESTRES_DIPLOMANT ,
)
)
2024-01-20 09:31:02 +01:00
2024-01-23 09:05:52 +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-21 18:55:21 +01:00
def get_dernier_semestre ( semestres : dict [ int , FormSemestre ] ) :
2024-01-23 09:54:30 +01:00
""" Renvoie le dernier semestre en date (de fin) d ' un dictionnaire
2024-01-21 18:55:21 +01:00
de semestres de la forme { fid : FormSemestre ( fid ) } .
La date prise en compte est celle marquant la * * fin * * des semestres .
2024-01-20 16:34:38 +01:00
Args :
semestres : Un dictionnaire de semestres
Return :
Un dictionnaire { fid : FormSemestre ( fid ) } contenant le semestre le plus récent
"""
if semestres :
fid_dernier_semestre = list ( semestres . keys ( ) ) [ 0 ]
dernier_semestre = { fid_dernier_semestre : semestres [ fid_dernier_semestre ] }
for fid in semestres :
if (
semestres [ fid ] . date_fin
> dernier_semestre [ fid_dernier_semestre ] . date_fin
) :
dernier_semestre = { fid : semestres [ fid ] }
fid_dernier_semestre = fid
return dernier_semestre
else :
return { }