forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -9,7 +9,7 @@
|
|||||||
from flask import g
|
from flask import g
|
||||||
from app import log
|
from app import log
|
||||||
|
|
||||||
PE_DEBUG = False
|
PE_DEBUG = True
|
||||||
|
|
||||||
|
|
||||||
# On stocke les logs PE dans g.scodoc_pe_log
|
# On stocke les logs PE dans g.scodoc_pe_log
|
||||||
@ -22,14 +22,15 @@ def pe_start_log() -> list[str]:
|
|||||||
|
|
||||||
def pe_print(*a):
|
def pe_print(*a):
|
||||||
"Log (or print in PE_DEBUG mode) and store in g"
|
"Log (or print in PE_DEBUG mode) and store in g"
|
||||||
lines = getattr(g, "scodoc_pe_log")
|
|
||||||
if lines is None:
|
|
||||||
lines = pe_start_log()
|
|
||||||
msg = " ".join(a)
|
|
||||||
lines.append(msg)
|
|
||||||
if PE_DEBUG:
|
if PE_DEBUG:
|
||||||
|
msg = " ".join(a)
|
||||||
print(msg)
|
print(msg)
|
||||||
else:
|
else:
|
||||||
|
lines = getattr(g, "scodoc_pe_log")
|
||||||
|
if lines is None:
|
||||||
|
lines = pe_start_log()
|
||||||
|
msg = " ".join(a)
|
||||||
|
lines.append(msg)
|
||||||
log(msg)
|
log(msg)
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ class SemestreTag(TableTag):
|
|||||||
# Les étudiants
|
# Les étudiants
|
||||||
self.etuds = self.nt.etuds
|
self.etuds = self.nt.etuds
|
||||||
self.etudiants = {etud.etudid: etud.etat_civil for etud in self.etuds}
|
self.etudiants = {etud.etudid: etud.etat_civil for etud in self.etuds}
|
||||||
|
self.etudids = list(self.etudiants.keys())
|
||||||
|
|
||||||
# Les notes, les modules implémentés triés, les étudiants, les coeffs,
|
# Les notes, les modules implémentés triés, les étudiants, les coeffs,
|
||||||
# récupérés notamment de py:mod:`res_but`
|
# récupérés notamment de py:mod:`res_but`
|
||||||
@ -94,12 +95,12 @@ class SemestreTag(TableTag):
|
|||||||
tags_personnalises = get_synthese_tags_personnalises_semestre(
|
tags_personnalises = get_synthese_tags_personnalises_semestre(
|
||||||
self.nt.formsemestre
|
self.nt.formsemestre
|
||||||
)
|
)
|
||||||
noms_tags_perso = list(set(tags_personnalises.keys()))
|
noms_tags_perso = sorted(list(set(tags_personnalises.keys())))
|
||||||
|
|
||||||
## Déduit des compétences
|
## Déduit des compétences
|
||||||
dict_ues_competences = get_noms_competences_from_ues(self.nt.formsemestre)
|
# dict_ues_competences = get_noms_competences_from_ues(self.nt.formsemestre)
|
||||||
noms_tags_comp = list(set(dict_ues_competences.values()))
|
# noms_tags_comp = list(set(dict_ues_competences.values()))
|
||||||
noms_tags_auto = ["but"] + noms_tags_comp
|
noms_tags_auto = ["but"] # + noms_tags_comp
|
||||||
self.tags = noms_tags_perso + noms_tags_auto
|
self.tags = noms_tags_perso + noms_tags_auto
|
||||||
"""Tags du semestre taggué"""
|
"""Tags du semestre taggué"""
|
||||||
|
|
||||||
@ -122,23 +123,31 @@ class SemestreTag(TableTag):
|
|||||||
"""
|
"""
|
||||||
raise ScoValueError(message)
|
raise ScoValueError(message)
|
||||||
|
|
||||||
|
ues_hors_sport = [ue for ue in self.ues if ue.type != UE_SPORT]
|
||||||
|
|
||||||
# Calcul des moyennes & les classements de chaque étudiant à chaque tag
|
# Calcul des moyennes & les classements de chaque étudiant à chaque tag
|
||||||
self.moyennes_tags = {}
|
self.moyennes_tags = {}
|
||||||
|
|
||||||
for tag in tags_personnalises:
|
for tag in tags_personnalises:
|
||||||
# pe_affichage.pe_print(f" -> Traitement du tag {tag}")
|
# pe_affichage.pe_print(f" -> Traitement du tag {tag}")
|
||||||
moy_gen_tag = self.compute_moyenne_tag(tag, tags_personnalises)
|
moy_ues_tag = self.compute_moy_ues_tag(tag, tags_personnalises)
|
||||||
self.moyennes_tags[tag] = MoyenneTag(tag, moy_gen_tag)
|
moy_gen_tag = self.compute_moy_gen_tag(moy_ues_tag)
|
||||||
|
|
||||||
# Ajoute les moyennes générales de BUT pour le semestre considéré
|
self.moyennes_tags[tag] = MoyenneTag(
|
||||||
|
tag, ues_hors_sport, moy_ues_tag, moy_gen_tag
|
||||||
|
)
|
||||||
|
|
||||||
|
# Ajoute les d'UE moyennes générales de BUT pour le semestre considéré
|
||||||
|
# moy_gen_but = self.nt.etud_moy_gen
|
||||||
|
# self.moyennes_tags["but"] = MoyenneTag("but", [], None, moy_gen_but, )
|
||||||
|
|
||||||
|
# Ajoute les moyennes par UEs (et donc par compétence) + la moyenne générale (but)
|
||||||
|
df_ues = pd.DataFrame({ue.id: self.nt.etud_moy_ue[ue.id] for ue in ues_hors_sport},
|
||||||
|
index = self.etudids)
|
||||||
|
# moy_ues = self.nt.etud_moy_ue[ue_id]
|
||||||
moy_gen_but = self.nt.etud_moy_gen
|
moy_gen_but = self.nt.etud_moy_gen
|
||||||
self.moyennes_tags["but"] = MoyenneTag("but", moy_gen_but)
|
self.moyennes_tags["but"] = MoyenneTag("but", ues_hors_sport, df_ues, moy_gen_but)
|
||||||
|
|
||||||
# Ajoute les moyennes par compétence
|
|
||||||
for ue_id, competence in dict_ues_competences.items():
|
|
||||||
if competence not in self.moyennes_tags:
|
|
||||||
moy_ue = self.nt.etud_moy_ue[ue_id]
|
|
||||||
self.moyennes_tags[competence] = MoyenneTag(competence, moy_ue)
|
|
||||||
|
|
||||||
self.tags_sorted = self.get_all_tags()
|
self.tags_sorted = self.get_all_tags()
|
||||||
"""Tags (personnalisés+compétences) par ordre alphabétique"""
|
"""Tags (personnalisés+compétences) par ordre alphabétique"""
|
||||||
@ -156,8 +165,8 @@ class SemestreTag(TableTag):
|
|||||||
"""Nom affiché pour le semestre taggué"""
|
"""Nom affiché pour le semestre taggué"""
|
||||||
return app.pe.pe_etudiant.nom_semestre_etape(self.formsemestre, avec_fid=True)
|
return app.pe.pe_etudiant.nom_semestre_etape(self.formsemestre, avec_fid=True)
|
||||||
|
|
||||||
def compute_moyenne_tag(self, tag: str, tags_infos: dict) -> pd.Series:
|
def compute_moy_ues_tag(self, tag: str, tags_infos: dict) -> pd.Series:
|
||||||
"""Calcule la moyenne des étudiants pour le tag indiqué,
|
"""Calcule la moyenne par UE des étudiants pour le tag indiqué,
|
||||||
pour ce SemestreTag, en ayant connaissance des informations sur
|
pour ce SemestreTag, en ayant connaissance des informations sur
|
||||||
les tags (dictionnaire donnant les coeff de repondération)
|
les tags (dictionnaire donnant les coeff de repondération)
|
||||||
|
|
||||||
@ -199,7 +208,12 @@ class SemestreTag(TableTag):
|
|||||||
self.dispense_ues,
|
self.dispense_ues,
|
||||||
block=self.formsemestre.block_moyennes,
|
block=self.formsemestre.block_moyennes,
|
||||||
)
|
)
|
||||||
|
return moyennes_ues_tag
|
||||||
|
|
||||||
|
def compute_moy_gen_tag(self, moy_ues_tag: pd.DataFrame) -> pd.Series:
|
||||||
|
"""Calcule la moyenne générale (toutes UE confondus)
|
||||||
|
pour le tag considéré, en les pondérant par les crédits ECTS.
|
||||||
|
"""
|
||||||
# Les ects
|
# Les ects
|
||||||
ects = self.ues_inscr_parcours_df.fillna(0.0) * [
|
ects = self.ues_inscr_parcours_df.fillna(0.0) * [
|
||||||
ue.ects for ue in self.ues if ue.type != UE_SPORT
|
ue.ects for ue in self.ues if ue.type != UE_SPORT
|
||||||
@ -207,7 +221,7 @@ class SemestreTag(TableTag):
|
|||||||
|
|
||||||
# Calcule la moyenne générale dans le semestre (pondérée par le ECTS)
|
# Calcule la moyenne générale dans le semestre (pondérée par le ECTS)
|
||||||
moy_gen_tag = comp.moy_sem.compute_sem_moys_apc_using_ects(
|
moy_gen_tag = comp.moy_sem.compute_sem_moys_apc_using_ects(
|
||||||
moyennes_ues_tag,
|
moy_ues_tag,
|
||||||
ects,
|
ects,
|
||||||
formation_id=self.formsemestre.formation_id,
|
formation_id=self.formsemestre.formation_id,
|
||||||
skip_empty_ues=True,
|
skip_empty_ues=True,
|
||||||
|
@ -42,19 +42,27 @@ import numpy as np
|
|||||||
|
|
||||||
from app import ScoValueError
|
from app import ScoValueError
|
||||||
from app.comp.moy_sem import comp_ranks_series
|
from app.comp.moy_sem import comp_ranks_series
|
||||||
|
from app.models import UniteEns
|
||||||
from app.pe import pe_affichage
|
from app.pe import pe_affichage
|
||||||
from app.pe.pe_affichage import SANS_NOTE
|
from app.pe.pe_affichage import SANS_NOTE
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
|
from app.scodoc.codes_cursus import UE_SPORT
|
||||||
|
|
||||||
TAGS_RESERVES = ["but"]
|
TAGS_RESERVES = ["but"]
|
||||||
|
|
||||||
|
|
||||||
class MoyenneTag:
|
class MoyenneTag:
|
||||||
def __init__(self, tag: str, notes: pd.Series):
|
def __init__(
|
||||||
|
self,
|
||||||
|
tag: str,
|
||||||
|
ues: list[UniteEns],
|
||||||
|
notes_ues: pd.DataFrame,
|
||||||
|
notes_gen: pd.Series,
|
||||||
|
):
|
||||||
"""Classe centralisant la synthèse des moyennes/classements d'une série
|
"""Classe centralisant la synthèse des moyennes/classements d'une série
|
||||||
d'étudiants à un tag donné, en stockant un dictionnaire :
|
d'étudiants à un tag donné, en stockant :
|
||||||
|
|
||||||
``
|
``
|
||||||
{
|
{
|
||||||
@ -69,16 +77,26 @@ class MoyenneTag:
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
tag: Un tag
|
tag: Un tag
|
||||||
note: Une série de notes (moyenne) sous forme d'un pd.Series()
|
ues: La liste des UEs ayant servie au calcul de la moyenne
|
||||||
|
notes_ues: Les moyennes (etudid x ues) aux différentes UEs et pour le tag
|
||||||
|
notes_gen: Une série de notes (moyenne) sous forme d'un pd.Series() (toutes UEs confondues)
|
||||||
"""
|
"""
|
||||||
self.tag = tag
|
self.tag = tag
|
||||||
"""Le tag associé à la moyenne"""
|
"""Le tag associé à la moyenne"""
|
||||||
self.etudids = list(notes.index) # calcul à venir
|
self.etudids = list(notes_gen.index) # calcul à venir
|
||||||
"""Les id des étudiants"""
|
"""Les id des étudiants"""
|
||||||
self.inscrits_ids = notes[notes.notnull()].index.to_list()
|
self.ues: list[UniteEns] = ues
|
||||||
"""Les id des étudiants dont la moyenne est non nulle"""
|
"""Les UEs sur lesquelles sont calculées les moyennes"""
|
||||||
self.df: pd.DataFrame = self.comp_moy_et_stat(notes)
|
self.df_ues: dict[int, pd.DataFrame] = {}
|
||||||
"""Le dataframe retraçant les moyennes/classements/statistiques"""
|
"""Les dataframes retraçant les moyennes/classements/statistiques des étudiants aux UEs"""
|
||||||
|
for ue in self.ues: # if ue.type != UE_SPORT:
|
||||||
|
notes = notes_ues[ue.id]
|
||||||
|
self.df_ues[ue.id] = self.comp_moy_et_stat(notes)
|
||||||
|
|
||||||
|
self.inscrits_ids = notes_gen[notes_gen.notnull()].index.to_list()
|
||||||
|
"""Les id des étudiants dont la moyenne générale est non nulle"""
|
||||||
|
self.df_gen: pd.DataFrame = self.comp_moy_et_stat(notes_gen)
|
||||||
|
"""Le dataframe retraçant les moyennes/classements/statistiques général"""
|
||||||
self.synthese = self.to_dict()
|
self.synthese = self.to_dict()
|
||||||
"""La synthèse (dictionnaire) des notes/classements/statistiques"""
|
"""La synthèse (dictionnaire) des notes/classements/statistiques"""
|
||||||
|
|
||||||
@ -88,7 +106,8 @@ class MoyenneTag:
|
|||||||
|
|
||||||
def comp_moy_et_stat(self, notes: pd.Series) -> dict:
|
def comp_moy_et_stat(self, notes: pd.Series) -> dict:
|
||||||
"""Calcule et structure les données nécessaires au PE pour une série
|
"""Calcule et structure les données nécessaires au PE pour une série
|
||||||
de notes (souvent une moyenne par tag) dans un dictionnaire spécifique.
|
de notes (pouvant être une moyenne d'un tag à une UE ou une moyenne générale
|
||||||
|
d'un tag) dans un dictionnaire spécifique.
|
||||||
|
|
||||||
Partant des notes, sont calculés les classements (en ne tenant compte
|
Partant des notes, sont calculés les classements (en ne tenant compte
|
||||||
que des notes non nulles).
|
que des notes non nulles).
|
||||||
@ -121,64 +140,65 @@ class MoyenneTag:
|
|||||||
|
|
||||||
# Les nb d'étudiants & nb d'inscrits
|
# Les nb d'étudiants & nb d'inscrits
|
||||||
df["nb_etuds"] = len(self.etudids)
|
df["nb_etuds"] = len(self.etudids)
|
||||||
df.loc[self.inscrits_ids, "nb_inscrits"] = len(self.inscrits_ids)
|
# Les étudiants dont la note n'est pas nulle
|
||||||
|
inscrits_ids = notes[notes.notnull()].index.to_list()
|
||||||
|
df.loc[inscrits_ids, "nb_inscrits"] = len(inscrits_ids)
|
||||||
|
|
||||||
# Le classement des inscrits
|
# Le classement des inscrits
|
||||||
notes_non_nulles = notes[self.inscrits_ids]
|
notes_non_nulles = notes[inscrits_ids]
|
||||||
(class_str, class_int) = comp_ranks_series(notes_non_nulles)
|
(class_str, class_int) = comp_ranks_series(notes_non_nulles)
|
||||||
df.loc[self.inscrits_ids, "classement"] = class_int
|
df.loc[inscrits_ids, "classement"] = class_int
|
||||||
|
|
||||||
# Le rang (classement/nb_inscrit)
|
# Le rang (classement/nb_inscrit)
|
||||||
df["rang"] = df["rang"].astype(str)
|
df["rang"] = df["rang"].astype(str)
|
||||||
df.loc[self.inscrits_ids, "rang"] = (
|
df.loc[inscrits_ids, "rang"] = (
|
||||||
df.loc[self.inscrits_ids, "classement"].astype(int).astype(str)
|
df.loc[inscrits_ids, "classement"].astype(int).astype(str)
|
||||||
+ "/"
|
+ "/"
|
||||||
+ df.loc[self.inscrits_ids, "nb_inscrits"].astype(int).astype(str)
|
+ df.loc[inscrits_ids, "nb_inscrits"].astype(int).astype(str)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Les stat (des inscrits)
|
# Les stat (des inscrits)
|
||||||
df.loc[self.inscrits_ids, "min"] = notes.min()
|
df.loc[inscrits_ids, "min"] = notes.min()
|
||||||
df.loc[self.inscrits_ids, "max"] = notes.max()
|
df.loc[inscrits_ids, "max"] = notes.max()
|
||||||
df.loc[self.inscrits_ids, "moy"] = notes.mean()
|
df.loc[inscrits_ids, "moy"] = notes.mean()
|
||||||
|
|
||||||
return df
|
return df
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self) -> dict:
|
||||||
"""Renvoie un dictionnaire de synthèse des moyennes/classements/statistiques"""
|
"""Renvoie un dictionnaire de synthèse des moyennes/classements/statistiques"""
|
||||||
synthese = {
|
synthese = {
|
||||||
"notes": self.df["note"],
|
"notes": self.df_gen["note"],
|
||||||
"classements": self.df["classement"],
|
"classements": self.df_gen["classement"],
|
||||||
"min": self.df["min"].mean(),
|
"min": self.df_gen["min"].mean(),
|
||||||
"max": self.df["max"].mean(),
|
"max": self.df_gen["max"].mean(),
|
||||||
"moy": self.df["moy"].mean(),
|
"moy": self.df_gen["moy"].mean(),
|
||||||
"nb_inscrits": self.df["nb_inscrits"].mean(),
|
"nb_inscrits": self.df_gen["nb_inscrits"].mean(),
|
||||||
}
|
}
|
||||||
return synthese
|
return synthese
|
||||||
|
|
||||||
def get_notes(self):
|
def get_notes(self):
|
||||||
"""Série des notes, arrondies à 2 chiffres après la virgule"""
|
"""Série des notes, arrondies à 2 chiffres après la virgule"""
|
||||||
return self.df["note"].round(2)
|
return self.df_gen["note"].round(2)
|
||||||
|
|
||||||
def get_rangs_inscrits(self) -> pd.Series:
|
def get_rangs_inscrits(self) -> pd.Series:
|
||||||
"""Série des rangs classement/nbre_inscrit"""
|
"""Série des rangs classement/nbre_inscrit"""
|
||||||
return self.df["rang"]
|
return self.df_gen["rang"]
|
||||||
|
|
||||||
def get_min(self) -> pd.Series:
|
def get_min(self) -> pd.Series:
|
||||||
"""Série des min"""
|
"""Série des min"""
|
||||||
return self.df["min"].round(2)
|
return self.df_gen["min"].round(2)
|
||||||
|
|
||||||
def get_max(self) -> pd.Series:
|
def get_max(self) -> pd.Series:
|
||||||
"""Série des max"""
|
"""Série des max"""
|
||||||
return self.df["max"].round(2)
|
return self.df_gen["max"].round(2)
|
||||||
|
|
||||||
def get_moy(self) -> pd.Series:
|
def get_moy(self) -> pd.Series:
|
||||||
"""Série des moy"""
|
"""Série des moy"""
|
||||||
return self.df["moy"].round(2)
|
return self.df_gen["moy"].round(2)
|
||||||
|
|
||||||
|
|
||||||
def get_note_for_df(self, etudid: int):
|
def get_note_for_df(self, etudid: int):
|
||||||
"""Note d'un étudiant donné par son etudid"""
|
"""Note d'un étudiant donné par son etudid"""
|
||||||
return round(self.df["note"].loc[etudid], 2)
|
return round(self.df_gen["note"].loc[etudid], 2)
|
||||||
|
|
||||||
def get_min_for_df(self) -> float:
|
def get_min_for_df(self) -> float:
|
||||||
"""Min renseigné pour affichage dans un df"""
|
"""Min renseigné pour affichage dans un df"""
|
||||||
@ -195,7 +215,7 @@ class MoyenneTag:
|
|||||||
def get_class_for_df(self, etudid: int) -> str:
|
def get_class_for_df(self, etudid: int) -> str:
|
||||||
"""Classement ramené au nombre d'inscrits,
|
"""Classement ramené au nombre d'inscrits,
|
||||||
pour un étudiant donné par son etudid"""
|
pour un étudiant donné par son etudid"""
|
||||||
classement = self.df["rang"].loc[etudid]
|
classement = self.df_gen["rang"].loc[etudid]
|
||||||
if not pd.isna(classement):
|
if not pd.isna(classement):
|
||||||
return classement
|
return classement
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user