2020-09-26 16:19:37 +02:00
|
|
|
|
# -*- mode: python -*-
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
##############################################################################
|
|
|
|
|
#
|
|
|
|
|
# Gestion scolarite IUT
|
|
|
|
|
#
|
2023-01-02 13:16:27 +01:00
|
|
|
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
2020-09-26 16:19:37 +02:00
|
|
|
|
#
|
|
|
|
|
# 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@univ-paris13.fr
|
|
|
|
|
#
|
|
|
|
|
##############################################################################
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
"""Semestres: Codes gestion cursus (constantes)
|
|
|
|
|
Attention: ne pas confondre avec les "parcours" du BUT.
|
|
|
|
|
Renommage des anciens "parcours" -> "cursus" effectué en 9.4.41
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""
|
2021-11-08 19:44:25 +01:00
|
|
|
|
import enum
|
|
|
|
|
|
2022-11-07 18:47:25 +01:00
|
|
|
|
import numpy as np
|
|
|
|
|
|
2021-11-09 11:47:48 +01:00
|
|
|
|
from app import log
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
2021-11-08 19:44:25 +01:00
|
|
|
|
|
|
|
|
|
@enum.unique
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CodesCursus(enum.IntEnum):
|
|
|
|
|
"""Codes numériques des cursus (ex parcours), enregistrés en base
|
2021-11-08 19:44:25 +01:00
|
|
|
|
dans notes_formations.type_parcours
|
|
|
|
|
Ne pas modifier.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
Legacy = 0
|
|
|
|
|
DUT = 100
|
|
|
|
|
DUT4 = 110
|
|
|
|
|
DUTMono = 120
|
|
|
|
|
DUT2 = 130
|
|
|
|
|
LP = 200
|
|
|
|
|
LP2sem = 210
|
|
|
|
|
LP2semEvry = 220
|
|
|
|
|
LP2014 = 230
|
|
|
|
|
LP2sem2014 = 240
|
|
|
|
|
M2 = 250
|
|
|
|
|
M2noncomp = 251
|
|
|
|
|
Mono = 300
|
|
|
|
|
MasterLMD = 402
|
|
|
|
|
MasterIG = 403
|
|
|
|
|
LicenceUCAC3 = 501
|
|
|
|
|
MasterUCAC2 = 502
|
|
|
|
|
MonoUCAC = 503
|
|
|
|
|
GEN_6_SEM = 600
|
|
|
|
|
BUT = 700
|
|
|
|
|
ISCID6 = 1001
|
|
|
|
|
ISCID4 = 1002
|
|
|
|
|
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
NOTES_TOLERANCE = 0.00499999999999 # si note >= (BARRE-TOLERANCE), considere ok
|
|
|
|
|
# (permet d'eviter d'afficher 10.00 sous barre alors que la moyenne vaut 9.999)
|
|
|
|
|
|
|
|
|
|
# Barre sur moyenne générale utilisée pour compensations semestres:
|
2022-06-20 17:56:27 +02:00
|
|
|
|
NOTES_BARRE_GEN = 10.0
|
|
|
|
|
NOTES_BARRE_GEN_COMPENSATION = NOTES_BARRE_GEN - NOTES_TOLERANCE
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
# ----------------------------------------------------------------
|
|
|
|
|
# Types d'UE:
|
|
|
|
|
UE_STANDARD = 0 # UE "fondamentale"
|
|
|
|
|
UE_SPORT = 1 # bonus "sport"
|
|
|
|
|
UE_STAGE_LP = 2 # ue "projet tuteuré et stage" dans les Lic. Pro.
|
|
|
|
|
UE_STAGE_10 = 3 # ue "stage" avec moyenne requise > 10
|
2023-02-12 13:36:47 +01:00
|
|
|
|
UE_ELECTIVE = 4 # UE "élective" dans certains cursus (UCAC?, ISCID)
|
2020-09-26 16:19:37 +02:00
|
|
|
|
UE_PROFESSIONNELLE = 5 # UE "professionnelle" (ISCID, ...)
|
2021-11-13 18:15:15 +01:00
|
|
|
|
UE_OPTIONNELLE = 6 # UE non fondamentales (ILEPS, ...)
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2022-04-02 14:26:16 +02:00
|
|
|
|
def ue_is_fondamentale(ue_type):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
return ue_type in (UE_STANDARD, UE_STAGE_LP, UE_PROFESSIONNELLE)
|
|
|
|
|
|
|
|
|
|
|
2022-04-02 14:26:16 +02:00
|
|
|
|
def ue_is_professionnelle(ue_type):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
return (
|
|
|
|
|
ue_type == UE_PROFESSIONNELLE
|
|
|
|
|
) # NB: les UE_PROFESSIONNELLE sont à la fois fondamentales et pro
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UE_TYPE_NAME = {
|
|
|
|
|
UE_STANDARD: "Standard",
|
|
|
|
|
UE_SPORT: "Sport/Culture (points bonus)",
|
|
|
|
|
UE_STAGE_LP: "Projet tuteuré et stage (Lic. Pro.)",
|
|
|
|
|
UE_STAGE_10: "Stage (moyenne min. 10/20)",
|
|
|
|
|
UE_ELECTIVE: "Elective (ISCID)",
|
2021-11-13 18:15:15 +01:00
|
|
|
|
UE_PROFESSIONNELLE: "Professionnelle (ISCID)",
|
|
|
|
|
UE_OPTIONNELLE: "Optionnelle",
|
2020-09-26 16:19:37 +02:00
|
|
|
|
# UE_FONDAMENTALE : '"Fondamentale" (eg UCAC)',
|
|
|
|
|
# UE_OPTIONNELLE : '"Optionnelle" (UCAC)'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Couleurs RGB (dans [0.,1.]) des UE pour les bulletins:
|
|
|
|
|
UE_DEFAULT_COLOR = (150 / 255.0, 200 / 255.0, 180 / 255.0)
|
|
|
|
|
UE_COLORS = {
|
|
|
|
|
UE_STANDARD: UE_DEFAULT_COLOR,
|
|
|
|
|
UE_SPORT: (0.40, 0.90, 0.50),
|
|
|
|
|
UE_STAGE_LP: (0.80, 0.90, 0.90),
|
|
|
|
|
}
|
|
|
|
|
UE_SEM_DEFAULT = 1000000 # indice semestre des UE sans modules
|
|
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------
|
|
|
|
|
# Codes proposés par ADIUT / Apogee
|
2022-06-05 13:01:29 +02:00
|
|
|
|
ABAN = "ABAN"
|
|
|
|
|
ABL = "ABL"
|
2020-09-26 16:19:37 +02:00
|
|
|
|
ADM = "ADM" # moyenne gen., barres UE, assiduité: sem. validé
|
|
|
|
|
ADC = "ADC" # admis par compensation (eg moy(S1, S2) > 10)
|
2023-06-15 08:49:05 +02:00
|
|
|
|
ADSUP = "ADSUP" # BUT: UE ou RCUE validé par niveau supérieur
|
2020-09-26 16:19:37 +02:00
|
|
|
|
ADJ = "ADJ" # admis par le jury
|
2023-01-12 14:14:54 +01:00
|
|
|
|
ADJR = "ADJR" # UE admise car son RCUE est ADJ
|
2020-09-26 16:19:37 +02:00
|
|
|
|
ATT = "ATT" #
|
|
|
|
|
ATJ = "ATJ" # pb assiduité: décision repoussée au semestre suivant
|
|
|
|
|
ATB = "ATB"
|
|
|
|
|
AJ = "AJ"
|
|
|
|
|
CMP = "CMP" # utile pour UE seulement (indique UE acquise car semestre acquis)
|
|
|
|
|
DEF = "DEF" # défaillance (n'est pas un code jury dans scodoc mais un état, comme inscrit ou demission)
|
2022-01-21 00:46:45 +01:00
|
|
|
|
DEM = "DEM"
|
2022-06-05 13:01:29 +02:00
|
|
|
|
EXCLU = "EXCLU"
|
|
|
|
|
JSD = "JSD" # jury tenu mais pas de code (Jury Sans Décision)
|
2022-05-29 17:34:03 +02:00
|
|
|
|
NAR = "NAR"
|
2022-06-05 13:01:29 +02:00
|
|
|
|
PASD = "PASD"
|
|
|
|
|
PAS1NCI = "PAS1NCI"
|
2022-05-29 17:34:03 +02:00
|
|
|
|
RAT = "RAT" # en attente rattrapage, sera ATT dans Apogée
|
2022-06-05 13:01:29 +02:00
|
|
|
|
RED = "RED"
|
|
|
|
|
UEBSL = "UEBSL" # UE blanchie
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
# codes actions
|
|
|
|
|
REDOANNEE = "REDOANNEE" # redouble annee (va en Sn-1)
|
|
|
|
|
REDOSEM = "REDOSEM" # redouble semestre (va en Sn)
|
|
|
|
|
RA_OR_NEXT = "RA_OR_NEXT" # redouble annee ou passe en Sn+1
|
|
|
|
|
RA_OR_RS = "RA_OR_RS" # redouble annee ou semestre
|
|
|
|
|
RS_OR_NEXT = "RS_OR_NEXT" # redouble semestre ou passe en Sn+1
|
|
|
|
|
NEXT_OR_NEXT2 = "NEXT_OR_NEXT2" # passe en suivant (Sn+1) ou sur-suivant (Sn+2)
|
|
|
|
|
NEXT = "NEXT"
|
|
|
|
|
NEXT2 = "NEXT2" # passe au sur-suivant (Sn+2)
|
|
|
|
|
REO = "REO"
|
|
|
|
|
BUG = "BUG"
|
|
|
|
|
|
|
|
|
|
ALL = "ALL"
|
|
|
|
|
|
2022-01-31 16:55:59 +01:00
|
|
|
|
# Explication des codes (de semestre ou d'UE)
|
2020-09-26 16:19:37 +02:00
|
|
|
|
CODES_EXPL = {
|
2022-06-05 13:01:29 +02:00
|
|
|
|
ABAN: "Non évalué pour manque d’assiduité: non présentation des notes de l'étudiant au jury",
|
|
|
|
|
ABL: "Année blanche",
|
2020-09-26 16:19:37 +02:00
|
|
|
|
ADC: "Validé par compensation",
|
|
|
|
|
ADJ: "Validé par le Jury",
|
2023-01-12 14:14:54 +01:00
|
|
|
|
ADJR: "UE validée car son RCUE est validé ADJ par le jury",
|
2022-01-22 12:15:03 +01:00
|
|
|
|
ADM: "Validé",
|
2023-06-15 08:49:05 +02:00
|
|
|
|
ADSUP: "UE ou RCUE validé car le niveau supérieur est validé",
|
2022-06-05 13:01:29 +02:00
|
|
|
|
AJ: "Ajourné (ou UE/BC de BUT en attente pour problème de moyenne)",
|
2020-09-26 16:19:37 +02:00
|
|
|
|
ATB: "Décision en attente d'un autre semestre (au moins une UE sous la barre)",
|
|
|
|
|
ATJ: "Décision en attente d'un autre semestre (assiduité insuffisante)",
|
2022-01-22 12:15:03 +01:00
|
|
|
|
ATT: "Décision en attente d'un autre semestre (faute d'atteindre la moyenne)",
|
2022-06-05 13:01:29 +02:00
|
|
|
|
CMP: """Code UE acquise car semestre acquis, ou, en BUT, acquise par
|
|
|
|
|
compensation UE avec l’UE de même compétence et de même année (ECTS acquis).
|
|
|
|
|
Utilisé aussi pour les blocs de compétences BUT (RCUE).
|
|
|
|
|
""",
|
|
|
|
|
DEF: "Défaillant, pas ou peu de notes par arrêt de la formation. Non évalué par manque assiduité.",
|
2022-01-31 16:55:59 +01:00
|
|
|
|
DEM: "Démission",
|
2022-06-05 13:01:29 +02:00
|
|
|
|
EXCLU: "Exclusion: décision réservée à des décisions disciplinaires",
|
|
|
|
|
NAR: "Non admis, réorientation, non autorisé à redoubler",
|
|
|
|
|
PASD: """Année BUT: non admis, mais passage de droit:
|
|
|
|
|
Passage en Année Supérieure de Droit (+ de 50% des UE VAL et RCUE Ajourné(s) >=8)
|
|
|
|
|
""",
|
|
|
|
|
PAS1NCI: """Année BUT: Non admis, mais passage par décision de jury:
|
|
|
|
|
Passage en Année Supérieure avec au moins 1 Niveau de Compétence Insuffisant (RCUE<8)
|
|
|
|
|
""",
|
|
|
|
|
RAT: "En attente d'un rattrapage",
|
|
|
|
|
RED: "Année: Ajourné, mais autorisé à redoubler",
|
|
|
|
|
UEBSL: "UE blanchie",
|
2020-09-26 16:19:37 +02:00
|
|
|
|
}
|
2022-05-29 17:34:03 +02:00
|
|
|
|
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
2022-01-22 12:15:03 +01:00
|
|
|
|
# Les codes de semestres:
|
|
|
|
|
CODES_JURY_SEM = {ADC, ADJ, ADM, AJ, ATB, ATJ, ATT, DEF, NAR, RAT}
|
2023-01-23 11:38:47 +01:00
|
|
|
|
CODES_SEM_VALIDES_DE_DROIT = {ADM, ADC}
|
|
|
|
|
CODES_SEM_VALIDES = CODES_SEM_VALIDES_DE_DROIT | {ADJ} # semestre validé
|
|
|
|
|
CODES_SEM_ATTENTES = {ATT, ATB, ATJ} # semestre en attente
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
2023-01-23 11:38:47 +01:00
|
|
|
|
CODES_SEM_REO = {NAR} # reorientation
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
2023-01-23 11:38:47 +01:00
|
|
|
|
CODES_UE_VALIDES_DE_DROIT = {ADM, CMP} # validation "de droit"
|
2023-06-15 08:49:05 +02:00
|
|
|
|
CODES_UE_VALIDES = CODES_UE_VALIDES_DE_DROIT | {ADJ, ADJR, ADSUP}
|
2023-01-17 23:14:58 +01:00
|
|
|
|
"UE validée"
|
2023-02-08 17:56:08 +01:00
|
|
|
|
CODES_UE_CAPITALISANTS = {ADM}
|
|
|
|
|
"UE capitalisée"
|
2023-01-17 23:14:58 +01:00
|
|
|
|
|
2023-01-23 11:38:47 +01:00
|
|
|
|
CODES_RCUE_VALIDES_DE_DROIT = {ADM, CMP}
|
2023-06-15 08:49:05 +02:00
|
|
|
|
CODES_RCUE_VALIDES = CODES_RCUE_VALIDES_DE_DROIT | {ADJ, ADSUP}
|
2023-01-17 23:14:58 +01:00
|
|
|
|
"Niveau RCUE validé"
|
|
|
|
|
|
2022-05-29 17:34:03 +02:00
|
|
|
|
# Pour le BUT:
|
2023-06-15 16:50:22 +02:00
|
|
|
|
CODES_ANNEE_BUT_VALIDES_DE_DROIT = {ADM, PASD} # PASD pour enregistrement auto
|
2023-06-15 08:49:05 +02:00
|
|
|
|
CODES_ANNEE_BUT_VALIDES = {ADM, ADSUP}
|
2022-06-09 07:39:58 +02:00
|
|
|
|
CODES_ANNEE_ARRET = {DEF, DEM, ABAN, ABL}
|
2022-06-23 08:40:33 +02:00
|
|
|
|
BUT_BARRE_UE8 = 8.0 - NOTES_TOLERANCE
|
|
|
|
|
BUT_BARRE_UE = BUT_BARRE_RCUE = 10.0 - NOTES_TOLERANCE
|
2022-06-20 17:56:27 +02:00
|
|
|
|
BUT_RCUE_SUFFISANT = 8.0 - NOTES_TOLERANCE
|
2022-06-25 03:52:28 +02:00
|
|
|
|
BUT_CODES_PASSAGE = {
|
|
|
|
|
ADM,
|
|
|
|
|
ADJ,
|
|
|
|
|
PASD,
|
|
|
|
|
PAS1NCI,
|
2022-06-30 20:13:30 +02:00
|
|
|
|
ATJ,
|
2022-06-25 03:52:28 +02:00
|
|
|
|
}
|
2023-01-08 19:36:05 +01:00
|
|
|
|
# les codes, du plus "défavorable" à l'étudiant au plus favorable:
|
|
|
|
|
# (valeur par défaut 0)
|
2023-06-22 08:22:37 +02:00
|
|
|
|
BUT_CODES_ORDER = {
|
2023-06-22 19:00:56 +02:00
|
|
|
|
ABAN: 0,
|
|
|
|
|
ABL: 0,
|
|
|
|
|
DEM: 0,
|
2023-01-12 14:14:54 +01:00
|
|
|
|
DEF: 0,
|
2023-06-22 19:00:56 +02:00
|
|
|
|
EXCLU: 0,
|
|
|
|
|
NAR: 0,
|
|
|
|
|
UEBSL: 0,
|
|
|
|
|
RAT: 5,
|
|
|
|
|
RED: 6,
|
2023-01-12 14:14:54 +01:00
|
|
|
|
AJ: 10,
|
|
|
|
|
ATJ: 20,
|
|
|
|
|
CMP: 50,
|
|
|
|
|
ADC: 50,
|
2023-06-22 08:22:37 +02:00
|
|
|
|
PAS1NCI: 50,
|
|
|
|
|
PASD: 60,
|
2023-01-12 14:14:54 +01:00
|
|
|
|
ADJR: 90,
|
2023-06-15 08:49:05 +02:00
|
|
|
|
ADSUP: 90,
|
2023-06-22 19:00:56 +02:00
|
|
|
|
ADJ: 90,
|
2023-01-12 14:14:54 +01:00
|
|
|
|
ADM: 100,
|
2023-01-08 19:36:05 +01:00
|
|
|
|
}
|
2022-05-29 17:34:03 +02:00
|
|
|
|
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
2022-02-06 16:09:17 +01:00
|
|
|
|
def code_semestre_validant(code: str) -> bool:
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"Vrai si ce CODE entraine la validation du semestre"
|
2023-01-23 11:38:47 +01:00
|
|
|
|
return code in CODES_SEM_VALIDES
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2022-02-06 16:09:17 +01:00
|
|
|
|
def code_semestre_attente(code: str) -> bool:
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"Vrai si ce CODE est un code d'attente (semestre validable plus tard par jury ou compensation)"
|
2023-01-23 11:38:47 +01:00
|
|
|
|
return code in CODES_SEM_ATTENTES
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2022-02-06 16:09:17 +01:00
|
|
|
|
def code_ue_validant(code: str) -> bool:
|
2022-07-09 13:32:14 +02:00
|
|
|
|
"Vrai si ce code d'UE est validant (ie attribue les ECTS)"
|
2023-01-23 11:38:47 +01:00
|
|
|
|
return code in CODES_UE_VALIDES
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-06-15 08:49:05 +02:00
|
|
|
|
def code_rcue_validant(code: str) -> bool:
|
|
|
|
|
"Vrai si ce code d'RCUE est validant"
|
|
|
|
|
return code in CODES_RCUE_VALIDES
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def code_annee_validant(code: str) -> bool:
|
|
|
|
|
"Vrai si code d'année BUT validant"
|
|
|
|
|
return code in CODES_ANNEE_BUT_VALIDES
|
|
|
|
|
|
|
|
|
|
|
2020-09-26 16:19:37 +02:00
|
|
|
|
DEVENIR_EXPL = {
|
|
|
|
|
NEXT: "Passage au semestre suivant",
|
|
|
|
|
REDOANNEE: "Redoublement année",
|
|
|
|
|
REDOSEM: "Redoublement semestre",
|
|
|
|
|
RA_OR_NEXT: "Passage, ou redoublement année",
|
|
|
|
|
RA_OR_RS: "Redoublement année, ou redoublement semestre", # slt si sems decales
|
|
|
|
|
RS_OR_NEXT: "Passage, ou redoublement semestre",
|
|
|
|
|
NEXT_OR_NEXT2: "Passage en semestre suivant ou à celui d'après",
|
|
|
|
|
NEXT2: "Passage au sur-suivant",
|
|
|
|
|
REO: "Réorientation",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Devenirs autorises dans les cursus sans semestres décalés:
|
|
|
|
|
DEVENIRS_STD = {NEXT: 1, REDOANNEE: 1, RA_OR_NEXT: 1, REO: 1}
|
|
|
|
|
|
|
|
|
|
# Devenirs autorises dans les cursus en un seul semestre, semestre_id==-1 (licences ?)
|
|
|
|
|
DEVENIRS_MONO = {REDOANNEE: 1, REO: 1}
|
|
|
|
|
|
|
|
|
|
# Devenirs supplementaires (en mode manuel) pour les cursus avec semestres decales
|
|
|
|
|
DEVENIRS_DEC = {REDOSEM: 1, RS_OR_NEXT: 1}
|
|
|
|
|
|
|
|
|
|
# Devenirs en n+2 (sautant un semestre) (si semestres décalés et s'il ne manque qu'un semestre avant le n+2)
|
|
|
|
|
DEVENIRS_NEXT2 = {NEXT_OR_NEXT2: 1, NEXT2: 1}
|
|
|
|
|
|
|
|
|
|
NO_SEMESTRE_ID = -1 # code semestre si pas de semestres
|
|
|
|
|
|
2023-04-06 16:10:32 +02:00
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
# Règles gestion cursus
|
2021-07-09 23:31:16 +02:00
|
|
|
|
class DUTRule(object):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
def __init__(self, rule_id, premise, conclusion):
|
|
|
|
|
self.rule_id = rule_id
|
|
|
|
|
self.premise = premise
|
|
|
|
|
self.conclusion = conclusion
|
|
|
|
|
# self.code, self.codes_ue, self.devenir, self.action, self.explication = conclusion
|
|
|
|
|
|
|
|
|
|
def match(self, state):
|
|
|
|
|
"True if state match rule premise"
|
|
|
|
|
assert len(state) == len(self.premise)
|
2022-04-02 14:26:16 +02:00
|
|
|
|
for i, stat in enumerate(state):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
prem = self.premise[i]
|
2021-07-11 17:59:47 +02:00
|
|
|
|
if isinstance(prem, (list, tuple)):
|
2022-04-02 14:26:16 +02:00
|
|
|
|
if not stat in prem:
|
2020-09-26 16:19:37 +02:00
|
|
|
|
return False
|
|
|
|
|
else:
|
2022-04-02 14:26:16 +02:00
|
|
|
|
if prem not in (ALL, stat):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
# Types de cursus
|
2023-04-06 16:10:32 +02:00
|
|
|
|
DEFAULT_TYPE_CURSUS = 700 # (BUT) pour le menu de creation nouvelle formation
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class TypeCursus:
|
|
|
|
|
TYPE_CURSUS = None # id, utilisé par notes_formation.type_parcours
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = None # required
|
|
|
|
|
NB_SEM = 1 # Nombre de semestres
|
|
|
|
|
COMPENSATION_UE = True # inutilisé
|
|
|
|
|
BARRE_MOY = 10.0
|
|
|
|
|
BARRE_UE_DEFAULT = 8.0
|
2022-04-02 14:26:16 +02:00
|
|
|
|
BARRE_UE_DISPLAY_WARNING = 8.0
|
2020-09-26 16:19:37 +02:00
|
|
|
|
BARRE_UE = {}
|
|
|
|
|
NOTES_BARRE_VALID_UE_TH = 10.0 # seuil pour valider UE
|
|
|
|
|
NOTES_BARRE_VALID_UE = NOTES_BARRE_VALID_UE_TH - NOTES_TOLERANCE # barre sur UE
|
|
|
|
|
ALLOW_SEM_SKIP = False # Passage: autorise-t-on les sauts de semestres ?
|
|
|
|
|
SESSION_NAME = "semestre"
|
|
|
|
|
SESSION_NAME_A = "du "
|
|
|
|
|
SESSION_ABBRV = "S" # S1, S2, ...
|
2023-02-12 13:36:47 +01:00
|
|
|
|
UNUSED_CODES = set() # Ensemble des codes jury non autorisés dans ce cursus
|
2020-09-26 16:19:37 +02:00
|
|
|
|
UE_IS_MODULE = False # 1 seul module par UE (si plusieurs modules, etudiants censéments inscrits à un seul d'entre eux)
|
2023-02-12 13:36:47 +01:00
|
|
|
|
ECTS_ONLY = False # Cursus avec progression basée uniquement sur les ECTS
|
2021-07-09 23:31:16 +02:00
|
|
|
|
ALLOWED_UE_TYPES = list(
|
|
|
|
|
UE_TYPE_NAME.keys()
|
|
|
|
|
) # par defaut, autorise tous les types d'UE
|
2021-11-08 19:44:25 +01:00
|
|
|
|
APC_SAE = False # Approche par compétences avec ressources et SAÉs
|
2021-12-03 11:03:33 +01:00
|
|
|
|
USE_REFERENTIEL_COMPETENCES = False # Lien avec ref. comp.
|
2022-02-06 16:09:17 +01:00
|
|
|
|
ECTS_FONDAMENTAUX_PER_YEAR = 0.0 # pour ISCID, deprecated
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
def check(self, formation=None):
|
|
|
|
|
return True, "" # status, diagnostic_message
|
|
|
|
|
|
|
|
|
|
def get_barre_ue(self, ue_type, tolerance=True):
|
|
|
|
|
"""Barre pour cette UE (la valeur peut dépendre du type d'UE).
|
|
|
|
|
Si tolerance, diminue de epsilon pour éviter les effets d'arrondis.
|
|
|
|
|
"""
|
|
|
|
|
if tolerance:
|
|
|
|
|
t = NOTES_TOLERANCE
|
|
|
|
|
else:
|
|
|
|
|
t = 0.0
|
|
|
|
|
return self.BARRE_UE.get(ue_type, self.BARRE_UE_DEFAULT) - t
|
|
|
|
|
|
|
|
|
|
def ues_sous_barre(self, ues_status):
|
|
|
|
|
"""Filtre les ues: liste celles ayant une moyenne sous la barre
|
|
|
|
|
|
|
|
|
|
ues_status est une liste de dict ayant des entrées 'moy' et 'coef_ue'
|
|
|
|
|
"""
|
|
|
|
|
return [
|
|
|
|
|
ue_status
|
|
|
|
|
for ue_status in ues_status
|
2022-02-27 20:12:20 +01:00
|
|
|
|
if ue_status["coef_ue"]
|
2021-07-11 22:32:01 +02:00
|
|
|
|
and isinstance(ue_status["moy"], float)
|
2020-09-26 16:19:37 +02:00
|
|
|
|
and ue_status["moy"] < self.get_barre_ue(ue_status["ue"]["type"])
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
def check_barre_ues(self, ues_status):
|
|
|
|
|
"""True si la ou les conditions sur les UE sont valides
|
|
|
|
|
Par defaut, vrai si les moyennes d'UE sont au dessus de la barre.
|
|
|
|
|
Le cas des LP2014 est plus compliqué.
|
|
|
|
|
"""
|
|
|
|
|
n = len(self.ues_sous_barre(ues_status))
|
|
|
|
|
if n == 0:
|
|
|
|
|
return True, "les UEs sont au dessus des barres"
|
|
|
|
|
else:
|
|
|
|
|
return False, """<b>%d UE sous la barre</b>""" % n
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
# Cursus définis (instances de sous-classes de TypeCursus):
|
|
|
|
|
SCO_CURSUS: dict[int, TypeCursus] = {} # type : Cursus
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
def register_cursus(cursus: TypeCursus):
|
|
|
|
|
SCO_CURSUS[int(cursus.TYPE_CURSUS)] = cursus
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusBUT(TypeCursus):
|
2021-11-08 19:44:25 +01:00
|
|
|
|
"""BUT Bachelor Universitaire de Technologie"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = 700
|
2021-11-08 19:44:25 +01:00
|
|
|
|
NAME = "BUT"
|
|
|
|
|
NB_SEM = 6
|
|
|
|
|
COMPENSATION_UE = False
|
|
|
|
|
APC_SAE = True
|
2021-12-03 11:03:33 +01:00
|
|
|
|
USE_REFERENTIEL_COMPETENCES = True
|
2021-11-08 19:44:25 +01:00
|
|
|
|
ALLOWED_UE_TYPES = [UE_STANDARD, UE_SPORT]
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusBUT())
|
2021-11-08 19:44:25 +01:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusDUT(TypeCursus):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""DUT selon l'arrêté d'août 2005"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = 100
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "DUT"
|
|
|
|
|
NB_SEM = 4
|
|
|
|
|
COMPENSATION_UE = True
|
|
|
|
|
ALLOWED_UE_TYPES = [UE_STANDARD, UE_SPORT]
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusDUT())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusDUT4(CursusDUT):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""DUT (en 4 semestres sans compensations)"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = 110
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "DUT4"
|
|
|
|
|
COMPENSATION_UE = False
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusDUT4())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusDUTMono(TypeCursus):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""DUT en un an (FC, Années spéciales)"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = 120
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "DUT"
|
|
|
|
|
NB_SEM = 1
|
|
|
|
|
COMPENSATION_UE = False
|
|
|
|
|
UNUSED_CODES = set((ADC, ATT, ATB))
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusDUTMono())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusDUT2(CursusDUT):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""DUT en deux semestres (par ex.: années spéciales semestrialisées)"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.DUT2
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "DUT2"
|
|
|
|
|
NB_SEM = 2
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusDUT2())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusLP(TypeCursus):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""Licence Pro (en un "semestre")
|
2023-02-12 13:36:47 +01:00
|
|
|
|
(pour anciennes LP. Après 2014, préférer CursusLP2014)
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.LP
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "LP"
|
|
|
|
|
NB_SEM = 1
|
|
|
|
|
COMPENSATION_UE = False
|
|
|
|
|
ALLOWED_UE_TYPES = [UE_STANDARD, UE_SPORT, UE_STAGE_LP]
|
|
|
|
|
BARRE_UE_DEFAULT = 0.0 # pas de barre sur les UE "normales"
|
|
|
|
|
BARRE_UE = {UE_STAGE_LP: 10.0}
|
|
|
|
|
# pas de codes ATT en LP
|
|
|
|
|
UNUSED_CODES = set((ADC, ATT, ATB))
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusLP())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusLP2sem(CursusLP):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""Licence Pro (en deux "semestres")"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.LP2sem
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "LP2sem"
|
|
|
|
|
NB_SEM = 2
|
|
|
|
|
COMPENSATION_UE = True
|
|
|
|
|
UNUSED_CODES = set((ADC,)) # autorise les codes ATT et ATB, mais pas ADC.
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusLP2sem())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusLP2semEvry(CursusLP):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""Licence Pro (en deux "semestres", U. Evry)"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.LP2semEvry
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "LP2semEvry"
|
|
|
|
|
NB_SEM = 2
|
|
|
|
|
COMPENSATION_UE = True
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusLP2semEvry())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusLP2014(TypeCursus):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""Licence Pro (en un "semestre"), selon arrêté du 22/01/2014"""
|
|
|
|
|
|
|
|
|
|
# Note: texte de référence
|
|
|
|
|
# https://www.legifrance.gouv.fr/affichTexte.do?cidTexte=JORFTEXT000000397481
|
|
|
|
|
|
|
|
|
|
# Article 7: Le stage et le projet tutoré constituent chacun une unité d'enseignement.
|
|
|
|
|
# Article 10:
|
|
|
|
|
# La licence professionnelle est décernée aux étudiants qui ont obtenu à la fois une moyenne
|
|
|
|
|
# générale égale ou supérieure à 10 sur 20 à l'ensemble des unités d'enseignement, y compris le
|
|
|
|
|
# projet tutoré et le stage, et une moyenne égale ou supérieure à 10 sur 20 à l'ensemble constitué
|
|
|
|
|
# du projet tutoré et du stage.
|
|
|
|
|
|
|
|
|
|
# Actuellement, les points suivants de l'article 7 ("Les unités d'enseignement sont affectées par
|
|
|
|
|
# l'établissement d'un coefficient qui peut varier dans un rapport de 1 à 3. ", etc ne sont _pas_
|
|
|
|
|
# vérifiés par ScoDoc)
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.LP2014
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "LP2014"
|
|
|
|
|
NB_SEM = 1
|
|
|
|
|
ALLOWED_UE_TYPES = [UE_STANDARD, UE_SPORT, UE_STAGE_LP]
|
|
|
|
|
BARRE_UE_DEFAULT = 0.0 # pas de barre sur les UE "normales"
|
|
|
|
|
# pas de codes ATT en LP
|
|
|
|
|
UNUSED_CODES = set((ADC, ATT, ATB))
|
|
|
|
|
# Specifique aux LP
|
|
|
|
|
BARRE_MOY_UE_STAGE_PROJET = 10.0
|
|
|
|
|
|
|
|
|
|
def check_barre_ues(self, ues_status):
|
|
|
|
|
"""True si la ou les conditions sur les UE sont valides
|
2020-12-01 11:34:26 +01:00
|
|
|
|
Article 10: "une moyenne égale ou supérieure à 10 sur 20 à l'ensemble constitué
|
2020-09-26 16:19:37 +02:00
|
|
|
|
du projet tutoré et du stage."
|
|
|
|
|
"""
|
|
|
|
|
# Les UE de type "projet ou stage" ayant des notes
|
|
|
|
|
mc_stages_proj = [
|
|
|
|
|
(ue_status["moy"], ue_status["coef_ue"])
|
|
|
|
|
for ue_status in ues_status
|
|
|
|
|
if ue_status["ue"]["type"] == UE_STAGE_LP
|
2022-11-07 18:47:25 +01:00
|
|
|
|
and np.issubdtype(type(ue_status["moy"]), np.floating)
|
2020-09-26 16:19:37 +02:00
|
|
|
|
]
|
|
|
|
|
# Moyenne des moyennes:
|
|
|
|
|
sum_coef = sum(x[1] for x in mc_stages_proj)
|
|
|
|
|
if sum_coef > 0.0:
|
|
|
|
|
moy = sum([x[0] * x[1] for x in mc_stages_proj]) / sum_coef
|
|
|
|
|
ok = moy > (self.BARRE_MOY_UE_STAGE_PROJET - NOTES_TOLERANCE)
|
|
|
|
|
if ok:
|
|
|
|
|
return True, "moyenne des UE de stages et projets au dessus de 10"
|
|
|
|
|
else:
|
|
|
|
|
return (
|
|
|
|
|
False,
|
|
|
|
|
"<b>moyenne des UE de stages et projets inférieure à 10</b>",
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
return True, "" # pas de coef, condition ok
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusLP2014())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusLP2sem2014(CursusLP):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""Licence Pro (en deux "semestres", selon arrêté du 22/01/2014)"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.LP2sem2014
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "LP2014_2sem"
|
|
|
|
|
NB_SEM = 2
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusLP2sem2014())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Masters: M2 en deux semestres
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusM2(TypeCursus):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""Master 2 (en deux "semestres")"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.M2
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "M2sem"
|
|
|
|
|
NB_SEM = 2
|
|
|
|
|
COMPENSATION_UE = True
|
|
|
|
|
UNUSED_CODES = set((ATT, ATB))
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusM2())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusM2noncomp(CursusM2):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""Master 2 (en deux "semestres") sans compensation"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.M2noncomp
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "M2noncomp"
|
|
|
|
|
COMPENSATION_UE = False
|
|
|
|
|
UNUSED_CODES = set((ADC, ATT, ATB))
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusM2noncomp())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusMono(TypeCursus):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""Formation générique en une session"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.Mono
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "Mono"
|
|
|
|
|
NB_SEM = 1
|
|
|
|
|
COMPENSATION_UE = False
|
|
|
|
|
UNUSED_CODES = set((ADC, ATT, ATB))
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusMono())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusLegacy(TypeCursus):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""DUT (ancien ScoDoc, ne plus utiliser)"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.Legacy
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "DUT"
|
|
|
|
|
NB_SEM = 4
|
|
|
|
|
COMPENSATION_UE = None # backward compat: defini dans formsemestre
|
|
|
|
|
ALLOWED_UE_TYPES = [UE_STANDARD, UE_SPORT]
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusLegacy())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusISCID(TypeCursus):
|
|
|
|
|
"""Superclasse pour les cursus de l'ISCID"""
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
# SESSION_NAME = "année"
|
|
|
|
|
# SESSION_NAME_A = "de l'"
|
|
|
|
|
# SESSION_ABBRV = 'A' # A1, A2, ...
|
|
|
|
|
COMPENSATION_UE = False
|
|
|
|
|
UNUSED_CODES = set((ADC, ATT, ATB, ATJ))
|
|
|
|
|
UE_IS_MODULE = True # pas de matieres et modules
|
|
|
|
|
ECTS_ONLY = True # jury basés sur les ECTS (pas moyenne generales, pas de barres, pas de compensations)
|
|
|
|
|
ALLOWED_UE_TYPES = [UE_STANDARD, UE_ELECTIVE, UE_PROFESSIONNELLE]
|
|
|
|
|
NOTES_BARRE_VALID_MODULE_TH = 10.0
|
|
|
|
|
NOTES_BARRE_VALID_MODULE = (
|
|
|
|
|
NOTES_BARRE_VALID_MODULE_TH - NOTES_TOLERANCE
|
|
|
|
|
) # barre sur module
|
|
|
|
|
ECTS_BARRE_VALID_YEAR = 60
|
|
|
|
|
ECTS_FONDAMENTAUX_PER_YEAR = 42 # mini pour valider l'annee
|
|
|
|
|
ECTS_PROF_DIPL = 0 # crédits professionnels requis pour obtenir le diplôme
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusBachelorISCID6(CursusISCID):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""ISCID: Bachelor en 3 ans (6 sem.)"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
NAME = "CursusBachelorISCID6"
|
|
|
|
|
TYPE_CURSUS = CodesCursus.ISCID6
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = ""
|
|
|
|
|
NB_SEM = 6
|
|
|
|
|
ECTS_PROF_DIPL = 8 # crédits professionnels requis pour obtenir le diplôme
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusBachelorISCID6())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusMasterISCID4(CursusISCID):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"ISCID: Master en 2 ans (4 sem.)"
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.ISCID4
|
|
|
|
|
NAME = "CursusMasterISCID4"
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NB_SEM = 4
|
|
|
|
|
ECTS_PROF_DIPL = 15 # crédits professionnels requis pour obtenir le diplôme
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusMasterISCID4())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusILEPS(TypeCursus):
|
|
|
|
|
"""Superclasse pour les cursus de l'ILEPS"""
|
2021-11-13 18:15:15 +01:00
|
|
|
|
|
|
|
|
|
# SESSION_NAME = "année"
|
|
|
|
|
# SESSION_NAME_A = "de l'"
|
|
|
|
|
# SESSION_ABBRV = 'A' # A1, A2, ...
|
|
|
|
|
COMPENSATION_UE = False
|
|
|
|
|
UNUSED_CODES = set((ADC, ATT, ATB, ATJ))
|
2022-02-22 18:45:43 +01:00
|
|
|
|
ALLOWED_UE_TYPES = [UE_STANDARD, UE_OPTIONNELLE, UE_SPORT]
|
2021-11-13 18:15:15 +01:00
|
|
|
|
# Barre moy gen. pour validation semestre:
|
|
|
|
|
BARRE_MOY = 10.0
|
|
|
|
|
# Barre pour UE ILEPS: 8/20 pour UE standards ("fondamentales")
|
|
|
|
|
# et pas de barre (-1.) pour UE élective.
|
|
|
|
|
BARRE_UE = {UE_STANDARD: 8.0, UE_OPTIONNELLE: 0.0}
|
|
|
|
|
BARRE_UE_DEFAULT = 0.0 # pas de barre sur les autres UE
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusLicenceILEPS6(CursusILEPS):
|
2021-11-13 18:15:15 +01:00
|
|
|
|
"""ILEPS: Licence 6 semestres"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = 1010
|
2021-11-13 18:15:15 +01:00
|
|
|
|
NAME = "LicenceILEPS6"
|
|
|
|
|
NB_SEM = 6
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusLicenceILEPS6())
|
2021-11-13 18:15:15 +01:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusUCAC(TypeCursus):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""Règles de validation UCAC"""
|
|
|
|
|
|
|
|
|
|
SESSION_NAME = "année"
|
|
|
|
|
SESSION_NAME_A = "de l'"
|
|
|
|
|
COMPENSATION_UE = False
|
|
|
|
|
BARRE_MOY = 12.0
|
|
|
|
|
NOTES_BARRE_VALID_UE_TH = 12.0 # seuil pour valider UE
|
|
|
|
|
NOTES_BARRE_VALID_UE = NOTES_BARRE_VALID_UE_TH - NOTES_TOLERANCE # barre sur UE
|
|
|
|
|
BARRE_UE_DEFAULT = (
|
|
|
|
|
NOTES_BARRE_VALID_UE_TH # il faut valider tt les UE pour valider l'année
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusLicenceUCAC3(CursusUCAC):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""UCAC: Licence en 3 sessions d'un an"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.LicenceUCAC3
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "Licence UCAC en 3 sessions d'un an"
|
|
|
|
|
NB_SEM = 3
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusLicenceUCAC3())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusMasterUCAC2(CursusUCAC):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""UCAC: Master en 2 sessions d'un an"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.MasterUCAC2
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "Master UCAC en 2 sessions d'un an"
|
|
|
|
|
NB_SEM = 2
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusMasterUCAC2())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusMonoUCAC(CursusUCAC):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""UCAC: Formation en 1 session de durée variable"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.MonoUCAC
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "Formation UCAC en 1 session de durée variable"
|
|
|
|
|
NB_SEM = 1
|
|
|
|
|
UNUSED_CODES = set((ADC, ATT, ATB))
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusMonoUCAC())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class Cursus6Sem(TypeCursus):
|
|
|
|
|
"""Cursus générique en 6 semestres"""
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.GEN_6_SEM
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "Formation en 6 semestres"
|
|
|
|
|
NB_SEM = 6
|
|
|
|
|
COMPENSATION_UE = True
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(Cursus6Sem())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
# # En cours d'implémentation:
|
2023-02-12 13:36:47 +01:00
|
|
|
|
# class CursusLicenceLMD(TypeCursus):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
# """Licence standard en 6 semestres dans le LMD"""
|
2023-02-12 13:36:47 +01:00
|
|
|
|
# TYPE_CURSUS = 401
|
2020-09-26 16:19:37 +02:00
|
|
|
|
# NAME = "Licence LMD"
|
|
|
|
|
# NB_SEM = 6
|
|
|
|
|
# COMPENSATION_UE = True
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
# register_cursus(CursusLicenceLMD())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusMasterLMD(TypeCursus):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""Master générique en 4 semestres dans le LMD"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.MasterLMD
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "Master LMD"
|
|
|
|
|
NB_SEM = 4
|
|
|
|
|
COMPENSATION_UE = True # variabale inutilisée
|
|
|
|
|
UNUSED_CODES = set((ADC, ATT, ATB))
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusMasterLMD())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
class CursusMasterIG(CursusMasterLMD):
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""Master de l'Institut Galilée (U. Paris 13) en 4 semestres (LMD)"""
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
TYPE_CURSUS = CodesCursus.MasterIG
|
2020-09-26 16:19:37 +02:00
|
|
|
|
NAME = "Master IG P13"
|
|
|
|
|
BARRE_MOY = 10.0
|
|
|
|
|
NOTES_BARRE_VALID_UE_TH = 10.0 # seuil pour valider UE
|
|
|
|
|
NOTES_BARRE_VALID_UE = NOTES_BARRE_VALID_UE_TH - NOTES_TOLERANCE # barre sur UE
|
|
|
|
|
BARRE_UE_DEFAULT = 7.0 # Les UE normales avec moins de 7/20 sont éliminatoires
|
|
|
|
|
# Specifique à l'UE de stage
|
|
|
|
|
BARRE_MOY_UE_STAGE = 10.0
|
|
|
|
|
ALLOWED_UE_TYPES = [UE_STANDARD, UE_SPORT, UE_STAGE_10]
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
def check_barre_ues(self, ues_status): # inspire de la fonction de CursusLP2014
|
2020-09-26 16:19:37 +02:00
|
|
|
|
"""True si la ou les conditions sur les UE sont valides
|
|
|
|
|
moyenne d'UE > 7, ou > 10 si UE de stage
|
|
|
|
|
"""
|
|
|
|
|
# Il y a-t-il une UE standard sous la barre ?
|
|
|
|
|
ue_sb = [
|
|
|
|
|
ue_status
|
|
|
|
|
for ue_status in ues_status
|
|
|
|
|
if ue_status["ue"]["type"] == UE_STANDARD
|
|
|
|
|
and ue_status["coef_ue"] > 0
|
2021-07-11 17:59:47 +02:00
|
|
|
|
and type(ue_status["moy"]) == float
|
2020-09-26 16:19:37 +02:00
|
|
|
|
and ue_status["moy"] < self.get_barre_ue(ue_status["ue"]["type"])
|
|
|
|
|
]
|
|
|
|
|
if len(ue_sb):
|
|
|
|
|
return (
|
|
|
|
|
False,
|
|
|
|
|
"<b>%d UE sous la barre (%s/20)</b>"
|
|
|
|
|
% (len(ue_sb), self.BARRE_UE_DEFAULT),
|
|
|
|
|
)
|
|
|
|
|
# Les UE de type "stage" ayant des notes
|
|
|
|
|
mc_stages = [
|
|
|
|
|
(ue_status["moy"], ue_status["coef_ue"])
|
|
|
|
|
for ue_status in ues_status
|
|
|
|
|
if ue_status["ue"]["type"] == UE_STAGE_10
|
2021-07-11 17:59:47 +02:00
|
|
|
|
and type(ue_status["moy"]) == float
|
2020-09-26 16:19:37 +02:00
|
|
|
|
]
|
|
|
|
|
# Moyenne des moyennes:
|
|
|
|
|
sum_coef = sum(x[1] for x in mc_stages)
|
|
|
|
|
if sum_coef > 0.0:
|
|
|
|
|
moy = sum([x[0] * x[1] for x in mc_stages]) / sum_coef
|
|
|
|
|
ok = moy > (self.BARRE_MOY_UE_STAGE - NOTES_TOLERANCE)
|
|
|
|
|
if ok:
|
|
|
|
|
return True, "moyenne des UE de stages au dessus de 10"
|
|
|
|
|
else:
|
|
|
|
|
return False, "<b>moyenne des UE de stages inférieure à 10</b>"
|
|
|
|
|
else:
|
|
|
|
|
return True, "" # pas de coef, condition ok
|
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
register_cursus(CursusMasterIG())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-12 13:36:47 +01:00
|
|
|
|
# Ajouter ici vos cursus, le TYPE_CURSUS devant être unique au monde
|
2020-09-26 16:19:37 +02:00
|
|
|
|
# (avisez sur la liste de diffusion)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# -------------------------
|
2023-02-12 13:36:47 +01:00
|
|
|
|
_tp = list(SCO_CURSUS.items())
|
2020-09-26 16:19:37 +02:00
|
|
|
|
_tp.sort(key=lambda x: x[1].__doc__) # sort by intitulé
|
2023-02-12 13:36:47 +01:00
|
|
|
|
FORMATION_CURSUS_DESCRS = [p[1].__doc__ for p in _tp] # intitulés (eg pour menu)
|
|
|
|
|
FORMATION_CURSUS_TYPES = [p[0] for p in _tp] # codes numeriques (TYPE_CURSUS)
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
|
|
2023-02-21 00:34:39 +01:00
|
|
|
|
def get_cursus_from_code(code_cursus: int) -> TypeCursus:
|
|
|
|
|
"renvoie le cursus de code indiqué"
|
2023-02-12 13:36:47 +01:00
|
|
|
|
cursus = SCO_CURSUS.get(code_cursus)
|
|
|
|
|
if cursus is None:
|
|
|
|
|
log(f"Warning: invalid code_cursus: {code_cursus}")
|
2021-11-09 11:47:48 +01:00
|
|
|
|
# default to legacy
|
2023-02-12 13:36:47 +01:00
|
|
|
|
cursus = SCO_CURSUS.get(0)
|
|
|
|
|
return cursus
|