235 lines
7.7 KiB
Python
235 lines
7.7 KiB
Python
##############################################################################
|
|
# Module "Avis de poursuite d'étude"
|
|
# conçu et développé par Cléo Baras (IUT de Grenoble)
|
|
##############################################################################
|
|
|
|
"""Affichages, debug
|
|
"""
|
|
|
|
from flask import g
|
|
from app import log
|
|
from app.pe.rcss import pe_rcs
|
|
|
|
PE_DEBUG = False
|
|
|
|
|
|
# On stocke les logs PE dans g.scodoc_pe_log
|
|
# pour ne pas modifier les nombreux appels à pe_print.
|
|
def pe_start_log() -> list[str]:
|
|
"Initialize log"
|
|
g.scodoc_pe_log = []
|
|
return g.scodoc_pe_log
|
|
|
|
|
|
def pe_print(*a, **cles):
|
|
"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 "info" in cles:
|
|
log(msg)
|
|
|
|
|
|
def pe_get_log() -> str:
|
|
"Renvoie une chaîne avec tous les messages loggués"
|
|
return "\n".join(getattr(g, "scodoc_pe_log", []))
|
|
|
|
|
|
# Affichage dans le tableur pe en cas d'absence de notes
|
|
SANS_NOTE = "-"
|
|
|
|
|
|
def repr_profil_coeffs(matrice_coeffs_moy_gen, with_index=False):
|
|
"""Affiche les différents types de coefficients (appelés profil)
|
|
d'une matrice_coeffs_moy_gen (pour debug)
|
|
"""
|
|
|
|
# Les profils des coeffs d'UE (pour debug)
|
|
profils = []
|
|
index_a_profils = {}
|
|
for i in matrice_coeffs_moy_gen.index:
|
|
val = matrice_coeffs_moy_gen.loc[i].fillna("-")
|
|
val = " | ".join([str(v) for v in val])
|
|
if val not in profils:
|
|
profils += [val]
|
|
index_a_profils[val] = [str(i)]
|
|
else:
|
|
index_a_profils[val] += [str(i)]
|
|
|
|
# L'affichage
|
|
if len(profils) > 1:
|
|
if with_index:
|
|
elmts = [
|
|
" " * 10
|
|
+ prof
|
|
+ " (par ex. "
|
|
+ ", ".join(index_a_profils[prof][:10])
|
|
+ ")"
|
|
for prof in profils
|
|
]
|
|
else:
|
|
elmts = [" " * 10 + prof for prof in profils]
|
|
profils_aff = "\n" + "\n".join(elmts)
|
|
else:
|
|
profils_aff = "\n".join(profils)
|
|
return profils_aff
|
|
|
|
|
|
def repr_asso_ue_comp(acronymes_ues_to_competences):
|
|
"""Représentation textuelle de l'association UE -> Compétences
|
|
fournies dans acronymes_ues_to_competences
|
|
"""
|
|
champs = acronymes_ues_to_competences.keys()
|
|
champs = sorted(champs)
|
|
aff_comp = []
|
|
for acro in champs:
|
|
aff_comp += [f"📍{acro} (∈ 💡{acronymes_ues_to_competences[acro]})"]
|
|
return ", ".join(aff_comp)
|
|
|
|
|
|
def aff_UEs(champs):
|
|
"""Représentation textuelle des UEs fournies dans `champs`"""
|
|
champs_tries = sorted(champs)
|
|
aff_comp = []
|
|
|
|
for comp in champs_tries:
|
|
aff_comp += ["📍" + comp]
|
|
return ", ".join(aff_comp)
|
|
|
|
|
|
def aff_competences(champs):
|
|
"""Affiche les compétences"""
|
|
champs_tries = sorted(champs)
|
|
aff_comp = []
|
|
|
|
for comp in champs_tries:
|
|
aff_comp += ["💡" + comp]
|
|
return ", ".join(aff_comp)
|
|
|
|
|
|
def repr_tags(tags):
|
|
"""Affiche les tags"""
|
|
tags_tries = sorted(tags)
|
|
aff_tag = ["👜" + tag for tag in tags_tries]
|
|
return ", ".join(aff_tag)
|
|
|
|
|
|
def aff_tags_par_categories(dict_tags):
|
|
"""Etant donné un dictionnaire de tags, triés
|
|
par catégorie (ici "personnalisés" ou "auto")
|
|
représentation textuelle des tags
|
|
"""
|
|
noms_tags_perso = sorted(list(set(dict_tags["personnalises"].keys())))
|
|
noms_tags_auto = sorted(list(set(dict_tags["auto"].keys()))) # + noms_tags_comp
|
|
if noms_tags_perso:
|
|
aff_tags_perso = ", ".join([f"👜{nom}" for nom in noms_tags_perso])
|
|
aff_tags_auto = ", ".join([f"👜{nom}" for nom in noms_tags_auto])
|
|
return f"Tags du programme de formation : {aff_tags_perso} + Automatiques : {aff_tags_auto}"
|
|
else:
|
|
aff_tags_auto = ", ".join([f"👜{nom}" for nom in noms_tags_auto])
|
|
return f"Tags automatiques {aff_tags_auto} (aucun tag personnalisé)"
|
|
|
|
# Affichage
|
|
|
|
|
|
def aff_trajectoires_suivies_par_etudiants(etudiants):
|
|
"""Affiche les trajectoires (regroupement de (form)semestres)
|
|
amenant un étudiant du S1 à un semestre final"""
|
|
# Affichage pour debug
|
|
etudiants_ids = etudiants.etudiants_ids
|
|
jeunes = list(enumerate(etudiants_ids))
|
|
for no_etud, etudid in jeunes:
|
|
etat = "⛔" if etudid in etudiants.abandons_ids else "✅"
|
|
|
|
pe_print(f"--> {etat} {etudiants.identites[etudid].nomprenom} (#{etudid}) :")
|
|
trajectoires = etudiants.trajectoires[etudid]
|
|
for nom_rcs, rcs in trajectoires.items():
|
|
if rcs:
|
|
pe_print(f" > RCS ⏯️{nom_rcs}: {rcs.get_repr()}")
|
|
|
|
|
|
def aff_semXs_suivis_par_etudiants(etudiants):
|
|
"""Affiche les SemX (regroupement de semestres de type Sx)
|
|
amenant un étudiant à valider un Sx"""
|
|
etudiants_ids = etudiants.etudiants_ids
|
|
jeunes = list(enumerate(etudiants_ids))
|
|
|
|
for no_etud, etudid in jeunes:
|
|
etat = "⛔" if etudid in etudiants.abandons_ids else "✅"
|
|
pe_print(f"--> {etat} {etudiants.identites[etudid].nomprenom} :")
|
|
for nom_rcs, rcs in etudiants.semXs[etudid].items():
|
|
if rcs:
|
|
pe_print(f" > SemX ⏯️{nom_rcs}: {rcs.get_repr()}")
|
|
|
|
vides = []
|
|
for nom_rcs in pe_rcs.TOUS_LES_SEMESTRES:
|
|
les_semX_suivis = []
|
|
for no_etud, etudid in jeunes:
|
|
if etudiants.semXs[etudid][nom_rcs]:
|
|
les_semX_suivis.append(etudiants.semXs[etudid][nom_rcs])
|
|
if not les_semX_suivis:
|
|
vides += [nom_rcs]
|
|
vides = sorted(list(set(vides)))
|
|
pe_print(f"⚠️ SemX sans données : {', '.join(vides)}")
|
|
|
|
|
|
def aff_capitalisations(etuds, ressembuttags, fid_final, acronymes_sorted, masque_df):
|
|
"""Affichage des capitalisations du sxtag pour debug"""
|
|
aff_cap = []
|
|
for etud in etuds:
|
|
cap = []
|
|
for frmsem_id in ressembuttags:
|
|
if frmsem_id != fid_final:
|
|
for accr in acronymes_sorted:
|
|
if masque_df[frmsem_id].loc[etud.etudid, accr] > 0.0:
|
|
cap += [accr]
|
|
if cap:
|
|
aff_cap += [f" > {etud.nomprenom} : {', '.join(cap)}"]
|
|
if aff_cap:
|
|
pe_print(f"--> ⚠️ Capitalisations :")
|
|
pe_print("\n".join(aff_cap))
|
|
|
|
|
|
def repr_comp_et_ues(acronymes_ues_to_competences):
|
|
"""Affichage pour debug"""
|
|
aff_comp = []
|
|
competences_sorted = sorted(acronymes_ues_to_competences.keys())
|
|
for comp in competences_sorted:
|
|
liste = []
|
|
for acro in acronymes_ues_to_competences:
|
|
if acronymes_ues_to_competences[acro] == comp:
|
|
liste += ["📍" + acro]
|
|
aff_comp += [f" 💡{comp} (⇔ {', '.join(liste)})"]
|
|
return "\n".join(aff_comp)
|
|
|
|
|
|
def aff_rcsemxs_suivis_par_etudiants(etudiants):
|
|
"""Affiche les RCSemX (regroupement de SemX)
|
|
amenant un étudiant du S1 à un Sx"""
|
|
etudiants_ids = etudiants.etudiants_ids
|
|
jeunes = list(enumerate(etudiants_ids))
|
|
|
|
for no_etud, etudid in jeunes:
|
|
etat = "⛔" if etudid in etudiants.abandons_ids else "✅"
|
|
pe_print(f"-> {etat} {etudiants.identites[etudid].nomprenom} :")
|
|
for nom_rcs, rcs in etudiants.rcsemXs[etudid].items():
|
|
if rcs:
|
|
pe_print(f" > RCSemX ⏯️{nom_rcs}: {rcs.get_repr()}")
|
|
|
|
vides = []
|
|
for nom_rcs in pe_rcs.TOUS_LES_RCS:
|
|
les_rcssemX_suivis = []
|
|
for no_etud, etudid in jeunes:
|
|
if etudiants.rcsemXs[etudid][nom_rcs]:
|
|
les_rcssemX_suivis.append(etudiants.rcsemXs[etudid][nom_rcs])
|
|
if not les_rcssemX_suivis:
|
|
vides += [nom_rcs]
|
|
vides = sorted(list(set(vides)))
|
|
pe_print(f"⚠️ RCSemX vides : {', '.join(vides)}")
|