forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -1,5 +1,16 @@
|
||||
from app.models import Formation, FormSemestre
|
||||
from app.scodoc import codes_cursus
|
||||
from app import log
|
||||
|
||||
PE_DEBUG = 0
|
||||
|
||||
if not PE_DEBUG:
|
||||
# log to notes.log
|
||||
def pe_print(*a, **kw):
|
||||
# kw is ignored. log always add a newline
|
||||
log(" ".join(a))
|
||||
else:
|
||||
pe_print = print # print function
|
||||
|
||||
|
||||
def nom_semestre_etape(semestre: FormSemestre, avec_fid=False) -> str:
|
||||
@ -29,7 +40,7 @@ def nom_semestre_etape(semestre: FormSemestre, avec_fid=False) -> str:
|
||||
f"{semestre.date_debut.year}-{semestre.date_fin.year}",
|
||||
]
|
||||
if avec_fid:
|
||||
description.append(f"({semestre.forsemestre_id})")
|
||||
description.append(f"({semestre.formsemestre_id})")
|
||||
|
||||
return " ".join(description)
|
||||
|
||||
|
@ -45,21 +45,11 @@ import unicodedata
|
||||
from flask import g
|
||||
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app import log
|
||||
|
||||
from app.models import FormSemestre
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc.sco_logos import find_logo
|
||||
|
||||
PE_DEBUG = 0
|
||||
|
||||
if not PE_DEBUG:
|
||||
# log to notes.log
|
||||
def pe_print(*a, **kw):
|
||||
# kw is ignored. log always add a newline
|
||||
log(" ".join(a))
|
||||
|
||||
else:
|
||||
pe_print = print # print function
|
||||
|
||||
|
||||
# Generated LaTeX files are encoded as:
|
||||
|
@ -35,10 +35,9 @@ Created on 17/01/2024
|
||||
|
||||
@author: barasc
|
||||
"""
|
||||
|
||||
import app.pe.pe_comp as pe_comp
|
||||
from app.models import FormSemestre, Identite
|
||||
from app.pe.pe_comp import pe_print
|
||||
import app.pe.pe_affichage as pe_affichage
|
||||
import app.pe.pe_comp as pe_comp
|
||||
|
||||
|
||||
class EtudiantsJuryPE:
|
||||
@ -86,17 +85,17 @@ class EtudiantsJuryPE:
|
||||
cosemestres = pe_comp.get_cosemestres_diplomants(self.annee_diplome, None)
|
||||
self.cosemestres = cosemestres
|
||||
|
||||
pe_comp.pe_print(f"1) Recherche des coSemestres -> {len(cosemestres)} trouvés")
|
||||
pe_affichage.pe_print(f"1) Recherche des coSemestres -> {len(cosemestres)} trouvés")
|
||||
|
||||
pe_comp.pe_print("2) Liste des étudiants dans les différents co-semestres")
|
||||
pe_affichage.pe_print("2) Liste des étudiants dans les différents co-semestres")
|
||||
self.etudiants_ids = get_etudiants_dans_semestres(cosemestres)
|
||||
pe_comp.pe_print(
|
||||
pe_affichage.pe_print(
|
||||
" => %d étudiants trouvés dans les cosemestres" % len(self.etudiants_ids)
|
||||
)
|
||||
|
||||
# Analyse des parcours étudiants pour déterminer leur année effective de diplome
|
||||
# avec prise en compte des redoublements, des abandons, ....
|
||||
pe_comp.pe_print("3) Analyse des parcours individuels des étudiants")
|
||||
pe_affichage.pe_print("3) Analyse des parcours individuels des étudiants")
|
||||
|
||||
no_etud = 0
|
||||
for no_etud, etudid in enumerate(self.etudiants_ids):
|
||||
@ -110,10 +109,6 @@ class EtudiantsJuryPE:
|
||||
# Analyse son parcours pour atteindre chaque semestre de la formation
|
||||
self.structure_cursus_etudiant(etudid)
|
||||
|
||||
if (no_etud + 1) % 10 == 0:
|
||||
pe_comp.pe_print(f"{no_etud + 1}")
|
||||
no_etud += 1
|
||||
pe_comp.pe_print()
|
||||
|
||||
# Les étudiants à prendre dans le diplôme, étudiants ayant abandonnés non compris
|
||||
self.etudiants_diplomes = self.get_etudiants_diplomes()
|
||||
@ -126,23 +121,23 @@ class EtudiantsJuryPE:
|
||||
"""Les formsemestres (des étudiants) dont il faut calculer les moyennes"""
|
||||
|
||||
# Synthèse
|
||||
pe_comp.pe_print(
|
||||
pe_affichage.pe_print(
|
||||
f" => {len(self.etudiants_diplomes)} étudiants à diplômer en {self.annee_diplome}"
|
||||
)
|
||||
nbre_abandons = len(self.etudiants_ids) - len(self.etudiants_diplomes)
|
||||
pe_comp.pe_print(f" => {nbre_abandons} étudiants éliminer pour abandon")
|
||||
pe_comp.pe_print(
|
||||
pe_affichage.pe_print(f" => {nbre_abandons} étudiants non considérés (redoublement, réorientation, abandon")
|
||||
pe_affichage.pe_print(
|
||||
f" => {len(self.formsemestres_jury_ids)} semestres dont il faut calculer la moyenne"
|
||||
)
|
||||
pe_comp.pe_print(
|
||||
" => quelques étudiants futurs diplômés : "
|
||||
+ ", ".join([str(etudid) for etudid in list(self.etudiants_diplomes)[:10]])
|
||||
)
|
||||
pe_comp.pe_print(
|
||||
" => semestres dont il faut calculer les moyennes : "
|
||||
+ ", ".join([str(fid) for fid in list(self.formsemestres_jury_ids)])
|
||||
)
|
||||
# Les abandons :
|
||||
# pe_affichage.pe_print(
|
||||
# " => quelques étudiants futurs diplômés : "
|
||||
# + ", ".join([str(etudid) for etudid in list(self.etudiants_diplomes)[:10]])
|
||||
# )
|
||||
# pe_affichage.pe_print(
|
||||
# " => semestres dont il faut calculer les moyennes : "
|
||||
# + ", ".join([str(fid) for fid in list(self.formsemestres_jury_ids)])
|
||||
# )
|
||||
# Les abandons (pour debug)
|
||||
self.abandons = sorted(
|
||||
[
|
||||
cursus["nom"]
|
||||
@ -416,7 +411,7 @@ def get_etudiants_dans_semestres(semestres: dict[int, FormSemestre]) -> set:
|
||||
for sem in semestres.values(): # pour chacun des semestres de la liste
|
||||
etudiants_du_sem = {ins.etudid for ins in sem.inscriptions}
|
||||
|
||||
pe_print(f" --> {sem} : {len(etudiants_du_sem)} etudiants")
|
||||
pe_affichage.pe_print(f" --> {sem} : {len(etudiants_du_sem)} etudiants")
|
||||
etudiants_ids = (
|
||||
etudiants_ids | etudiants_du_sem
|
||||
) # incluant la suppression des doublons
|
||||
|
@ -1,8 +1,9 @@
|
||||
from app.comp import moy_sem
|
||||
from app.pe.pe_tabletags import TableTag
|
||||
from app.pe.pe_etudiant import EtudiantsJuryPE
|
||||
from app.pe.pe_trajectoire import Trajectoire, TrajectoiresJuryPE
|
||||
from app.pe.pe_trajectoiretag import TrajectoireTag
|
||||
from app.comp import moy_sem
|
||||
|
||||
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
@ -46,29 +46,19 @@ import io
|
||||
import os
|
||||
from zipfile import ZipFile
|
||||
|
||||
|
||||
from app.comp import res_sem
|
||||
from app.comp.res_compat import NotesTableCompat
|
||||
from app.models import FormSemestre
|
||||
from app.models.etudiants import Identite
|
||||
|
||||
from app.scodoc.gen_tables import GenTable, SeqGenTable
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app.scodoc.gen_tables import SeqGenTable
|
||||
from app.pe.pe_etudiant import EtudiantsJuryPE
|
||||
from app.pe.pe_trajectoire import TrajectoiresJuryPE, Trajectoire
|
||||
import app.pe.pe_comp as pe_comp
|
||||
import app.pe.pe_affichage as pe_affichage
|
||||
from app.pe.pe_semtag import SemestreTag
|
||||
from app.pe.pe_interclasstag import AggregatInterclasseTag
|
||||
from app.pe.pe_trajectoiretag import TrajectoireTag
|
||||
import app.pe.pe_affichage as pe_affichage
|
||||
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------
|
||||
class JuryPE(object):
|
||||
"""Classe mémorisant toutes les informations nécessaires pour établir un jury de PE.
|
||||
Modèle basé sur NotesTable.
|
||||
@ -112,7 +102,7 @@ class JuryPE(object):
|
||||
self.zipdata = io.BytesIO()
|
||||
with ZipFile(self.zipdata, "w") as zipfile:
|
||||
# Chargement des étudiants à prendre en compte dans le jury
|
||||
pe_comp.pe_print(
|
||||
pe_affichage.pe_print(
|
||||
f"""*** Recherche et chargement des étudiants diplômés en {
|
||||
self.diplome} pour la formation {self.formation_id}"""
|
||||
)
|
||||
@ -123,42 +113,47 @@ class JuryPE(object):
|
||||
self.diplomes_ids = self.etudiants.diplomes_ids
|
||||
|
||||
# Génère les semestres taggués (avec le calcul des moyennes) pour le jury PE
|
||||
pe_comp.pe_print("*** Génère les semestres taggués")
|
||||
pe_affichage.pe_print("*** Génère les semestres taggués")
|
||||
self.semestres_taggues = compute_semestres_tag(self.etudiants)
|
||||
|
||||
if pe_comp.PE_DEBUG:
|
||||
# Intègre le bilan des semestres taggués au zip final
|
||||
# Intègre le bilan des semestres taggués au zip final
|
||||
output = io.BytesIO()
|
||||
with pd.ExcelWriter(output, engine="openpyxl") as writer:
|
||||
for formsemestretag in self.semestres_taggues.values():
|
||||
filename = formsemestretag.nom.replace(" ", "_") + ".csv"
|
||||
pe_comp.pe_print(f" - Export csv de {filename} ")
|
||||
self.add_file_to_zip(
|
||||
zipfile,
|
||||
filename,
|
||||
formsemestretag.str_tagtable(),
|
||||
path="details_semestres",
|
||||
)
|
||||
onglet = formsemestretag.nom
|
||||
df = formsemestretag.df_semtag()
|
||||
# écriture dans l'onglet
|
||||
df.to_excel(writer, onglet, index=True, header=True)
|
||||
output.seek(0)
|
||||
|
||||
self.add_file_to_zip(
|
||||
zipfile,
|
||||
f"semestres_taggues_{self.diplome}.xlsx",
|
||||
output.read(),
|
||||
path="details",
|
||||
)
|
||||
|
||||
# Génère les trajectoires (combinaison de semestres suivis
|
||||
# par un étudiant pour atteindre le semestre final d'un aggrégat)
|
||||
pe_comp.pe_print(
|
||||
pe_affichage.pe_print(
|
||||
"*** Génère les trajectoires (différentes combinaisons de semestres) des étudiants"
|
||||
)
|
||||
self.trajectoires = TrajectoiresJuryPE(self.diplome)
|
||||
self.trajectoires.cree_trajectoires(self.etudiants)
|
||||
|
||||
# Génère les moyennes par tags des trajectoires
|
||||
pe_comp.pe_print(
|
||||
pe_affichage.pe_print(
|
||||
"*** Calcule les moyennes par tag des trajectoires possibles"
|
||||
)
|
||||
self.trajectoires_tagguees = compute_trajectoires_tag(
|
||||
self.trajectoires, self.etudiants, self.semestres_taggues
|
||||
)
|
||||
|
||||
if pe_comp.PE_DEBUG:
|
||||
if pe_affichage.PE_DEBUG:
|
||||
# Intègre le bilan des trajectoires tagguées au zip final
|
||||
for trajectoire_tagguee in self.trajectoires_tagguees.values():
|
||||
filename = trajectoire_tagguee.get_repr().replace(" ", "_") + ".csv"
|
||||
pe_comp.pe_print(f" - Export csv de {filename} ")
|
||||
# pe_affichage.pe_print(f" - Export csv de {filename} ")
|
||||
self.add_file_to_zip(
|
||||
zipfile,
|
||||
filename,
|
||||
@ -167,16 +162,16 @@ class JuryPE(object):
|
||||
)
|
||||
|
||||
# Génère les interclassements (par promo et) par (nom d') aggrégat
|
||||
pe_comp.pe_print("*** Génère les interclassements par aggrégat")
|
||||
pe_affichage.pe_print("*** Génère les interclassements par aggrégat")
|
||||
self.interclassements_taggues = compute_interclassements(
|
||||
self.etudiants, self.trajectoires, self.trajectoires_tagguees
|
||||
)
|
||||
|
||||
if pe_comp.PE_DEBUG:
|
||||
if pe_affichage.PE_DEBUG:
|
||||
# Intègre le bilan des aggrégats (par promo) au zip final
|
||||
for interclass_tag in self.interclassements_taggues.values():
|
||||
filename = interclass_tag.get_repr().replace(" ", "_") + ".csv"
|
||||
pe_comp.pe_print(f" - Export csv de {filename} ")
|
||||
# pe_affichage.pe_print(f" - Export csv de {filename} ")
|
||||
self.add_file_to_zip(
|
||||
zipfile,
|
||||
filename,
|
||||
@ -188,7 +183,7 @@ class JuryPE(object):
|
||||
self.synthese = self.synthetise_juryPE()
|
||||
|
||||
# Export des données => mode 1 seule feuille -> supprimé
|
||||
pe_comp.pe_print("*** Export du jury de synthese")
|
||||
pe_affichage.pe_print("*** Export du jury de synthese")
|
||||
output = io.BytesIO()
|
||||
|
||||
with pd.ExcelWriter(output, engine="openpyxl") as writer:
|
||||
@ -241,15 +236,15 @@ class JuryPE(object):
|
||||
def synthetise_juryPE(self):
|
||||
"""Synthétise tous les résultats du jury PE dans des dataframes"""
|
||||
|
||||
pe_comp.pe_print("*** Synthèse finale des moyennes ***")
|
||||
pe_affichage.pe_print("*** Synthèse finale des moyennes ***")
|
||||
|
||||
synthese = {}
|
||||
pe_comp.pe_print(" -> Synthèse des données administratives")
|
||||
pe_affichage.pe_print(" -> Synthèse des données administratives")
|
||||
synthese["administratif"] = self.df_administratif()
|
||||
|
||||
tags = self.do_tags_list(self.interclassements_taggues)
|
||||
for tag in tags:
|
||||
pe_comp.pe_print(f" -> Synthèse du tag {tag}")
|
||||
pe_affichage.pe_print(f" -> Synthèse du tag {tag}")
|
||||
synthese[tag] = self.df_tag(tag)
|
||||
return synthese
|
||||
|
||||
@ -325,7 +320,7 @@ class JuryPE(object):
|
||||
donnees[etudid] |= {
|
||||
f"{aggregat} notes ": "-",
|
||||
f"{aggregat} class. (groupe)": "-",
|
||||
f"{aggregat} min/moy/max (groupe)": "-",
|
||||
f"{aggregat} min | moy | max (groupe)": "-",
|
||||
}
|
||||
if trajectoire:
|
||||
trajectoire_tagguee = self.trajectoires_tagguees[
|
||||
@ -335,24 +330,23 @@ class JuryPE(object):
|
||||
bilan = trajectoire_tagguee.moyennes_tags[tag]
|
||||
|
||||
donnees[etudid] |= {
|
||||
f"{aggregat} notes ": round(bilan['notes'].loc[etudid], 2),
|
||||
f"{aggregat} notes ": round(bilan["notes"].loc[etudid], 2),
|
||||
f"{aggregat} class. (groupe)": f"{bilan['classements'].loc[etudid]}/{bilan['nb_inscrits']}",
|
||||
f"{aggregat} min/moy/max (groupe)": f"{bilan['min']:.1f}/{bilan['moy']:.1f}/{bilan['max']:.1f}",
|
||||
f"{aggregat} min | moy | max (groupe)": f"{bilan['min']:.1f} | {bilan['moy']:.1f} | {bilan['max']:.1f}",
|
||||
}
|
||||
|
||||
|
||||
"""L'interclassement"""
|
||||
interclass = self.interclassements_taggues[aggregat]
|
||||
donnees[etudid] |= {
|
||||
f"{aggregat} class. (promo)": "-",
|
||||
f"{aggregat} min/moy/max (promo)": "-",
|
||||
f"{aggregat} min | moy | max (promo)": "-",
|
||||
}
|
||||
if tag in interclass.moyennes_tags:
|
||||
bilan = interclass.moyennes_tags[tag]
|
||||
|
||||
donnees[etudid] |= {
|
||||
f"{aggregat} class. (promo)": f"{bilan['classements'].loc[etudid]}/{bilan['nb_inscrits']}",
|
||||
f"{aggregat} min/moy/max (promo)": f"{bilan['min']:.1f}/{bilan['moy']:.1f}/{bilan['max']:.1f}",
|
||||
f"{aggregat} min | moy | max (promo)": f"{bilan['min']:.1f} | {bilan['moy']:.1f} | {bilan['max']:.1f}",
|
||||
}
|
||||
|
||||
# Fin de l'aggrégat
|
||||
@ -390,7 +384,7 @@ def compute_semestres_tag(etudiants: EtudiantsJuryPE) -> dict:
|
||||
"""
|
||||
|
||||
"""Création des semestres taggués, de type 'S1', 'S2', ..."""
|
||||
pe_comp.pe_print("*** Création des semestres taggués")
|
||||
pe_affichage.pe_print("*** Création des semestres taggués")
|
||||
|
||||
formsemestres = etudiants.get_formsemestres(
|
||||
semestres_recherches=pe_comp.TOUS_LES_SEMESTRES
|
||||
@ -398,19 +392,11 @@ def compute_semestres_tag(etudiants: EtudiantsJuryPE) -> dict:
|
||||
|
||||
semestres_tags = {}
|
||||
for frmsem_id, formsemestre in formsemestres.items():
|
||||
"""Choix d'un nom pour le semestretag"""
|
||||
nom = "S%d %d %d-%d" % (
|
||||
formsemestre.semestre_id,
|
||||
frmsem_id,
|
||||
formsemestre.date_debut.year,
|
||||
formsemestre.date_fin.year,
|
||||
)
|
||||
|
||||
pe_comp.pe_print(f" --> Semestre taggué {nom} sur la base de {formsemestre}")
|
||||
|
||||
# Crée le semestre_tag et exécute les calculs de moyennes
|
||||
formsemestretag = SemestreTag(nom, frmsem_id)
|
||||
|
||||
formsemestretag = SemestreTag(frmsem_id)
|
||||
pe_affichage.pe_print(
|
||||
f" --> Semestre taggué {formsemestretag.nom} sur la base de {formsemestre}"
|
||||
)
|
||||
# Stocke le semestre taggué
|
||||
semestres_tags[frmsem_id] = formsemestretag
|
||||
|
||||
@ -443,23 +429,16 @@ def compute_trajectoires_tag(
|
||||
semestres_tag: Les semestres tag (pour lesquels des moyennes par tag ont été calculés)
|
||||
|
||||
Return:
|
||||
Un dictionnaire de la forme {nom_aggregat: {fid_terminal: SetTag(fid_terminal)} }
|
||||
Un dictionnaire de la forme ``{nom_aggregat: {fid_terminal: SetTag(fid_terminal)} }``
|
||||
"""
|
||||
|
||||
pe_comp.pe_print(" *** Création des aggrégats ")
|
||||
|
||||
trajectoires_tagguees = {}
|
||||
|
||||
for trajectoire_id in trajectoires.trajectoires:
|
||||
trajectoire = trajectoires.trajectoires[trajectoire_id]
|
||||
for trajectoire_id, trajectoire in trajectoires.trajectoires.items():
|
||||
nom = trajectoire.get_repr()
|
||||
|
||||
pe_comp.pe_print(f" --> Fusion {nom}")
|
||||
|
||||
pe_affichage.pe_print(f" --> Aggrégat {nom}")
|
||||
# Trajectoire_tagguee associée
|
||||
trajectoire_tagguee = TrajectoireTag(nom, trajectoire, semestres_taggues)
|
||||
"""Trajectoire_tagguee associée"""
|
||||
|
||||
"""Mémorise le résultat"""
|
||||
# Mémorise le résultat
|
||||
trajectoires_tagguees[trajectoire_id] = trajectoire_tagguee
|
||||
|
||||
return trajectoires_tagguees
|
||||
@ -474,11 +453,9 @@ def compute_interclassements(
|
||||
pour fournir un classement sur la promo. Le classement est établi au regard du nombre
|
||||
d'étudiants ayant participé au même aggrégat.
|
||||
"""
|
||||
pe_comp.pe_print(" Interclassement sur la promo")
|
||||
|
||||
aggregats_interclasses_taggues = {}
|
||||
for nom_aggregat in pe_comp.TOUS_LES_SEMESTRES + pe_comp.TOUS_LES_AGGREGATS:
|
||||
pe_comp.pe_print(f" --> {nom_aggregat}")
|
||||
pe_affichage.pe_print(f" --> Interclassement {nom_aggregat}")
|
||||
interclass = AggregatInterclasseTag(
|
||||
nom_aggregat, etudiants, trajectoires_jury_pe, trajectoires_tagguees
|
||||
)
|
||||
|
@ -45,63 +45,63 @@ from app.models.moduleimpls import ModuleImpl
|
||||
|
||||
from app.scodoc import sco_tag_module
|
||||
from app.scodoc.codes_cursus import UE_SPORT
|
||||
import app.pe.pe_comp as pe_comp
|
||||
from app.pe.pe_tabletags import (TableTag, TAGS_RESERVES)
|
||||
import app.pe.pe_affichage as pe_affichage
|
||||
from app.pe.pe_tabletags import TableTag, TAGS_RESERVES
|
||||
import pandas as pd
|
||||
|
||||
class SemestreTag(TableTag):
|
||||
"""Un SemestreTag représente les résultats des étudiants à un semestre, en donnant
|
||||
accès aux moyennes par tag.
|
||||
Il s'appuie principalement sur FormSemestre et sur ResultatsSemestreBUT.
|
||||
"""
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Fonctions d'initialisation
|
||||
# -----------------------------------------------------------------------------
|
||||
def __init__(self, nom: str, formsemestre_id: int):
|
||||
def __init__(self, formsemestre_id: int):
|
||||
"""
|
||||
Un SemestreTag représente les résultats des étudiants à un semestre, en donnant
|
||||
accès aux moyennes par tag.
|
||||
Il s'appuie principalement sur FormSemestre et sur ResultatsSemestreBUT.
|
||||
|
||||
Args:
|
||||
nom: Nom à donner au SemestreTag
|
||||
formsemestre_id: Identifiant du FormSemestre sur lequel il se base
|
||||
formsemestre_id: Identifiant du ``FormSemestre`` sur lequel il se base
|
||||
"""
|
||||
TableTag.__init__(self, nom=nom)
|
||||
# TableTag.__init__(self, nom=nom)
|
||||
|
||||
"""Le semestre"""
|
||||
# Le semestre
|
||||
self.formsemestre_id = formsemestre_id
|
||||
self.formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||
|
||||
"""Les résultats du semestre"""
|
||||
# Le nom du semestre taggué
|
||||
self.nom = self.get_repr()
|
||||
|
||||
# Les résultats du semestre
|
||||
self.nt = load_formsemestre_results(self.formsemestre)
|
||||
|
||||
"""Les étudiants"""
|
||||
# Les étudiants
|
||||
self.etuds = self.nt.etuds
|
||||
self.etudiants = {etud.etudid: etud.etat_civil for etud in self.etuds}
|
||||
|
||||
"""Les notes, les modules implémentés triés, les étudiants, les coeffs,
|
||||
récupérés notamment de py:mod:`res_but`
|
||||
"""
|
||||
# Les notes, les modules implémentés triés, les étudiants, les coeffs,
|
||||
# récupérés notamment de py:mod:`res_but`
|
||||
self.sem_cube = self.nt.sem_cube
|
||||
self.modimpls_sorted = self.nt.formsemestre.modimpls_sorted
|
||||
self.modimpl_coefs_df = self.nt.modimpl_coefs_df
|
||||
|
||||
"""Les inscriptions au module et les dispenses d'UE"""
|
||||
# Les inscriptions au module et les dispenses d'UE
|
||||
self.modimpl_inscr_df = self.nt.modimpl_inscr_df
|
||||
self.ues = self.nt.ues
|
||||
self.ues_inscr_parcours_df = self.nt.load_ues_inscr_parcours()
|
||||
self.dispense_ues = self.nt.dispense_ues
|
||||
|
||||
"""Les tags (en supprimant les tags réservés)"""
|
||||
# Les tags (en supprimant les tags réservés)
|
||||
self.tags = get_synthese_tags_semestre(self.nt.formsemestre)
|
||||
for tag in TAGS_RESERVES:
|
||||
if tag in self.tags:
|
||||
del self.tags[tag]
|
||||
|
||||
"""Calcul des moyennes & les classements de chaque étudiant à chaque tag"""
|
||||
# Calcul des moyennes & les classements de chaque étudiant à chaque tag
|
||||
self.moyennes_tags = {}
|
||||
|
||||
for tag in self.tags:
|
||||
pe_comp.pe_print(f" -> Traitement du tag {tag}")
|
||||
# pe_affichage.pe_print(f" -> Traitement du tag {tag}")
|
||||
moy_gen_tag = self.compute_moyenne_tag(tag)
|
||||
class_gen_tag = moy_sem.comp_ranks_series(moy_gen_tag)[1] # en int
|
||||
class_gen_tag = moy_sem.comp_ranks_series(moy_gen_tag)[1] # en int
|
||||
self.moyennes_tags[tag] = {
|
||||
"notes": moy_gen_tag,
|
||||
"classements": class_gen_tag,
|
||||
@ -111,8 +111,7 @@ class SemestreTag(TableTag):
|
||||
"nb_inscrits": len(moy_gen_tag),
|
||||
}
|
||||
|
||||
"""Ajoute les moyennes générales de BUT pour le semestre considéré"""
|
||||
pe_comp.pe_print(f" -> Traitement du tag but")
|
||||
# Ajoute les moyennes générales de BUT pour le semestre considéré
|
||||
moy_gen_but = self.nt.etud_moy_gen
|
||||
class_gen_but = self.nt.etud_moy_gen_ranks_int
|
||||
self.moyennes_tags["but"] = {
|
||||
@ -124,16 +123,18 @@ class SemestreTag(TableTag):
|
||||
"nb_inscrits": len(moy_gen_but),
|
||||
}
|
||||
|
||||
"""Synthétise l'ensemble des moyennes dans un dataframe"""
|
||||
self.tags_sorted = sorted(self.moyennes_tags) # les tags par ordre alphabétique
|
||||
self.notes = self.df_tagtable() # Le dataframe synthétique des notes (=moyennes par tag)
|
||||
# Synthétise l'ensemble des moyennes dans un dataframe
|
||||
self.tags_sorted = sorted(self.moyennes_tags) # les tags par ordre alphabétique
|
||||
self.notes = (
|
||||
self.df_tagtable()
|
||||
) # Le dataframe synthétique des notes (=moyennes par tag)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_etudids(self):
|
||||
"""Renvoie la liste des etud_id des étudiants inscrits au semestre"""
|
||||
return [etud["etudid"] for etud in self.inscrlist]
|
||||
pe_affichage.pe_print(f" => Traitement des tags {', '.join(self.tags_sorted)}")
|
||||
|
||||
def get_repr(self):
|
||||
"""Nom affiché pour le semestre taggué"""
|
||||
return pe_affichage.nom_semestre_etape(self.formsemestre, avec_fid=True)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def compute_moyenne_tag(self, tag: str) -> list:
|
||||
"""Calcule la moyenne des étudiants pour le tag indiqué,
|
||||
pour ce SemestreTag.
|
||||
@ -192,14 +193,22 @@ class SemestreTag(TableTag):
|
||||
|
||||
return moy_gen_tag
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_noteEtCoeff_modimpl(self, modimpl_id, etudid, profondeur=2):
|
||||
"""Renvoie un couple donnant la note et le coeff normalisé d'un étudiant à un module d'id modimpl_id.
|
||||
La note et le coeff sont extraits :
|
||||
1) soit des données du semestre en normalisant le coefficient par rapport à la somme des coefficients des modules du semestre,
|
||||
2) soit des données des UE précédemment capitalisées, en recherchant un module de même CODE que le modimpl_id proposé,
|
||||
le coefficient normalisé l'étant alors par rapport au total des coefficients du semestre auquel appartient l'ue capitalisée
|
||||
|
||||
TODO:: A rependre si nécessaire
|
||||
"""
|
||||
|
||||
def get_ue_capitalisees(etudid) -> list[dict]:
|
||||
"""Renvoie la liste des capitalisation effectivement capitalisées par un étudiant"""
|
||||
if etudid in self.nt.validations.ue_capitalisees.index:
|
||||
return self.nt.validations.ue_capitalisees.loc[[etudid]].to_dict("records")
|
||||
return []
|
||||
|
||||
(note, coeff_norm) = (None, None)
|
||||
|
||||
modimpl = get_moduleimpl(modimpl_id) # Le module considéré
|
||||
@ -207,7 +216,7 @@ class SemestreTag(TableTag):
|
||||
return (None, None)
|
||||
|
||||
# Y-a-t-il eu capitalisation d'UE ?
|
||||
ue_capitalisees = self.get_ue_capitalisees(
|
||||
ue_capitalisees = get_ue_capitalisees(
|
||||
etudid
|
||||
) # les ue capitalisées des étudiants
|
||||
ue_capitalisees_id = {
|
||||
@ -273,130 +282,18 @@ class SemestreTag(TableTag):
|
||||
# Sinon - pas de notes à prendre en compte
|
||||
return (note, coeff_norm)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_ue_capitalisees(self, etudid) -> list[dict]:
|
||||
"""Renvoie la liste des capitalisation effectivement capitalisées par un étudiant"""
|
||||
if etudid in self.nt.validations.ue_capitalisees.index:
|
||||
return self.nt.validations.ue_capitalisees.loc[[etudid]].to_dict("records")
|
||||
return []
|
||||
def df_semtag(self):
|
||||
"""Renvoie un dataframe listant toutes les moyennes,
|
||||
les rangs des étudiants pour tous les tags dans le semestre taggué"""
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Fonctions d'affichage (et d'export csv) des données du semestre en mode debug
|
||||
# -----------------------------------------------------------------------------
|
||||
def str_detail_resultat_d_un_tag(self, tag, etudid=None, delim=";"):
|
||||
"""Renvoie une chaine de caractère décrivant les résultats d'étudiants à un tag :
|
||||
rappelle les notes obtenues dans les modules à prendre en compte, les moyennes et les rangs calculés.
|
||||
Si etudid=None, tous les étudiants inscrits dans le semestre sont pris en compte. Sinon seuls les étudiants indiqués sont affichés.
|
||||
"""
|
||||
# Entete
|
||||
chaine = delim.join(["%15s" % "nom", "etudid"]) + delim
|
||||
taglist = self.get_all_tags()
|
||||
if tag in taglist:
|
||||
for mod in self.tagdict[tag].values():
|
||||
chaine += mod["module_code"] + delim
|
||||
chaine += ("%1.1f" % mod["ponderation"]) + delim
|
||||
chaine += "coeff" + delim
|
||||
chaine += delim.join(
|
||||
["moyenne", "rang", "nbinscrit", "somme_coeff", "somme_coeff"]
|
||||
) # ligne 1
|
||||
chaine += "\n"
|
||||
etudiants = self.etudiants
|
||||
df = pd.DataFrame.from_dict(etudiants, orient="index", columns=["nom"])
|
||||
|
||||
# Différents cas de boucles sur les étudiants (de 1 à plusieurs)
|
||||
if etudid == None:
|
||||
lesEtuds = self.get_etudids()
|
||||
elif isinstance(etudid, str) and etudid in self.get_etudids():
|
||||
lesEtuds = [etudid]
|
||||
elif isinstance(etudid, list):
|
||||
lesEtuds = [eid for eid in self.get_etudids() if eid in etudid]
|
||||
else:
|
||||
lesEtuds = []
|
||||
|
||||
for etudid in lesEtuds:
|
||||
descr = (
|
||||
"%15s" % self.nt.get_nom_short(etudid)[:15]
|
||||
+ delim
|
||||
+ str(etudid)
|
||||
+ delim
|
||||
)
|
||||
if tag in taglist:
|
||||
for modimpl_id in self.tagdict[tag]:
|
||||
(note, coeff) = self.get_noteEtCoeff_modimpl(modimpl_id, etudid)
|
||||
descr += (
|
||||
(
|
||||
"%2.2f" % note
|
||||
if note != None and isinstance(note, float)
|
||||
else str(note)
|
||||
)
|
||||
+ delim
|
||||
+ (
|
||||
"%1.5f" % coeff
|
||||
if coeff != None and isinstance(coeff, float)
|
||||
else str(coeff)
|
||||
)
|
||||
+ delim
|
||||
+ (
|
||||
"%1.5f" % (coeff * self.somme_coeffs)
|
||||
if coeff != None and isinstance(coeff, float)
|
||||
else "???" # str(coeff * self._sum_coeff_semestre) # voir avec Cléo
|
||||
)
|
||||
+ delim
|
||||
)
|
||||
moy = self.get_moy_from_resultats(tag, etudid)
|
||||
rang = self.get_rang_from_resultats(tag, etudid)
|
||||
coeff = self.get_coeff_from_resultats(tag, etudid)
|
||||
tot = (
|
||||
coeff * self.somme_coeffs
|
||||
if coeff != None
|
||||
and self.somme_coeffs != None
|
||||
and isinstance(coeff, float)
|
||||
else None
|
||||
)
|
||||
descr += (
|
||||
pe_tagtable.TableTag.str_moytag(
|
||||
moy, rang, len(self.get_etudids()), delim=delim
|
||||
)
|
||||
+ delim
|
||||
)
|
||||
descr += (
|
||||
(
|
||||
"%1.5f" % coeff
|
||||
if coeff != None and isinstance(coeff, float)
|
||||
else str(coeff)
|
||||
)
|
||||
+ delim
|
||||
+ (
|
||||
"%.2f" % (tot)
|
||||
if tot != None
|
||||
else str(coeff) + "*" + str(self.somme_coeffs)
|
||||
)
|
||||
)
|
||||
chaine += descr
|
||||
chaine += "\n"
|
||||
return chaine
|
||||
|
||||
def str_tagsModulesEtCoeffs(self):
|
||||
"""Renvoie une chaine affichant la liste des tags associés au semestre,
|
||||
les modules qui les concernent et les coeffs de pondération.
|
||||
Plus concrètement permet d'afficher le contenu de self._tagdict"""
|
||||
chaine = "Semestre %s d'id %d" % (self.nom, id(self)) + "\n"
|
||||
chaine += " -> somme de coeffs: " + str(self.somme_coeffs) + "\n"
|
||||
taglist = self.get_all_tags()
|
||||
for tag in taglist:
|
||||
chaine += " > " + tag + ": "
|
||||
for modid, mod in self.tagdict[tag].items():
|
||||
chaine += (
|
||||
mod["module_code"]
|
||||
+ " ("
|
||||
+ str(mod["coeff"])
|
||||
+ "*"
|
||||
+ str(mod["ponderation"])
|
||||
+ ") "
|
||||
+ str(modid)
|
||||
+ ", "
|
||||
)
|
||||
chaine += "\n"
|
||||
return chaine
|
||||
for tag in self.get_all_tags():
|
||||
df = df.join(self.moyennes_tags[tag]["notes"].rename(f"Moy {tag}"))
|
||||
df = df.join(self.moyennes_tags[tag]["classements"].rename(f"Class {tag}"))
|
||||
|
||||
return df
|
||||
|
||||
# ************************************************************************
|
||||
# Fonctions diverses
|
||||
@ -437,8 +334,8 @@ def get_moy_ue_from_nt(nt, etudid, modimpl_id) -> float:
|
||||
def get_synthese_tags_semestre(formsemestre: FormSemestre):
|
||||
"""Etant données les implémentations des modules du semestre (modimpls),
|
||||
synthétise les tags les concernant (tags saisis dans le programme pédagogique)
|
||||
en les associant aux modimpls qui les concernent (modimpl_id, module_id,
|
||||
le code du module, coeff et pondération fournie avec le tag (par défaut 1 si non indiquée)).
|
||||
en les associant aux modimpls qui les concernent (modimpl_id) et
|
||||
aucoeff et pondération fournie avec le tag (par défaut 1 si non indiquée)).
|
||||
|
||||
{ tagname1: { modimpl_id1: { 'module_id': ...,
|
||||
'coeff': ...,
|
||||
@ -451,6 +348,9 @@ def get_synthese_tags_semestre(formsemestre: FormSemestre):
|
||||
|
||||
Args:
|
||||
formsemestre: Le formsemestre à la base de la recherche des tags
|
||||
|
||||
Return:
|
||||
Un dictionnaire de tags
|
||||
"""
|
||||
synthese_tags = {}
|
||||
|
||||
|
@ -91,188 +91,6 @@ class TableTag(object):
|
||||
return sorted(self.moyennes_tags.keys())
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# Accesseurs
|
||||
# *****************************************************************************************************************
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
def get_moy_from_resultats(self, tag, etudid):
|
||||
"""Renvoie la moyenne obtenue par un étudiant à un tag donné au regard du format de self.resultats"""
|
||||
return (
|
||||
self.moyennes_tags[tag][etudid][0]
|
||||
if tag in self.moyennes_tags and etudid in self.moyennes_tags[tag]
|
||||
else None
|
||||
)
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
def get_rang_from_resultats(self, tag, etudid):
|
||||
"""Renvoie le rang à un tag d'un étudiant au regard du format de self.resultats"""
|
||||
return (
|
||||
self.rangs[tag][etudid]
|
||||
if tag in self.moyennes_tags and etudid in self.moyennes_tags[tag]
|
||||
else None
|
||||
)
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
def get_coeff_from_resultats(self, tag, etudid):
|
||||
"""Renvoie la somme des coeffs de pondération normalisée utilisés dans le calcul de la moyenne à un tag d'un étudiant
|
||||
au regard du format de self.resultats.
|
||||
"""
|
||||
return (
|
||||
self.moyennes_tags[tag][etudid][1]
|
||||
if tag in self.moyennes_tags and etudid in self.moyennes_tags[tag]
|
||||
else None
|
||||
)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
def get_nbinscrits(self):
|
||||
"""Renvoie le nombre d'inscrits"""
|
||||
return len(self.inscrlist)
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
def get_moy_from_stats(self, tag):
|
||||
"""Renvoie la moyenne des notes calculées pour d'un tag donné"""
|
||||
return self.statistiques[tag][0] if tag in self.statistiques else None
|
||||
|
||||
def get_min_from_stats(self, tag):
|
||||
"""Renvoie la plus basse des notes calculées pour d'un tag donné"""
|
||||
return self.statistiques[tag][1] if tag in self.statistiques else None
|
||||
|
||||
def get_max_from_stats(self, tag):
|
||||
"""Renvoie la plus haute des notes calculées pour d'un tag donné"""
|
||||
return self.statistiques[tag][2] if tag in self.statistiques else None
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
# La structure des données mémorisées pour chaque tag dans le dictionnaire de synthèse
|
||||
# d'un jury PE
|
||||
FORMAT_DONNEES_ETUDIANTS = (
|
||||
"note",
|
||||
"coeff",
|
||||
"rang",
|
||||
"nbinscrits",
|
||||
"moy",
|
||||
"max",
|
||||
"min",
|
||||
)
|
||||
|
||||
def get_resultatsEtud(self, tag, etudid):
|
||||
"""Renvoie un tuple (note, coeff, rang, nb_inscrit, moy, min, max) synthétisant les résultats d'un étudiant
|
||||
à un tag donné. None sinon"""
|
||||
return (
|
||||
self.get_moy_from_resultats(tag, etudid),
|
||||
self.get_coeff_from_resultats(tag, etudid),
|
||||
self.get_rang_from_resultats(tag, etudid),
|
||||
self.get_nbinscrits(),
|
||||
self.get_moy_from_stats(tag),
|
||||
self.get_min_from_stats(tag),
|
||||
self.get_max_from_stats(tag),
|
||||
)
|
||||
|
||||
# return self.tag_stats[tag]
|
||||
# else :
|
||||
# return self.pe_stats
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# Ajout des notes
|
||||
# *****************************************************************************************************************
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
def add_moyennesTag(self, tag, listMoyEtCoeff) -> bool:
|
||||
"""
|
||||
Mémorise les moyennes, les coeffs de pondération et les etudid dans resultats
|
||||
avec calcul du rang
|
||||
:param tag: Un tag
|
||||
:param listMoyEtCoeff: Une liste donnant [ (moy, coeff, etudid) ]
|
||||
|
||||
TODO:: Inutile maintenant ?
|
||||
"""
|
||||
# ajout des moyennes au dictionnaire résultat
|
||||
if listMoyEtCoeff:
|
||||
self.moyennes_tags[tag] = {
|
||||
etudid: (moyenne, somme_coeffs)
|
||||
for (moyenne, somme_coeffs, etudid) in listMoyEtCoeff
|
||||
}
|
||||
|
||||
# Calcule les rangs
|
||||
lesMoyennesTriees = sorted(
|
||||
listMoyEtCoeff,
|
||||
reverse=True,
|
||||
key=lambda col: col[0]
|
||||
if isinstance(col[0], float)
|
||||
else 0, # remplace les None et autres chaines par des zéros
|
||||
) # triées
|
||||
self.rangs[tag] = scu.comp_ranks(lesMoyennesTriees) # les rangs
|
||||
|
||||
# calcul des stats
|
||||
self.comp_stats_d_un_tag(tag)
|
||||
return True
|
||||
return False
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# Méthodes dévolues aux calculs de statistiques (min, max, moy) sur chaque moyenne taguée
|
||||
# *****************************************************************************************************************
|
||||
|
||||
def comp_stats_d_un_tag(self, tag):
|
||||
"""
|
||||
Calcule la moyenne generale, le min, le max pour un tag donné,
|
||||
en ne prenant en compte que les moyennes significatives. Mémorise le resultat dans
|
||||
self.statistiques
|
||||
"""
|
||||
stats = ("-NA-", "-", "-")
|
||||
if tag not in self.moyennes_tags:
|
||||
return stats
|
||||
|
||||
notes = [
|
||||
self.get_moy_from_resultats(tag, etudid)
|
||||
for etudid in self.moyennes_tags[tag]
|
||||
] # les notes du tag
|
||||
notes_valides = [
|
||||
note for note in notes if isinstance(note, float) and note != None
|
||||
]
|
||||
nb_notes_valides = len(notes_valides)
|
||||
if nb_notes_valides > 0:
|
||||
(moy, _) = moyenne_ponderee_terme_a_terme(notes_valides, force=True)
|
||||
self.statistiques[tag] = (moy, max(notes_valides), min(notes_valides))
|
||||
|
||||
# ************************************************************************
|
||||
# Méthodes dévolues aux affichages -> a revoir
|
||||
# ************************************************************************
|
||||
def str_resTag_d_un_etudiant(self, tag, etudid, delim=";"):
|
||||
"""Renvoie une chaine de caractères (valable pour un csv)
|
||||
décrivant la moyenne et le rang d'un étudiant, pour un tag donné ;
|
||||
"""
|
||||
if tag not in self.get_all_tags() or etudid not in self.moyennes_tags[tag]:
|
||||
return ""
|
||||
|
||||
moystr = TableTag.str_moytag(
|
||||
self.get_moy_from_resultats(tag, etudid),
|
||||
self.get_rang_from_resultats(tag, etudid),
|
||||
self.get_nbinscrits(),
|
||||
delim=delim,
|
||||
)
|
||||
return moystr
|
||||
|
||||
def str_res_d_un_etudiant(self, etudid, delim=";"):
|
||||
"""Renvoie sur une ligne les résultats d'un étudiant à tous les tags (par ordre alphabétique)."""
|
||||
return delim.join(
|
||||
[self.str_resTag_d_un_etudiant(tag, etudid) for tag in self.get_all_tags()]
|
||||
)
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
def str_moytag(cls, moyenne, rang, nbinscrit, delim=";"):
|
||||
"""Renvoie une chaine de caractères représentant une moyenne (float ou string) et un rang
|
||||
pour différents formats d'affichage : HTML, debug ligne de commande, csv"""
|
||||
moystr = (
|
||||
"%2.2f%s%s%s%d" % (moyenne, delim, rang, delim, nbinscrit)
|
||||
if isinstance(moyenne, float)
|
||||
else str(moyenne) + delim + str(rang) + delim + str(nbinscrit)
|
||||
)
|
||||
return moystr
|
||||
|
||||
str_moytag = classmethod(str_moytag)
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
def df_tagtable(self):
|
||||
"""Renvoie un dataframe (etudid x tag) listant toutes les moyennes par tags
|
||||
|
||||
@ -300,68 +118,3 @@ class TableTag(object):
|
||||
|
||||
return df.to_csv(sep=";")
|
||||
|
||||
|
||||
# ************************************************************************
|
||||
# Fonctions diverses
|
||||
# ************************************************************************
|
||||
|
||||
|
||||
# *********************************************
|
||||
def moyenne_ponderee_terme_a_terme(notes, coefs=None, force=False):
|
||||
"""
|
||||
Calcule la moyenne pondérée d'une liste de notes avec d'éventuels coeffs de pondération.
|
||||
Renvoie le résultat sous forme d'un tuple (moy, somme_coeff)
|
||||
|
||||
La liste de notes contient soit :
|
||||
1) des valeurs numériques
|
||||
2) des strings "-NA-" (pas de notes) ou "-NI-" (pas inscrit) ou "-c-" ue capitalisée,
|
||||
3) None.
|
||||
|
||||
Le paramètre force indique si le calcul de la moyenne doit être forcée ou non, c'est à
|
||||
dire s'il y a ou non omission des notes non numériques (auquel cas la moyenne est
|
||||
calculée sur les notes disponibles) ; sinon renvoie (None, None).
|
||||
"""
|
||||
# Vérification des paramètres d'entrée
|
||||
if not isinstance(notes, list) or (
|
||||
coefs != None and not isinstance(coefs, list) and len(coefs) != len(notes)
|
||||
):
|
||||
raise ValueError("Erreur de paramètres dans moyenne_ponderee_terme_a_terme")
|
||||
|
||||
# Récupération des valeurs des paramètres d'entrée
|
||||
coefs = [1] * len(notes) if coefs is None else coefs
|
||||
|
||||
# S'il n'y a pas de notes
|
||||
if not notes: # Si notes = []
|
||||
return (None, None)
|
||||
|
||||
# Liste indiquant les notes valides
|
||||
notes_valides = [
|
||||
(isinstance(note, float) and not np.isnan(note)) or isinstance(note, int)
|
||||
for note in notes
|
||||
]
|
||||
# Si on force le calcul de la moyenne ou qu'on ne le force pas
|
||||
# et qu'on a le bon nombre de notes
|
||||
if force or sum(notes_valides) == len(notes):
|
||||
moyenne, ponderation = 0.0, 0.0
|
||||
for i in range(len(notes)):
|
||||
if notes_valides[i]:
|
||||
moyenne += coefs[i] * notes[i]
|
||||
ponderation += coefs[i]
|
||||
return (
|
||||
(moyenne / (ponderation * 1.0), ponderation)
|
||||
if ponderation != 0
|
||||
else (None, 0)
|
||||
)
|
||||
# Si on ne force pas le calcul de la moyenne
|
||||
return (None, None)
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------------------------
|
||||
def conversionDate_StrToDate(date_fin):
|
||||
"""Conversion d'une date fournie sous la forme d'une chaine de caractère de
|
||||
type 'jj/mm/aaaa' en un objet date du package datetime.
|
||||
Fonction servant au tri des semestres par date
|
||||
"""
|
||||
(d, m, y) = [int(x) for x in date_fin.split("/")]
|
||||
date_fin_dst = datetime.date(y, m, d)
|
||||
return date_fin_dst
|
||||
|
@ -1,4 +1,6 @@
|
||||
import app.pe.pe_comp as pe_comp
|
||||
import app.pe.pe_affichage as pe_affichage
|
||||
|
||||
from app.models import FormSemestre
|
||||
from app.pe.pe_etudiant import EtudiantsJuryPE, get_dernier_semestre_en_date
|
||||
|
||||
@ -129,7 +131,7 @@ def get_trajectoires_etudid(trajectoires, etudid):
|
||||
trajectoires suivies par un étudiant
|
||||
"""
|
||||
if etudid not in trajectoires.suivi:
|
||||
pe_comp.pe_print(f"{etudid} fait-il bien partie du jury ?")
|
||||
pe_affichage.pe_print(f"{etudid} fait-il bien partie du jury ?")
|
||||
|
||||
liste = []
|
||||
for aggregat in pe_comp.TOUS_LES_PARCOURS:
|
||||
|
@ -39,12 +39,10 @@ Created on Fri Sep 9 09:15:05 2016
|
||||
from app.comp import moy_sem
|
||||
from app.comp.res_sem import load_formsemestre_results
|
||||
from app.pe.pe_semtag import SemestreTag
|
||||
from app.pe import pe_tabletags
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from app.pe.pe_trajectoire import Trajectoire
|
||||
|
||||
from app.pe.pe_etudiant import EtudiantsJuryPE
|
||||
from app.pe.pe_tabletags import TableTag
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user