1
0
forked from ScoDoc/ScoDoc

Ajoute les moy par ue et par tag au semtag

This commit is contained in:
Cléo Baras 2024-02-14 17:00:05 +01:00
parent 02a73de04d
commit 267dbb6460
3 changed files with 89 additions and 54 deletions

View File

@ -9,7 +9,7 @@
from flask import g
from app import log
PE_DEBUG = False
PE_DEBUG = True
# On stocke les logs PE dans g.scodoc_pe_log
@ -22,14 +22,15 @@ def pe_start_log() -> list[str]:
def pe_print(*a):
"Log (or print in PE_DEBUG mode) and store in g"
if PE_DEBUG:
msg = " ".join(a)
print(msg)
else:
lines = getattr(g, "scodoc_pe_log")
if lines is None:
lines = pe_start_log()
msg = " ".join(a)
lines.append(msg)
if PE_DEBUG:
print(msg)
else:
log(msg)

View File

@ -76,6 +76,7 @@ class SemestreTag(TableTag):
# Les étudiants
self.etuds = self.nt.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,
# récupérés notamment de py:mod:`res_but`
@ -94,12 +95,12 @@ class SemestreTag(TableTag):
tags_personnalises = get_synthese_tags_personnalises_semestre(
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
dict_ues_competences = get_noms_competences_from_ues(self.nt.formsemestre)
noms_tags_comp = list(set(dict_ues_competences.values()))
noms_tags_auto = ["but"] + noms_tags_comp
# dict_ues_competences = get_noms_competences_from_ues(self.nt.formsemestre)
# noms_tags_comp = list(set(dict_ues_competences.values()))
noms_tags_auto = ["but"] # + noms_tags_comp
self.tags = noms_tags_perso + noms_tags_auto
"""Tags du semestre taggué"""
@ -122,23 +123,31 @@ class SemestreTag(TableTag):
"""
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
self.moyennes_tags = {}
for tag in tags_personnalises:
# pe_affichage.pe_print(f" -> Traitement du tag {tag}")
moy_gen_tag = self.compute_moyenne_tag(tag, tags_personnalises)
self.moyennes_tags[tag] = MoyenneTag(tag, moy_gen_tag)
moy_ues_tag = self.compute_moy_ues_tag(tag, tags_personnalises)
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
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()
"""Tags (personnalisés+compétences) par ordre alphabétique"""
@ -156,8 +165,8 @@ class SemestreTag(TableTag):
"""Nom affiché pour le semestre taggué"""
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:
"""Calcule la moyenne des étudiants pour le tag indiqué,
def compute_moy_ues_tag(self, tag: str, tags_infos: dict) -> pd.Series:
"""Calcule la moyenne par UE des étudiants pour le tag indiqué,
pour ce SemestreTag, en ayant connaissance des informations sur
les tags (dictionnaire donnant les coeff de repondération)
@ -199,7 +208,12 @@ class SemestreTag(TableTag):
self.dispense_ues,
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
ects = self.ues_inscr_parcours_df.fillna(0.0) * [
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)
moy_gen_tag = comp.moy_sem.compute_sem_moys_apc_using_ects(
moyennes_ues_tag,
moy_ues_tag,
ects,
formation_id=self.formsemestre.formation_id,
skip_empty_ues=True,

View File

@ -42,19 +42,27 @@ import numpy as np
from app import ScoValueError
from app.comp.moy_sem import comp_ranks_series
from app.models import UniteEns
from app.pe import pe_affichage
from app.pe.pe_affichage import SANS_NOTE
from app.scodoc import sco_utils as scu
import pandas as pd
from app.scodoc.codes_cursus import UE_SPORT
TAGS_RESERVES = ["but"]
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
d'étudiants à un tag donné, en stockant un dictionnaire :
d'étudiants à un tag donné, en stockant :
``
{
@ -69,16 +77,26 @@ class MoyenneTag:
Args:
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
"""Le tag associé à la moyenne"""
self.etudids = list(notes.index) # calcul à venir
self.etudids = list(notes_gen.index) # calcul à venir
"""Les id des étudiants"""
self.inscrits_ids = notes[notes.notnull()].index.to_list()
"""Les id des étudiants dont la moyenne est non nulle"""
self.df: pd.DataFrame = self.comp_moy_et_stat(notes)
"""Le dataframe retraçant les moyennes/classements/statistiques"""
self.ues: list[UniteEns] = ues
"""Les UEs sur lesquelles sont calculées les moyennes"""
self.df_ues: dict[int, pd.DataFrame] = {}
"""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()
"""La synthèse (dictionnaire) des notes/classements/statistiques"""
@ -88,7 +106,8 @@ class MoyenneTag:
def comp_moy_et_stat(self, notes: pd.Series) -> dict:
"""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
que des notes non nulles).
@ -121,64 +140,65 @@ class MoyenneTag:
# Les nb d'étudiants & nb d'inscrits
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
notes_non_nulles = notes[self.inscrits_ids]
notes_non_nulles = notes[inscrits_ids]
(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)
df["rang"] = df["rang"].astype(str)
df.loc[self.inscrits_ids, "rang"] = (
df.loc[self.inscrits_ids, "classement"].astype(int).astype(str)
df.loc[inscrits_ids, "rang"] = (
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)
df.loc[self.inscrits_ids, "min"] = notes.min()
df.loc[self.inscrits_ids, "max"] = notes.max()
df.loc[self.inscrits_ids, "moy"] = notes.mean()
df.loc[inscrits_ids, "min"] = notes.min()
df.loc[inscrits_ids, "max"] = notes.max()
df.loc[inscrits_ids, "moy"] = notes.mean()
return df
def to_dict(self) -> dict:
"""Renvoie un dictionnaire de synthèse des moyennes/classements/statistiques"""
synthese = {
"notes": self.df["note"],
"classements": self.df["classement"],
"min": self.df["min"].mean(),
"max": self.df["max"].mean(),
"moy": self.df["moy"].mean(),
"nb_inscrits": self.df["nb_inscrits"].mean(),
"notes": self.df_gen["note"],
"classements": self.df_gen["classement"],
"min": self.df_gen["min"].mean(),
"max": self.df_gen["max"].mean(),
"moy": self.df_gen["moy"].mean(),
"nb_inscrits": self.df_gen["nb_inscrits"].mean(),
}
return synthese
def get_notes(self):
"""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:
"""Série des rangs classement/nbre_inscrit"""
return self.df["rang"]
return self.df_gen["rang"]
def get_min(self) -> pd.Series:
"""Série des min"""
return self.df["min"].round(2)
return self.df_gen["min"].round(2)
def get_max(self) -> pd.Series:
"""Série des max"""
return self.df["max"].round(2)
return self.df_gen["max"].round(2)
def get_moy(self) -> pd.Series:
"""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):
"""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:
"""Min renseigné pour affichage dans un df"""
@ -195,7 +215,7 @@ class MoyenneTag:
def get_class_for_df(self, etudid: int) -> str:
"""Classement ramené au nombre d'inscrits,
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):
return classement
else: