forked from viennet/Referentiels
amélioratios diverses
This commit is contained in:
parent
5ed495fcf5
commit
159db50add
@ -130,70 +130,42 @@ print(f"{nbre_ressources} ressources")
|
||||
ressources = {"S1" : [], "S2": []}
|
||||
|
||||
for r in liste_ressources:
|
||||
# Nettoie titre
|
||||
nettoie_titre(r)
|
||||
|
||||
# Nettoie le champ heures_encadrees
|
||||
if r.heures_encadrees:
|
||||
volumes = nettoie_heure(r.heures_encadrees)
|
||||
if r.tp:
|
||||
r.tp = nettoie_heure(r.tp)
|
||||
if isinstance(volumes, int):
|
||||
r.heures_encadrees = volumes
|
||||
elif isinstance(volumes, tuple):
|
||||
r.heures_encadrees = volumes[0]
|
||||
if not r.tp:
|
||||
r.tp = volumes[1]
|
||||
elif r.tp != volumes[1]:
|
||||
__LOGGER.warning(r"Dans {r.nom}, pb dans les heures tp/td")
|
||||
else:
|
||||
r.heures_encadrees = None
|
||||
nettoie_heure(r)
|
||||
|
||||
# Nettoie les codes
|
||||
if r.code:
|
||||
r.code = nettoie_code(r.code)
|
||||
if not r.code: # Recherche le code dans les ressources
|
||||
code_devine = get_code_from_nom(r)
|
||||
if code_devine:
|
||||
__LOGGER.warning(f"Dans \"{r.nom}\", remplace le code par {code_devine}")
|
||||
r.code = code_devine
|
||||
nettoie_code(r)
|
||||
|
||||
# Nettoie les semestres
|
||||
if r.semestre:
|
||||
if "1" in r.semestre:
|
||||
r.semestre = "S1"
|
||||
elif "2" in r.semestre:
|
||||
r.semestre = "S2"
|
||||
else:
|
||||
__LOGGER.warning(f"Dans \"{r.nom}, PAS de semestre => rattaché au S2")
|
||||
r.semestre = "S2"
|
||||
else:
|
||||
__LOGGER.warning(f"Dans \"{r.nom}, PAS de semestre => rattaché au S2")
|
||||
r.semestre = "S2"
|
||||
# Remet en forme le titre
|
||||
if r.code:
|
||||
if supprime_accent_espace(r.nom) != supprime_accent_espace(DATA_RESSOURCES[r.semestre][r.code]):
|
||||
__LOGGER.warning(f"Dans \"{r.nom}\", pb dans le nom de la ressource : devient " + DATA_RESSOURCES[r.semestre][r.code])
|
||||
r.nom = DATA_RESSOURCES[r.semestre][r.code]
|
||||
|
||||
|
||||
nettoie_semestre(r)
|
||||
|
||||
# Remet en forme les ACs
|
||||
acs = r.apprentissages
|
||||
if len(acs) != 3:
|
||||
__LOGGER.warning(f"Problème dans le nombre de compétences de {r.nom}")
|
||||
for comp in range(3):
|
||||
donnees = acs[comp] # chaine de caractères listant les ACS
|
||||
# donnees = donnees.replace("\t", "").replace("-", "") # supprime les tabulations
|
||||
acs_avec_code = devine_acs_by_code(donnees)
|
||||
acs_avec_nom = devine_acs_by_nom(donnees)
|
||||
acs_finaux = sorted(list(set(acs_avec_code + acs_avec_nom)))
|
||||
r.apprentissages[comp] = acs_finaux
|
||||
nettoie_acs(r)
|
||||
|
||||
# Remet en forme les pré-requis
|
||||
nettoie_prerequis(r)
|
||||
|
||||
# Remet en forme le descriptif
|
||||
nettoie_description(r)
|
||||
|
||||
# Tri dans le bon semestre
|
||||
ressources[r.semestre] += [r]
|
||||
|
||||
# complète les codes d'après les numéros
|
||||
for sem in ressources:
|
||||
for (i, r) in enumerate(ressources[sem]):
|
||||
if not r.code:
|
||||
if i == 0:
|
||||
r.code = "R" + sem[1] + "01"
|
||||
elif ressources[sem][i-1].code:
|
||||
r.code = "R" + sem[1] + "{:02d}".format(int(ressources[sem][i-1].code[-2:])+1)
|
||||
|
||||
# ************************************************************************
|
||||
# Affichages divers
|
||||
|
||||
|
||||
# Bilan des heures & Calcul somme des heures par semestre
|
||||
ligne = "{:20s} | {:75s} | {:10s} | {:10s} |"
|
||||
trait = "-"*len(ligne.format("", "", "", ""))
|
||||
@ -247,3 +219,6 @@ for sem in ressources:
|
||||
valeurs = tuple(valeurs)
|
||||
print(ligne.format(*valeurs))
|
||||
|
||||
for sem in ressources:
|
||||
for r in ressources[sem]:
|
||||
print(r.to_latex())
|
17
python/modeles.py
Normal file
17
python/modeles.py
Normal file
@ -0,0 +1,17 @@
|
||||
"""
|
||||
Gestion des modeles de question/reponses latex
|
||||
"""
|
||||
import string, os
|
||||
|
||||
def get_modele(fichier):
|
||||
# print(os.path.abspath(os.curdir))
|
||||
with open(fichier, "r", encoding="utf8") as fid:
|
||||
contenu = fid.read()
|
||||
|
||||
return contenu
|
||||
|
||||
def effify(non_f_str: str):
|
||||
return eval(f'f"""{non_f_str}"""')
|
||||
|
||||
class TemplateLatex(string.Template):
|
||||
delimiter = '#'
|
37
python/pn/modele_ressource.tex
Normal file
37
python/pn/modele_ressource.tex
Normal file
@ -0,0 +1,37 @@
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Ressources
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
\nouvelleressource{#code}{#nom}
|
||||
|
||||
\ajoutheures{#heures_formation}{#heures_tp}
|
||||
|
||||
%% Les compétences et les ACs
|
||||
\ajoutcompetence{RT1-Administrer}{\niveauA}
|
||||
|
||||
#compRT1
|
||||
|
||||
\ajoutcompetence{RT2-Connecter}{\niveauA}
|
||||
|
||||
#compRT2
|
||||
|
||||
\ajoutcompetence{RT3-Programmer}{\niveauA}
|
||||
|
||||
% Les SAE
|
||||
#saes
|
||||
|
||||
% Les pre-requis
|
||||
#prerequis
|
||||
|
||||
% Le descriptif
|
||||
\ajoutancrage{
|
||||
#contexte
|
||||
}
|
||||
|
||||
% Contenus
|
||||
\ajoutcontenudetaille{
|
||||
#contenu
|
||||
}
|
||||
|
||||
% Mots-clés
|
||||
\ajoutmotscles{#motscles}
|
@ -6,3 +6,7 @@ S1:
|
||||
SAE15: "Traiter des données"
|
||||
S2:
|
||||
SAE21: ""
|
||||
SAE22: ""
|
||||
SAE23: ""
|
||||
SAE24: ""
|
||||
|
||||
|
@ -3,6 +3,7 @@ import logging
|
||||
import re
|
||||
import yaml
|
||||
import unicodedata
|
||||
from modeles import *
|
||||
|
||||
__LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -12,6 +13,8 @@ with open("pn/ressources.yml", 'r', encoding="utf8") as fid:
|
||||
# Récupère les données officielles des ACs
|
||||
with open("pn/acs.yml", 'r', encoding="utf8") as fid:
|
||||
DATA_ACS = yaml.load(fid.read(), Loader=yaml.Loader)
|
||||
with open("pn/saes.yml", 'r', encoding="utf8") as fid:
|
||||
DATA_SAES = yaml.load(fid.read(), Loader=yaml.Loader)
|
||||
|
||||
class Ressource():
|
||||
"""Classe modélisant les ressources"""
|
||||
@ -27,6 +30,8 @@ class Ressource():
|
||||
self.sae = sae
|
||||
self.prerequis = prerequis
|
||||
self.description = description
|
||||
self.contexte = None
|
||||
self.contenu = None
|
||||
self.mots = mots
|
||||
|
||||
def charge_ac(self, apprentissages):
|
||||
@ -35,36 +40,154 @@ class Ressource():
|
||||
def __str__(self):
|
||||
print(self.nom + " " + self.code)
|
||||
|
||||
def to_latex(self):
|
||||
contenu = get_modele("pn/modele_ressource.tex")
|
||||
|
||||
def nettoie_heure(champ):
|
||||
ajoutac = "\\ajoutac{%s}{%s}"
|
||||
compRT = []
|
||||
for i in range(len(self.apprentissages)):
|
||||
comps = []
|
||||
for ac in self.apprentissages[i]:
|
||||
comps.append( ajoutac % (ac, DATA_ACS["RT"+str(i+1)][ac]) )
|
||||
compRT.append("\n".join(comps))
|
||||
|
||||
# ajoutsaes = "\\ajoutsae{%s}{%s}"
|
||||
# compRT = []
|
||||
# for i in range(len(self.apprentissages)):
|
||||
# comps = []
|
||||
# for ac in self.apprentissages[i]:
|
||||
# code = self.apprentissages[i]
|
||||
# comps.append(ajoutac % (code, DATA_ACS["RT" + str(i + 1)][code]))
|
||||
# compRT.append("\n".join(comps))
|
||||
|
||||
ajoutprerequis = "\\ajoutprerequis{%s}{%s}"
|
||||
prerequis = ""
|
||||
|
||||
chaine = TemplateLatex(contenu).substitute(code=self.code,
|
||||
nom=self.nom,
|
||||
heures_formation=str(self.heures_encadrees) if self.heures_encadrees else "???",
|
||||
heures_tp=str(self.tp) if self.tp else "???",
|
||||
compRT1=compRT[0],
|
||||
compRT2=compRT[1],
|
||||
compRT3=compRT[2],
|
||||
saes="",
|
||||
prerequis=prerequis,
|
||||
contexte=self.contexte,
|
||||
contenu=self.contenu,
|
||||
motscles=self.mots
|
||||
)
|
||||
return chaine
|
||||
|
||||
|
||||
def nettoie_heure(r):
|
||||
"""Nettoie le champ (horaire) (de la forme 46h ou 33...) pour en extraire la valeur numérique :
|
||||
le champ peut contenir 2 volumes (heures formation puis heures tp), auquel cas les 2 valeurs sont renvoyées
|
||||
dans un tuple"""
|
||||
try: # champ contenant uniquement un nbre d'heure
|
||||
volumes = int(champ)
|
||||
return volumes
|
||||
except:
|
||||
volumes = re.findall("(\d{2}\D|\d{1}\D)", champ)
|
||||
if len(volumes) == 1:
|
||||
return int(volumes[0][:-1])
|
||||
elif len(volumes) == 2:
|
||||
volumes = sorted(volumes, reverse=True)
|
||||
return (int(volumes[0][:-1]), int(volumes[1][:-1]))
|
||||
def nettoie_champ_heure(champ):
|
||||
try: # champ contenant uniquement un nbre d'heure
|
||||
volumes = int(champ)
|
||||
return volumes
|
||||
except:
|
||||
volumes = re.findall("(\d{2}\D|\d{1}\D)", champ)
|
||||
if len(volumes) == 1:
|
||||
return int(volumes[0][:-1])
|
||||
elif len(volumes) == 2:
|
||||
volumes = sorted(volumes, reverse=True)
|
||||
return (int(volumes[0][:-1]), int(volumes[1][:-1]))
|
||||
|
||||
if r.heures_encadrees: # si les heures encadrées sont renseignées
|
||||
volumes = nettoie_champ_heure(r.heures_encadrees)
|
||||
if r.tp:
|
||||
r.tp = nettoie_champ_heure(r.tp)
|
||||
if isinstance(volumes, int):
|
||||
r.heures_encadrees = volumes
|
||||
elif isinstance(volumes, tuple):
|
||||
r.heures_encadrees = volumes[0]
|
||||
if not r.tp:
|
||||
r.tp = volumes[1]
|
||||
elif r.tp != volumes[1]:
|
||||
__LOGGER.warning(r"nettoie_heure: ans {r.nom}, pb dans les heures tp/td")
|
||||
else:
|
||||
r.heures_encadrees = None
|
||||
#else:
|
||||
#__LOGGER.warning("Heures non détectées")
|
||||
|
||||
def nettoie_code(champ):
|
||||
def nettoie_code(r):
|
||||
"""Recherche les codes ressources de la forme RXXX dans champ"""
|
||||
codes = re.findall(r"(R[0-9][0-9][0-9])", champ)
|
||||
# if len(codes) > 1:
|
||||
# __LOGGER.warning("plusieurs codes trouvés :(")
|
||||
#elif len(codes) == 0:
|
||||
# __LOGGER.warning("code manquant")
|
||||
if len(codes) == 1:
|
||||
return codes[0]
|
||||
champ = r.code
|
||||
if r.code:
|
||||
codes = re.findall(r"(R[0-9][0-9][0-9])", champ)
|
||||
# if len(codes) > 1:
|
||||
# __LOGGER.warning("plusieurs codes trouvés :(")
|
||||
#elif len(codes) == 0:
|
||||
# __LOGGER.warning("code manquant")
|
||||
if len(codes) == 1:
|
||||
r.code = codes[0]
|
||||
else:
|
||||
code_devine = get_code_from_nom(r)
|
||||
if code_devine:
|
||||
__LOGGER.warning(f"nettoie_code : \"{r.nom}\" => code {code_devine}")
|
||||
r.code = code_devine
|
||||
else:
|
||||
r.code = None
|
||||
__LOGGER.warning(f"nettoie_code : \"{r.nom}\" => code manquant")
|
||||
|
||||
def nettoie_semestre(r):
|
||||
"""Nettoie les semestres : semestre 1 => "S1", semestre 2 => "S2" """
|
||||
if r.semestre:
|
||||
if "1" in r.semestre:
|
||||
r.semestre = "S1"
|
||||
elif "2" in r.semestre:
|
||||
r.semestre = "S2"
|
||||
else:
|
||||
__LOGGER.warning(f"nettoie_semestre : dans \"{r.nom}, PAS de semestre => rattaché au S2")
|
||||
r.semestre = "S2"
|
||||
else:
|
||||
__LOGGER.warning(f"nettoie_semestre : dans \"{r.nom}, PAS de semestre => rattaché au S2")
|
||||
r.semestre = "S2"
|
||||
|
||||
def nettoie_titre(r):
|
||||
"""Nettoie le titre en utilisant les titres officiels"""
|
||||
def devine_nom_from_ressources(champ):
|
||||
champ_purge = supprime_accent_espace(champ)
|
||||
for sem in DATA_RESSOURCES:
|
||||
for code in DATA_RESSOURCES[sem]:
|
||||
nom_purge = supprime_accent_espace(DATA_RESSOURCES[sem][code])
|
||||
if champ_purge.startswith(nom_purge):
|
||||
return DATA_RESSOURCES[sem][code] # le bon nom
|
||||
|
||||
old = r.nom
|
||||
titre = devine_nom_from_ressources(r.nom)
|
||||
if titre and titre != old:
|
||||
__LOGGER.warning(f"nettoie_titre : {old} => titre \"{titre}\"")
|
||||
r.nom = titre
|
||||
|
||||
def nettoie_acs(r):
|
||||
"""Nettoie les acs d'une ressource en les remplaçant par leur code pour les 3 compétences"""
|
||||
if len(r.apprentissages) != 3:
|
||||
__LOGGER.warning(f"nettoie_acs : Problème dans le nombre de compétences de {r.nom}")
|
||||
for comp in range(3):
|
||||
donnees = r.apprentissages[comp] # chaine de caractères listant les ACS
|
||||
# donnees = donnees.replace("\t", "").replace("-", "") # supprime les tabulations
|
||||
acs_avec_code = devine_acs_by_code(donnees)
|
||||
acs_avec_nom = devine_acs_by_nom(donnees)
|
||||
acs_finaux = acs_avec_code + acs_avec_nom
|
||||
acs_finaux = [ac.replace(" ", "") for ac in acs_finaux]
|
||||
acs_finaux = sorted(list(set(acs_finaux)))
|
||||
r.apprentissages[comp] = acs_finaux
|
||||
|
||||
def nettoie_prerequis(r):
|
||||
"""Nettoie les prérequis (ressource) en les remplaçant par leur code de ressource"""
|
||||
R_avec_code = devine_ressources_by_code(r.prerequis)
|
||||
R_avec_nom = devine_ressources_by_code(r.prerequis)
|
||||
R_finaux = sorted(list(set(R_avec_code + R_avec_nom)))
|
||||
if R_finaux:
|
||||
r.prerequis = R_finaux
|
||||
else:
|
||||
r.prerequis = "Aucun"
|
||||
|
||||
def supprime_accent_espace(chaine):
|
||||
"""Met en minuscule, supprime les accents, les ponctuations et les espaces"""
|
||||
purge = chaine.lower().replace("'", "").replace("’", "")
|
||||
purge = unicodedata.normalize('NFD', purge).encode('ascii', 'ignore').decode('ascii')
|
||||
purge = purge.replace(" ", "")
|
||||
@ -72,6 +195,8 @@ def supprime_accent_espace(chaine):
|
||||
|
||||
|
||||
def get_code_from_nom(ressource):
|
||||
"""Récupère le code d'une ressource d'après son nom en utilisant les noms officiels
|
||||
des ressources du yaml"""
|
||||
nom = supprime_accent_espace(ressource.nom)
|
||||
for sem in DATA_RESSOURCES:
|
||||
for code in DATA_RESSOURCES[sem]:
|
||||
@ -103,6 +228,88 @@ def devine_acs_by_nom(donnees):
|
||||
acs += [code]
|
||||
return sorted(list(set(acs)))
|
||||
|
||||
def devine_ressources_by_code(champ):
|
||||
"""Recherche les codes ressources de la forme RXXX dans champ ;
|
||||
"""
|
||||
codes = re.findall(r"(R\d{3}\D)", champ) # de code à 3 chiffres
|
||||
return sorted(list(set(codes)))
|
||||
|
||||
def devine_ressources_by_nom(donnees):
|
||||
"""Partant d'une chaine de caractères, détermine les ressources
|
||||
présentes dans la donnée, en utilisant les infos officielles de
|
||||
ressources.yml"""
|
||||
donnees_purge = supprime_accent_espace(donnees)
|
||||
codes = []
|
||||
for sem in DATA_RESSOURCES:
|
||||
for code in DATA_RESSOURCES[sem]:
|
||||
nom_purge = supprime_accent_espace(DATA_RESSOURCES[sem][code])
|
||||
if nom_purge in donnees_purge:
|
||||
codes += [code]
|
||||
return sorted(list(set(codes)))
|
||||
|
||||
def nettoie_description(r):
|
||||
champs = r.description.split("\n")
|
||||
champs = [c for c in champs if c] # supprime les lignes vides
|
||||
|
||||
indicea = 0 # la ligne mentionnant le contexte
|
||||
if True in [ligne.startswith("Contexte et ") for ligne in champs]: # la ligne commençant par Contenus
|
||||
indicea = [ligne.startswith("Contexte et ") for ligne in champs].index(True)
|
||||
|
||||
indicec = 0
|
||||
if True in [ligne.startswith("Contenus") for ligne in champs]: # la ligne commençant par Contenus
|
||||
indicec = [ligne.startswith("Contenus") for ligne in champs].index(True)
|
||||
if indicea>0:
|
||||
contexte = "\n".join(champs[indicea:indicec])
|
||||
else:
|
||||
contexte = "\n".join(champs[:indicec])
|
||||
|
||||
contenus = champs[indicec+1:]
|
||||
# suppression des \t
|
||||
contenus = [ligne.rstrip().replace("--", "-") for ligne in contenus]
|
||||
contenus = [c for c in contenus if c] # supprime les lignes vides
|
||||
marqueurs = []
|
||||
for ligne in contenus:
|
||||
m = re.search(r"(\t)*", ligne) # dès \t ?
|
||||
if m.group() != "":
|
||||
ajout = m.group()
|
||||
else:
|
||||
ajout = ""
|
||||
ligne = ligne.replace("\t","")[0]
|
||||
if ligne[0] not in string.ascii_letters and ligne[0] != "É":
|
||||
marqueurs += [ajout + ligne[0]]
|
||||
|
||||
def has_digits(liste):
|
||||
return sum([m in string.digits for m in liste])>0
|
||||
|
||||
a_marqueur_numerique = has_digits(marqueurs) # des marqueurs numériques ?
|
||||
marqueurs_finaux = [] # tri les marqueurs
|
||||
for m in marqueurs:
|
||||
if m not in string.digits and m not in marqueurs_finaux:
|
||||
marqueurs_finaux.append(m)
|
||||
elif m not in marqueurs_finaux:
|
||||
if a_marqueur_numerique:
|
||||
if not has_digits(marqueurs_finaux):
|
||||
marqueurs_finaux.append(m)
|
||||
|
||||
contenus_fin = contenus[:] # copie des ligne
|
||||
for (i, ligne) in enumerate(contenus):
|
||||
if ligne[0] in string.digits:
|
||||
pos = marqueurs_finaux.index("1")
|
||||
if ligne[1:].startswith("/"):
|
||||
contenus_fin[i] = "\t" * pos + "* " + ligne[2:].replace("\t", "").rstrip()
|
||||
else:
|
||||
contenus_fin[i] = "\t" * pos + "* " + ligne[1:].replace("\t", "").rstrip() # la ligne avec marqueur supprimé et / supprimé
|
||||
else:
|
||||
if ligne[0] in marqueurs_finaux:
|
||||
pos = marqueurs_finaux.index(ligne[0])
|
||||
contenus_fin[i] = "\t" * pos + "* " + ligne[1:].replace("\t", "").rstrip()
|
||||
|
||||
contenu = "\n".join(contenus_fin)
|
||||
|
||||
r.contexte = contexte
|
||||
r.contenu = contenu
|
||||
print(r.nom, contexte, contenu, sep="\n")
|
||||
|
||||
if __name__=="__main__":
|
||||
# Eléments de test
|
||||
for sem in DATA_RESSOURCES:
|
||||
|
Loading…
Reference in New Issue
Block a user