From a1cda41e514807bf62d105a047d44721592c5677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9o=20Baras?= Date: Sat, 3 Apr 2021 09:53:25 +0200 Subject: [PATCH] Ajout l'export yaml des ExemplesSAE --- latex/macros_formations.sty | 2 +- latex/saes/SAE11.tex | 3 +- latex/saes/SAE12.tex | 2 +- python/export_docx_to_yaml.py | 2 +- python/export_sae_docx_to_yaml.py | 36 +++++++++++++-- python/export_yaml_to_latex.py | 15 +++++-- python/officiel.py | 9 +++- python/ressource.py | 73 ++++++++++++++++++++++++++++++- python/ressourcedocx.py | 71 ++++++++++++++++++++++++++++-- python/tools.py | 6 ++- 10 files changed, 201 insertions(+), 18 deletions(-) diff --git a/latex/macros_formations.sty b/latex/macros_formations.sty index 814aee5..60bb638 100644 --- a/latex/macros_formations.sty +++ b/latex/macros_formations.sty @@ -161,7 +161,7 @@ % **************************** -% Déclaration de la ressource : +% Déclaration de la saé : % \nouvellesae{code_sae}{intitule_sae} \def\nouvellesae#1#2{ \addtocounter{cptsae}{1} % Ajoute une ressource (tous semestres confondu) diff --git a/latex/saes/SAE11.tex b/latex/saes/SAE11.tex index 74b82a8..ea0254e 100644 --- a/latex/saes/SAE11.tex +++ b/latex/saes/SAE11.tex @@ -23,7 +23,8 @@ % Le description -\ajoutSdescription{Il s'agit de faire prendre conscience aux étudiants les risques +\ajoutSdescription{ +Il s'agit de faire prendre conscience aux étudiants les risques potentiels pris par l'usager d'un environnement numérique et de leur fournir les réflexes afin de devenir un usager conscient, averti et responsable. L'hygiène informatique et les bonnes pratiques de l'usage diff --git a/latex/saes/SAE12.tex b/latex/saes/SAE12.tex index 9bafffe..965a237 100644 --- a/latex/saes/SAE12.tex +++ b/latex/saes/SAE12.tex @@ -2,7 +2,7 @@ % Ressources %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\nouvellesae{SAÉ12}{S’initier aux réseaux informatiques} +\nouvellesae{SAÉ12}{S'initier aux réseaux informatiques} \ajoutSheures{10}{7}{20} diff --git a/python/export_docx_to_yaml.py b/python/export_docx_to_yaml.py index 734109a..535815f 100644 --- a/python/export_docx_to_yaml.py +++ b/python/export_docx_to_yaml.py @@ -118,7 +118,7 @@ print(f"{nbre_ressources} ressources") ressources = {"S1" : [], "S2": []} for r in liste_ressources: - nettoie_titre(r) + nettoie_titre_ressource(r) nettoie_heure_ressource(r) nettoie_code(r, type="ressource") nettoie_semestre(r) diff --git a/python/export_sae_docx_to_yaml.py b/python/export_sae_docx_to_yaml.py index 54d738b..e7864b6 100644 --- a/python/export_sae_docx_to_yaml.py +++ b/python/export_sae_docx_to_yaml.py @@ -105,7 +105,7 @@ for i in range(1, len(docu)): # A priori un tableau r.charge_ac(apprentissages) # nettoie le titre et le code - nettoie_titre(r) + nettoie_titre_sae(r) nettoie_code(r, type="sae") last_sae = r.code @@ -116,7 +116,7 @@ for i in range(1, len(docu)): # A priori un tableau nom_exemple = res[0][1][0] # Création de la ressource - r = ExempleSAEDocx(nom_exemple, res) + r = ExempleSAEDocx(nom_exemple, res, last_sae) liste_exemples[last_sae].append(r) # Parsing des données brute de la sae @@ -159,8 +159,10 @@ for s in liste_exemples: print(f"{s} :" + str(len(liste_exemples[s])) + " exemples") # ************************************************************************ +print("*Etape 2* : Post-traitement") # Post traitement des saes => gestion des heures/des acs/ + tri par semestre +print(" > SAE") saes = {"S1" : [], "S2": []} for s in liste_saes: @@ -176,7 +178,26 @@ for s in liste_saes: # Tri dans le bon semestre saes[s.semestre] += [s] -# # Export yaml +# Post traitement des exemples "S1" => "codesae chapeau" => "ExempleSAE" +exemples = {"S1" : {}, "S2" : {} } +print(" > Exemples") +for s in liste_exemples: # la sae + sem = get_officiel_sem_sae_by_code(s) + exemples[sem][s] = [] + for e in liste_exemples[s]: + print(f"{s} : {e.nom}") + # nettoie_description(s) => rien à faire ? + nettoie_description(e) + nettoie_problematique(e) + if e.nom.startswith("Concevoir"): + print("ici") + nettoie_modalite(e) + + # Tri dans le bon semestre + exemples[sem][s].append(e) + +# Export yaml +print("*Etape 3* : Export yaml") for sem in saes: for s in saes[sem]: output = s.to_yaml() @@ -185,3 +206,12 @@ for sem in saes: with open(fichier, "w", encoding="utf8") as fid: fid.write(output) +for sem in exemples: + for s in exemples[sem]: + for (i, e) in enumerate(exemples[sem][s]): + output = e.to_yaml() + fichier = "export/{}_exemple{}.yml".format(s.replace("É", "E"), i+1) + with open(fichier, "w", encoding="utf8") as fid: + fid.write(output) + + diff --git a/python/export_yaml_to_latex.py b/python/export_yaml_to_latex.py index 04180ef..f9c9f95 100644 --- a/python/export_yaml_to_latex.py +++ b/python/export_yaml_to_latex.py @@ -1,5 +1,5 @@ -from ressource import Ressource, SAE -from ressourcedocx import * +from ressource import * +import os import pypandoc @@ -27,12 +27,21 @@ fichiers = os.listdir(REPERTOIRE_RESSOURCES) fichiers = sorted(fichiers) # tri par ordre alphabétique saes = {"S1": [], "S2": []} +exemples = {"S1" : {}, "S2" : {} } + for file in fichiers: fichieryaml = REPERTOIRE_RESSOURCES + "/" + file - if file.startswith("S"): # si c'est une sae + if file.startswith("S") and "exemple" not in file: # si c'est le chapeau d'une sae s = SAE(fichieryaml) sem = "S" + str(s.sae["semestre"]) saes[sem].append(s) + elif file.startswith("S") and "exemple" in file: # si c'est un exemple de sae + e = ExempleSAE(fichieryaml) + sem = "S" + str(e.exemple["semestre"]) + sae = e.exemple["code"] + if sae not in exemples[sem]: + exemples[sem][sae] = [] + exemples[sem][sae].append(e) # Eléments de tests r1 = ressources["S1"][0] diff --git a/python/officiel.py b/python/officiel.py index 74bb0ca..4d718d4 100644 --- a/python/officiel.py +++ b/python/officiel.py @@ -109,6 +109,7 @@ def get_officiel_sae_name_by_code(code): return get_officiel_name_by_code_using_dict(code, DATA_SAES) + def get_code_from_nom_using_dict(ressource, dico): """Récupère le code d'une ressource d'après son nom en utilisant les noms officiels des ressources du yaml si dico == DATA_RESSOURCES ; sinon fait de même avec les SAE""" @@ -117,4 +118,10 @@ def get_code_from_nom_using_dict(ressource, dico): for code in dico[sem]: nom_data = supprime_accent_espace(dico[sem][code]) if nom.startswith(nom_data): - return code \ No newline at end of file + return code + +def get_officiel_sem_sae_by_code(sae): + """Récupère le semestre de la SAE d'après son code""" + for sem in DATA_SAES: + if sae in DATA_SAES[sem]: + return sem \ No newline at end of file diff --git a/python/ressource.py b/python/ressource.py index ce0b9ac..156da7e 100644 --- a/python/ressource.py +++ b/python/ressource.py @@ -106,7 +106,7 @@ class Ressource(): class SAE(): - """Modélise une ressource lorsqu'elle est extraite d'un yaml""" + """Modélise une saé (chapeau) lorsqu'elle est extraite d'un yaml""" __LOGGER = logging.getLogger(__name__) def __init__(self, fichieryaml): @@ -139,6 +139,77 @@ class SAE(): ressources = "\n".join(resRT) + # préparation du descriptif + descriptif = self.sae["description"] + if descriptif == "Aucun": + descriptif = "" + SAE.__LOGGER.warning(f"{self.sae['titre']} n'a pas de description") + else: + descriptif = descriptif.replace("\n", "\n\n").replace("\n" * 4, "\n") # corrige les suppressions de ligne à la relecture du yaml + descriptif = md_to_latex(descriptif) + + # préparation des livrables + livrables = self.sae["livrables"] + if livrables == "Aucun": + livrables = "" + SAE.__LOGGER.warning(f"{self.sae['titre']} n'a pas de livrables") + else: + livrables = livrables.replace("\n", "\n\n").replace("\n" * 4, "\n") # corrige les suppressions de ligne à la relecture du yaml + livrables = md_to_latex(livrables) + + chaine = "" + chaine = TemplateLatex(modlatex).substitute(code=self.sae["code"], + titre=self.sae["titre"], + heures_encadrees=self.sae["heures_encadrees"], + heures_tp=self.sae["tp"], + heures_projet=self.sae["projet"], + compRT1=compRT[0], + compRT2=compRT[1], + compRT3=compRT[2], + description=caracteres_recalcitrants(descriptif), + ressources=ressources, + livrables= livrables, + motscles = caracteres_recalcitrants(self.sae["motscles"]), + ) + # chaine = chaine.replace("&", "\&") + + chaine = chaine.replace("\\tightlist\n", "") + return chaine + +class ExempleSAE(): + """Modélise un exemple de SAE lorsqu'elle est extraite d'un yaml""" + __LOGGER = logging.getLogger(__name__) + + def __init__(self, fichieryaml): + with open(fichieryaml, "r", encoding="utf8") as fid: + yaml = ruamel.yaml.YAML() + try: + self.exemple = yaml.load(fid.read()) + except: + Ressource.__LOGGER.warning(f"Pb de chargement de {fichieryaml}") + + def to_latex(self, modele="pn/modele_sae_exemple.tex"): + """Génère le code latex décrivant la ressource""" + modlatex = get_modele(modele) #"pn/modele_ressource.tex") + + # Préparation des ac + ajoutac = "\\ajoutSac{%s}{%s}" + compRT = [] + for accomp in self.sae["acs"]: + comps = [] + for no_ac in range(len(self.sae["acs"][accomp])): # les ac de la comp + code_ac = self.sae["acs"][accomp][no_ac] + comps.append( ajoutac % (code_ac, DATA_ACS[accomp][code_ac]) ) + compRT.append("\n".join(comps)) + + # Préparation des ressources + ajoutressources = "\\ajoutSressources{%s}{%s}" + resRT = [] + for (i, res) in enumerate(self.sae["ressources"]): # in range(len(self.apprentissages)): + resRT.append(ajoutressources % (res, get_officiel_ressource_name_by_code(res))) + ressources = "\n".join(resRT) + + # préparation du descriptif descriptif = self.sae["description"] if descriptif == "Aucun": diff --git a/python/ressourcedocx.py b/python/ressourcedocx.py index 8aacea2..4d007ef 100644 --- a/python/ressourcedocx.py +++ b/python/ressourcedocx.py @@ -160,8 +160,9 @@ def nettoie_semestre(r): __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 nettoie_titre_ressource(r): + """Nettoie le titre d'une ressource en utilisant les titres officiels fournis dans le + yaml (via le dictionnaire DATA_RESSOURCES)""" def devine_nom_from_ressources(champ): champ_purge = supprime_accent_espace(champ) for sem in DATA_RESSOURCES: @@ -173,9 +174,26 @@ def nettoie_titre(r): old = r.nom titre = devine_nom_from_ressources(r.nom) if titre and titre != old: - __LOGGER.warning(f"nettoie_titre : {old} => titre \"{titre}\"") + __LOGGER.warning(f"nettoie_titre_ressource : {old} => titre \"{titre}\"") r.nom = titre +def nettoie_titre_sae(s): + """Nettoie le titre d'une sae en utilisant les titres officiels fournis dans le + yaml (via le dictionnaire DATA_RESSOURCES)""" + def devine_nom_from_sae(champ): + champ_purge = supprime_accent_espace(champ) + for sem in DATA_SAES: + for code in DATA_SAES[sem]: + nom_purge = supprime_accent_espace(DATA_SAES[sem][code]) + if champ_purge.startswith(nom_purge): + return DATA_SAES[sem][code] # le bon nom + + old = s.nom + titre = devine_nom_from_sae(s.nom) + if titre and titre != old: + __LOGGER.warning(f"nettoie_titre_sae : {old} => titre \"{titre}\"") + s.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: @@ -370,6 +388,8 @@ def convert_to_markdown(contenu): if m: pos = marqueurs_finaux.index(m) contenus_fin[i] = "\t" * (pos) + "* " + ligne.replace(m, "").replace("\t", "").rstrip() + + contenu = "\n\n".join(contenus_fin) return contenu @@ -388,6 +408,31 @@ def nettoie_livrables_sae(s): contenu = convert_to_markdown(contenu) s.livrables = contenu +def nettoie_description(s): + """Nettoie la description d'un exemple de SAE""" + contenu = s.description + contenu = remove_link(contenu) # supprime les liens + contenu = convert_to_markdown(contenu) + s.description = contenu + +def nettoie_problematique(s): + """Nettoie la description d'un exemple de SAE""" + if s.problematique: + contenu = s.problematique + contenu = convert_to_markdown(contenu) + s.problematique = contenu + else: + s.problematique = "" + +def nettoie_modalite(s): + """Nettoie les modalités (d'évaluation) d'un exemple de SAE""" + if s.modalite: + contenu = s.modalite + contenu = convert_to_markdown(contenu) + s.modalite = contenu + else: + s.modalite = f"Les même que les livrables et les productions de la {s.code}" + class SAEDocx(): def __init__(self, nom, brut): @@ -405,6 +450,7 @@ class SAEDocx(): self.livrables = livrables self.mots = mots + def charge_ac(self, apprentissages): self.apprentissages = apprentissages @@ -430,9 +476,12 @@ class SAEDocx(): class ExempleSAEDocx(): - def __init__(self, nom, brut): + def __init__(self, nom, brut, code): self.nom = nom self.brut = brut # les données brutes de la ressource + self.code = code # code de la SAE à laquelle l'exemple est raccroché + # Ajoute le semestre de la SAE + self.semestre = int(get_officiel_sem_sae_by_code(code)[1]) def charge_informations(self, description, formes, problematique, modalite): self.description = description @@ -440,6 +489,20 @@ class ExempleSAEDocx(): self.problematique = problematique self.modalite = modalite + def to_yaml(self): + """Exporte la ressource en yaml""" + dico = {"titre": self.nom, + "code": self.code, + "semestre": self.semestre, + "description": folded(self.description), + "formes": self.formes, + "problematique": folded(self.problematique), + "modalite": folded(self.modalite), + } + output = ruamel.yaml.dump(dico, Dumper=ruamel.yaml.RoundTripDumper, + allow_unicode=True, width=100) + output = output.replace("\n\n\n", "\n\n") + return output if __name__=="__main__": # Eléments de test diff --git a/python/tools.py b/python/tools.py index e9e11f6..5354578 100644 --- a/python/tools.py +++ b/python/tools.py @@ -20,8 +20,10 @@ def get_indice_sans_accent_ni_espace(champ, entetes): def caracteres_recalcitrants(contenu): - contenu = contenu.replace("è", "è").replace(b"\xe2\x80\x99".decode("utf8"), "'").replace("é", "é") - contenu = contenu.replace("’", "'") + contenu = contenu.replace("\'", "'") + contenu = contenu.replace("è", "è") + contenu = contenu.replace("é", "é") + contenu = contenu.replace("’", "'").replace(b"\xe2\x80\x99".decode("utf8"), "'") contenu = contenu.replace("â", "â").replace(b'a\xcc\x82'.decode("utf8"), "â") contenu = contenu.replace('\xa0', ' ') # le nbsp