forked from viennet/Referentiels
969 lines
33 KiB
Python
969 lines
33 KiB
Python
import logging
|
|
import re
|
|
import string
|
|
import pypandoc
|
|
import ruamel.yaml
|
|
|
|
from config import Config
|
|
|
|
from modeles import get_modele, TemplateLatex
|
|
from officiel import *
|
|
from ressourcedocx import remove_ligne_vide
|
|
from tools import caracteres_recalcitrants
|
|
|
|
__LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
def nettoie_latex(chaine):
|
|
"""Purge certains éléments de la chaine latex générée par pypandoc"""
|
|
chaine = chaine.replace("\\tightlist\n", "")
|
|
chaine = ajoute_abbr_latex(chaine) # détecte les abréviations
|
|
|
|
# detecte les espaces insécables
|
|
chaine = chaine.replace(" :", "~:")
|
|
m = re.findall(r"(\w\w:)", chaine)
|
|
m += re.findall(r"(\w}:)", chaine)
|
|
for marq in m:
|
|
if marq != "ex:" and marq != "ps:" and marq != "tp:": # les ex et les liens
|
|
chaine = chaine.replace(marq, marq[0:2] + "~:")
|
|
m = re.findall(r"(:\w)", chaine) # les : suivis d'une lettre
|
|
m += re.findall(r"(:\\)", chaine)
|
|
for marq in m:
|
|
chaine = chaine.replace(marq, ": " + marq[-1])
|
|
chaine = chaine.replace(" ;", "\,;")
|
|
m = re.findall(r"(\w;)", chaine)
|
|
m += re.findall(r"(\);)", chaine)
|
|
for marq in m:
|
|
chaine = chaine.replace(marq, marq[0] + "\,;")
|
|
|
|
# Ajoute les topsep
|
|
lignes = chaine.split("\n")
|
|
nbre_itemize = 0
|
|
for (i, ligne) in enumerate(lignes):
|
|
if "\\begin{itemize}" in ligne: # on rencontre un itemize
|
|
nbre_itemize += 1
|
|
if nbre_itemize == 1 and i != 0: # si c'est le 1er itemize et que ce n'est pas la 1ère ligne
|
|
lignes[i] = lignes[i].replace("\\begin{itemize}", "\\begin{itemize}[topsep=5pt]")
|
|
elif "\\end{itemize}" in ligne:
|
|
nbre_itemize -= 1
|
|
chaine = "\n".join(lignes)
|
|
|
|
return chaine
|
|
|
|
|
|
class Ressource:
|
|
"""Modélise une ressource 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.ressource = yaml.load(fid.read())
|
|
except:
|
|
Ressource.__LOGGER.warning(f"Pb de chargement de {fichieryaml}")
|
|
|
|
def to_latex(self, modele=Config.ROOT + "/python/pn/modele_ressource.tex"):
|
|
"""Génère le code latex décrivant la ressource"""
|
|
modlatex = get_modele(modele) # "pn/modele_ressource.tex")
|
|
|
|
# if self.ressource["code"] == "R107":
|
|
# print("ici")
|
|
|
|
# Préparation des coeffs
|
|
ajoutcoeff = "\\ajoutRcoeff{%s}"
|
|
coeffRT = []
|
|
for comp in ["RT1", "RT2", "RT3"]:
|
|
if comp in self.ressource["coeffs"]:
|
|
coeffRT.append(ajoutcoeff % (str(self.ressource["coeffs"][comp])))
|
|
else:
|
|
coeffRT.append("")
|
|
|
|
# Préparation des ac
|
|
ajoutac = "\\ajoutRac{%s}{%s}"
|
|
compRT = []
|
|
for accomp in ["RT1", "RT2", "RT3"]:
|
|
comps = []
|
|
if accomp in self.ressource["acs"]:
|
|
for no_ac in range(
|
|
len(self.ressource["acs"][accomp])
|
|
): # les ac de la comp
|
|
code_ac = self.ressource["acs"][accomp][no_ac]
|
|
comps.append(ajoutac % (code_ac, DATA_ACS[accomp][code_ac]))
|
|
compRT.append("\n".join(comps))
|
|
|
|
# Préparation des sae
|
|
ajoutsaes = "\\ajoutRsae{%s}{%s}" # nom, intitule, code_latex
|
|
saesRT = []
|
|
for (i, sae) in enumerate(
|
|
self.ressource["sae"]
|
|
): # in range(len(self.apprentissages)):
|
|
code_latex = (
|
|
string.ascii_uppercase[int(sae[-2]) - 1]
|
|
+ string.ascii_uppercase[int(sae[-1]) - 1]
|
|
)
|
|
saesRT.append(
|
|
ajoutsaes % (sae, get_officiel_sae_name_by_code(sae))
|
|
) # , code_latex))
|
|
saes = "\n".join(saesRT)
|
|
|
|
if self.ressource["code"] == "R110":
|
|
print("ici")
|
|
prerequis = ""
|
|
if self.ressource["prerequis"] == AUCUN_PREREQUIS:
|
|
prerequis = ""
|
|
else:
|
|
# est-une liste de ressources
|
|
if not self.ressource["prerequis"][0].startswith("R"):
|
|
prerequis = "\\ajoutRprerequislycee{%s}" % (self.ressource["prerequis"])
|
|
else:
|
|
ajoutprerequis = "\\ajoutRprerequis{%s}{%s}"
|
|
liste = []
|
|
for (no, mod) in enumerate(self.ressource["prerequis"]):
|
|
liste.append(
|
|
ajoutprerequis % (mod, get_officiel_ressource_name_by_code(mod))
|
|
)
|
|
prerequis = "\n".join(liste)
|
|
|
|
# préparation du contexte
|
|
contexte = self.ressource["contexte"]
|
|
if contexte == "Aucun":
|
|
contexte = ""
|
|
Ressource.__LOGGER.warning(f"{self.ressource['nom']} n'a pas de contexte")
|
|
|
|
else:
|
|
contexte = md_to_latex(contexte)
|
|
|
|
# contexte = remove_ligne_vide(contexte)
|
|
# préparation du contenu
|
|
|
|
contenu = self.ressource["contenu"] # supprime les passages à la ligne
|
|
|
|
if contenu:
|
|
if self.ressource["code"] == "R112":
|
|
print("ici")
|
|
contenu = md_to_latex(contenu)
|
|
|
|
chaine = ""
|
|
chaine = TemplateLatex(modlatex).substitute(
|
|
code=self.ressource["code"],
|
|
nom=self.ressource["nom"],
|
|
heures_formation=self.ressource["heures_formation"],
|
|
heures_tp=self.ressource["heures_tp"],
|
|
coeffRT1=coeffRT[0],
|
|
coeffRT2=coeffRT[1],
|
|
coeffRT3=coeffRT[2],
|
|
compRT1=compRT[0],
|
|
compRT2=compRT[1],
|
|
compRT3=compRT[2],
|
|
saes=saes,
|
|
motscles=self.ressource["motscles"] + ".",
|
|
prerequis=prerequis,
|
|
contexte=contexte,
|
|
contenu=contenu,
|
|
)
|
|
# chaine = chaine.replace("&", "\&")
|
|
chaine = nettoie_latex(chaine)
|
|
|
|
# Insère les abbréviations
|
|
return chaine
|
|
|
|
|
|
def contient_abbr(chaine):
|
|
"""Détecte les abréviations présentes dans la chaine
|
|
(dont la liste est fournie par DATA_ABBREVIATIONS lues depuis le .yml) et
|
|
les renvoie sous forme d'une liste par abréviations de nombre de caractères décroissants"""
|
|
mots = []
|
|
for lettre in DATA_ABBREVIATIONS:
|
|
for mot in DATA_ABBREVIATIONS[lettre]:
|
|
if mot in chaine:
|
|
mots.append(mot)
|
|
mots = sorted(
|
|
mots, key=lambda m: len(m), reverse=True
|
|
) # les mots triés par nbre de carac décroissant
|
|
return mots
|
|
|
|
|
|
def ajoute_abbr_latex(chaine):
|
|
"""
|
|
Parse la chaine latex pour ajouter les abbréviations et les remplacer par
|
|
\\textabbrv{abreviation}
|
|
"""
|
|
mots = chaine.split(" ")
|
|
for (i, mot) in enumerate(mots):
|
|
abbrs = contient_abbr(mot)
|
|
if abbrs:
|
|
mots[i] = mots[i].replace(abbrs[0], "\\textabbrv{" + abbrs[0] + "}")
|
|
chaine = " ".join(mots)
|
|
if "/IP" in chaine:
|
|
chaine = chaine.replace("/IP", "/\\textabbrv{IP}")
|
|
return chaine
|
|
|
|
def contient_commandes(chaine):
|
|
"""Détecte si la chaine est une commande (éventuellement avec un caractère
|
|
de ponctuation final)"""
|
|
chaine_texte = ""
|
|
for car in chaine:
|
|
if car in string.ascii_lowercase + "-":
|
|
chaine_texte += car
|
|
if "ipc" in chaine:
|
|
print("ici")
|
|
if chaine_texte in DATA_MOTSCLES["commandes"]:
|
|
return chaine_texte
|
|
return None
|
|
|
|
def ajoute_cmd_latex(chaine):
|
|
"""
|
|
Parse la chaine latex pour ajouter les abbréviations et les remplacer par
|
|
\\textabbrv{abreviation}
|
|
"""
|
|
mots = chaine.split(" ")
|
|
for (i, mot) in enumerate(mots):
|
|
champs = mot.split("\n")
|
|
for (j, champ) in enumerate(champs):
|
|
cmd = contient_commandes(champ)
|
|
if cmd:
|
|
champs[j] = champs[j].replace(cmd, "\\texttt{" + cmd + "}")
|
|
mots[i] = "\n".join(champs)
|
|
chaine = " ".join(mots)
|
|
return chaine
|
|
|
|
class SAE:
|
|
"""Modélise une saé (chapeau) 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.sae = yaml.load(fid.read())
|
|
except:
|
|
Ressource.__LOGGER.warning(f"Pb de chargement de {fichieryaml}")
|
|
|
|
def to_latex(self, modele=Config.ROOT + "/python/pn/modele_sae.tex"):
|
|
"""Génère le code latex décrivant la ressource"""
|
|
modlatex = get_modele(modele) # "pn/modele_ressource.tex")
|
|
|
|
# Préparation des coeffs
|
|
ajoutcoeff = "\\ajoutScoeff{%s}"
|
|
coeffRT = []
|
|
for comp in ["RT1", "RT2", "RT3"]:
|
|
if comp in self.sae["coeffs"]:
|
|
coeffRT.append(ajoutcoeff % (str(self.sae["coeffs"][comp])))
|
|
else:
|
|
coeffRT.append("")
|
|
|
|
# Préparation des ac
|
|
ajoutac = "\\ajoutSac{%s}{%s}" # nom, intitule, code latex
|
|
compRT = []
|
|
for accomp in ["RT1", "RT2", "RT3"]:
|
|
comps = []
|
|
if accomp in self.sae["acs"]:
|
|
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":
|
|
descriptif = ""
|
|
SAE.__LOGGER.warning(f"{self.sae['titre']} n'a pas de description")
|
|
else:
|
|
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 = 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"],
|
|
coeffRT1=coeffRT[0],
|
|
coeffRT2=coeffRT[1],
|
|
coeffRT3=coeffRT[2],
|
|
compRT1=compRT[0],
|
|
compRT2=compRT[1],
|
|
compRT3=compRT[2],
|
|
description=descriptif,
|
|
ressources=ressources,
|
|
livrables=livrables,
|
|
motscles=self.sae["motscles"] + ".",
|
|
)
|
|
# chaine = chaine.replace("&", "\&")
|
|
|
|
chaine = nettoie_latex(chaine)
|
|
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=Config.ROOT + "/python/pn/modele_exemple_sae.tex"):
|
|
"""Génère le code latex décrivant la ressource"""
|
|
modlatex = get_modele(modele) # "pn/modele_ressource.tex")
|
|
|
|
# préparation du descriptif
|
|
description = self.exemple["description"]
|
|
if not description:
|
|
description = ""
|
|
ExempleSAE.__LOGGER.warning(
|
|
f"{self.exemple['titre']} n'a pas de description"
|
|
)
|
|
else:
|
|
description = md_to_latex(description)
|
|
|
|
|
|
# préparation de la forme
|
|
formes = self.exemple["formes"]
|
|
if not formes:
|
|
formes = ""
|
|
ExempleSAE.__LOGGER.warning(f"{self.exemple['titre']} n'a pas de formes")
|
|
else:
|
|
formes = md_to_latex(formes)
|
|
|
|
# préparation de la problématique
|
|
problematique = self.exemple["problematique"]
|
|
if not problematique:
|
|
problematique = ""
|
|
ExempleSAE.__LOGGER.warning(
|
|
f"{self.exemple['titre']} n'a pas de problematique"
|
|
)
|
|
else:
|
|
problematique = md_to_latex(problematique)
|
|
if "15" in self.exemple["code"]:
|
|
# supprime le \\[3pt]
|
|
problematique = problematique[:-7]
|
|
|
|
# préparation des modalites
|
|
modalite = self.exemple["modalite"]
|
|
if not modalite:
|
|
modalite = ""
|
|
ExempleSAE.__LOGGER.warning(f"{self.exemple['titre']} n'a pas de modalite")
|
|
else:
|
|
modalite = md_to_latex(modalite)
|
|
|
|
chaine = ""
|
|
chaine = TemplateLatex(modlatex).substitute(
|
|
titre=self.exemple["titre"],
|
|
description=description,
|
|
formes=formes,
|
|
problematique=problematique,
|
|
modalite=modalite,
|
|
)
|
|
# chaine = chaine.replace("&", "\&")
|
|
chaine = nettoie_latex(chaine)
|
|
|
|
return chaine
|
|
|
|
|
|
def md_to_latex(contenu):
|
|
"""Réalise la conversion markdown to latex avec pypandoc"""
|
|
contenu = contenu.replace(
|
|
"\n", "\n\n"
|
|
) # corrige les suppressions de ligne à la relecture du yaml
|
|
|
|
contenu = pypandoc.convert_text(
|
|
contenu, "tex", format="md", extra_args=["--atx-headers"]
|
|
)
|
|
contenu = contenu.replace("\r\n", "\n")
|
|
lignes = contenu.split("\n\n") # Détecte les sauts de ligne
|
|
for (i, ligne) in enumerate(lignes):
|
|
if i < len(lignes) - 1:
|
|
if (
|
|
lignes[i].strip().startswith("\\") == False
|
|
and lignes[i].startswith(" ") == False
|
|
and lignes[i + 1].strip().startswith("\\") == False
|
|
and lignes[i + 1].startswith(" ") == False
|
|
and lignes[i].strip().endswith("\\\\") == False
|
|
):
|
|
lignes[i] = lignes[i] + "\\\\" # ajoute un passage à la ligne latex
|
|
contenu = "\n\n".join(lignes)
|
|
|
|
# contenu = caracteres_recalcitrants(contenu)
|
|
contenu = remove_ligne_vide(contenu)
|
|
lignes = contenu.split("\n") # pour debug
|
|
|
|
if contenu.startswith("\\begin{itemize}"):
|
|
contenu = (
|
|
"\\vspace{-10pt}\n" + contenu
|
|
) # ajout d'un offset en cas de liste à puces
|
|
contenu = contenu.replace("\\\\" * 2, "\\\\[25pt]")
|
|
if not contenu.endswith("\\end{itemize}"):
|
|
contenu += "\\\\[3pt]"
|
|
|
|
contenu = ajoute_cmd_latex(contenu) # détecte les commandes
|
|
|
|
return contenu
|
|
|
|
|
|
def get_matrices_ac_ressource(saes, ressources, sem):
|
|
"""Calcule la matrice AC vs sae + ressource pour un sem donné et la renvoie"""
|
|
les_codes_acs = [code for comp in DATA_ACS for code in DATA_ACS[comp]]
|
|
nbre_acs = len(les_codes_acs)
|
|
|
|
saesem = saes[sem] # les saé du semestre
|
|
ressem = ressources[sem] # les ressources du semestre
|
|
|
|
nbre_saes = len(DATA_SAES[sem])
|
|
nbre_ressources = len(DATA_RESSOURCES[sem])
|
|
if len(saesem) != nbre_saes or len(ressem) != nbre_ressources:
|
|
__LOGGER.warning(f"Pb => il manque des saes/ressources au {sem}")
|
|
|
|
matrice = [[False] * (nbre_saes + nbre_ressources) for i in range(nbre_acs)]
|
|
|
|
for (i, s) in enumerate(saesem): # pour chaque SAE
|
|
for comp in s.sae["acs"]: # pour chaque comp
|
|
for (j, ac) in enumerate(DATA_ACS[comp]): # pour chaque ac
|
|
if ac in s.sae["acs"][comp]: # si l'ac est prévue dans la ressource
|
|
k = les_codes_acs.index(ac)
|
|
matrice[k][i] = True
|
|
|
|
for (i, r) in enumerate(ressem): # pour chaque ressource
|
|
for comp in r.ressource["acs"]: # pour chaque comp
|
|
for (j, ac) in enumerate(DATA_ACS[comp]): # pour chaque ac
|
|
if (
|
|
ac in r.ressource["acs"][comp]
|
|
): # si l'ac est prévue dans la ressource
|
|
k = les_codes_acs.index(ac)
|
|
matrice[k][i + nbre_saes] = True
|
|
return matrice
|
|
|
|
|
|
def get_matrices_coeffs(saes, ressources, sem):
|
|
"""Calcule la matrice AC vs sae + ressource pour un sem donné et la renvoie"""
|
|
comps = ["RT1", "RT2", "RT3"]
|
|
|
|
saesem = saes[sem] # les saé du semestre
|
|
ressem = ressources[sem] # les ressources du semestre
|
|
|
|
nbre_saes = len(DATA_SAES[sem])
|
|
nbre_ressources = len(DATA_RESSOURCES[sem])
|
|
if len(saesem) != nbre_saes or len(ressem) != nbre_ressources:
|
|
__LOGGER.warning(f"Pb => il manque des saes/ressources au {sem}")
|
|
|
|
matrice = [[None] * (len(comps)) for i in range(nbre_saes + nbre_ressources)]
|
|
|
|
for (i, s) in enumerate(saesem): # pour chaque SAE
|
|
for (j, comp) in enumerate(comps): # pour chaque comp
|
|
if comp in s.sae["coeffs"]:
|
|
matrice[i][j] = s.sae["coeffs"][comp]
|
|
|
|
for (i, r) in enumerate(ressem): # pour chaque ressource
|
|
for (j, comp) in enumerate(comps): # pour chaque comp
|
|
if comp in r.ressource["coeffs"]: # pour chaque ac
|
|
matrice[i + nbre_saes][j] = r.ressource["coeffs"][comp]
|
|
return matrice
|
|
|
|
|
|
def get_matrices_volumes(saes, ressources, sem):
|
|
"""Calcule la matrice AC vs sae + ressource pour un sem donné et la renvoie"""
|
|
format = ["CM/TD", "TP", "Projet"]
|
|
|
|
saesem = saes[sem] # les saé du semestre
|
|
ressem = ressources[sem] # les ressources du semestre
|
|
|
|
nbre_saes = len(DATA_SAES[sem])
|
|
nbre_ressources = len(DATA_RESSOURCES[sem])
|
|
if len(saesem) != nbre_saes or len(ressem) != nbre_ressources:
|
|
__LOGGER.warning(f"Pb => il manque des saes/ressources au {sem}")
|
|
|
|
matrice = [[0] * (len(format)) for i in range(nbre_saes + nbre_ressources)]
|
|
|
|
for (i, s) in enumerate(saesem): # pour chaque SAE
|
|
formation = (
|
|
s.sae["heures_encadrees"]
|
|
if not isinstance(s.sae["heures_encadrees"], str)
|
|
else 0
|
|
)
|
|
tp = s.sae["tp"] if not isinstance(s.sae["tp"], str) else 0
|
|
matrice[i][0] = formation - tp
|
|
matrice[i][1] = tp
|
|
matrice[i][2] = s.sae["projet"] if not isinstance(s.sae["projet"], str) else 0
|
|
|
|
for (i, r) in enumerate(ressem): # pour chaque ressource
|
|
formation = (
|
|
r.ressource["heures_formation"]
|
|
if not isinstance(r.ressource["heures_formation"], str)
|
|
else 0
|
|
)
|
|
tp = (
|
|
r.ressource["heures_tp"]
|
|
if not isinstance(r.ressource["heures_tp"], str)
|
|
else 0
|
|
)
|
|
matrice[i + nbre_saes][0] = formation - tp
|
|
matrice[i + nbre_saes][1] = tp
|
|
|
|
return matrice
|
|
|
|
|
|
def str_matrice(matrice, saes, ressources, sem):
|
|
"""Renvoie une chaine de caractère affichant la matrice"""
|
|
les_codes_acs = [code for comp in DATA_ACS for code in DATA_ACS[comp]]
|
|
nbre_acs = len(les_codes_acs)
|
|
|
|
saesem = saes[sem] # les saé du semestre
|
|
ressem = ressources[sem] # les ressources du semestre
|
|
|
|
nbre_saes = len(DATA_SAES[sem])
|
|
nbre_ressources = len(DATA_RESSOURCES[sem])
|
|
|
|
chaine = ""
|
|
ligne = "{:20s} | " + "{:5s} | " * (nbre_saes + nbre_ressources)
|
|
valeurs = ("" for i in range(nbre_saes + nbre_ressources + 1))
|
|
trait = "-" * len(ligne.format(*valeurs))
|
|
|
|
valeurs = (
|
|
[""]
|
|
+ [s.sae["code"] if s.sae["code"] else "????" for s in saesem]
|
|
+ [r.ressource["code"] if r.ressource["code"] else "????" for r in ressem]
|
|
+ [""] * (nbre_saes - len(saesem) + nbre_ressources - len(ressem))
|
|
)
|
|
valeurs = tuple(valeurs)
|
|
chaine += ligne.format(*valeurs) + "\n" + trait + "\n"
|
|
for (j, ac) in enumerate(les_codes_acs):
|
|
valeurs = [ac] + [
|
|
("X" if matrice[j][i] == True else "")
|
|
for i in range(nbre_saes + nbre_ressources)
|
|
]
|
|
valeurs = tuple(valeurs)
|
|
chaine += ligne.format(*valeurs) + "\n"
|
|
chaine += trait + "\n"
|
|
return chaine
|
|
|
|
|
|
def cesure_contenu(contenu, long_max=30):
|
|
chaine = "\\rotatebox[origin=c]{90}{\n"
|
|
chaine += "\\begin{tabular}{ll}\n"
|
|
contenu_cesure = []
|
|
while contenu:
|
|
indice_espace = contenu.find(" ", long_max)
|
|
if indice_espace < 0:
|
|
contenu_cesure.append(contenu)
|
|
contenu = ""
|
|
else:
|
|
contenu_cesure.append(contenu[:indice_espace])
|
|
contenu = contenu[indice_espace + 1 :]
|
|
chaine += " \\\\ ".join(contenu_cesure)
|
|
chaine += "\\end{tabular} }"
|
|
return chaine
|
|
|
|
|
|
def rotation_entete_colonne(contenu, pos="l"):
|
|
chaine = "\\rotatebox[origin=" + pos + "]{90}{"
|
|
chaine += contenu + "}"
|
|
return chaine
|
|
|
|
|
|
def to_latex_matrice_acs(matrice, saes, ressources, sem):
|
|
"""Renvoie le tableau latex affichant la matrice"""
|
|
|
|
les_codes_acs = [code for comp in DATA_ACS for code in DATA_ACS[comp]]
|
|
nbre_acs = len(les_codes_acs)
|
|
|
|
lettresem = "A" if sem == "S1" else "B"
|
|
|
|
saesem = saes[sem] # les saé du semestre
|
|
ressem = ressources[sem] # les ressources du semestre
|
|
|
|
nbre_saes = len(DATA_SAES[sem])
|
|
nbre_ressources = len(DATA_RESSOURCES[sem])
|
|
nbre_colonnes = nbre_saes + nbre_ressources + 2
|
|
longueur = 4
|
|
chaine = (
|
|
"\\begin{tabular}[c]{|lp{%scm}|" % str(longueur)
|
|
+ "c|" * (nbre_saes)
|
|
+ "c|" * (nbre_ressources)
|
|
+ "}"
|
|
+ "\n"
|
|
)
|
|
chaine += "\\hline \n" # % (nbre_saes + nbre_ressources+1)+ "\n"
|
|
# l'entete
|
|
chaine += " & & "
|
|
chaine += (
|
|
"\multicolumn{%d}{c|}{\\textcolor{saeC}{\\bfseries SAÉs}}" % (nbre_saes) + "\n"
|
|
)
|
|
chaine += " & "
|
|
chaine += (
|
|
"\multicolumn{%d}{c|}{\\textcolor{ressourceC}{\\bfseries Ressources}}"
|
|
% (nbre_ressources)
|
|
+ "\\\\ \n"
|
|
)
|
|
chaine += "\\cline{3-%d}" % (nbre_colonnes)
|
|
chaine += " & & "
|
|
# les noms des SAE et des ressources
|
|
noms_saes = []
|
|
for (i, s) in enumerate(saesem): # pour chaque SAE
|
|
# saecode = "Scode" + lettresem + string.ascii_uppercase[i]
|
|
# contenu = "\\xdef\saecode{\csname " + saecode + "\endcsname}"
|
|
# contenu += "\\tiny{\\hyperlink{sae:\\saecode}{" + s.sae["titre"] + "~}}"
|
|
contenu = "\\tiny{" + s.sae["titre"] + "~}"
|
|
noms_saes.append(rotation_entete_colonne(contenu) + "\n")
|
|
chaine += " & ".join(noms_saes) + "\n"
|
|
chaine += " & "
|
|
noms_ressources = []
|
|
for (i, r) in enumerate(ressem): # pour chaque SAE
|
|
# contenu = r.ressource["code"] + " | " + r.ressource["nom"]
|
|
# noms_ressources.append(rotation_entete_colonne(contenu) + "\n")
|
|
contenu = "\\tiny{" + r.ressource["nom"] + "~}"
|
|
noms_ressources.append(rotation_entete_colonne(contenu) + "\n")
|
|
chaine += " & ".join(noms_ressources) + "\n"
|
|
chaine += "\\\\ \n"
|
|
|
|
# les codes des SAE et des ressources
|
|
noms_saes = []
|
|
chaine += " & & \n"
|
|
for (i, s) in enumerate(saesem): # pour chaque SAE
|
|
contenu = "~\\hyperlink{sae:" + s.sae["code"] + "}{"
|
|
contenu += "\\textcolor{saeC}{" + s.sae["code"] + "}"
|
|
contenu += "}"
|
|
noms_saes.append(rotation_entete_colonne(contenu, pos="r") + "\n")
|
|
chaine += " & ".join(noms_saes) + "\n"
|
|
chaine += " & "
|
|
noms_ressources = []
|
|
for (i, r) in enumerate(ressem): # pour chaque SAE
|
|
contenu = "~\\hyperlink{res:" + r.ressource["code"] + "}{"
|
|
contenu += "\\textcolor{ressourceC}{" + r.ressource["code"] + "}"
|
|
contenu += "}"
|
|
noms_ressources.append(rotation_entete_colonne(contenu, pos="r") + "\n")
|
|
chaine += " & ".join(noms_ressources) + "\n"
|
|
chaine += "\\\\ \n"
|
|
chaine += "\\hline \n"
|
|
|
|
# Les ACS et les croix
|
|
for (noc, comp) in enumerate(DATA_ACS):
|
|
nom_comp = DATA_COMPETENCES[comp]["nom"]
|
|
niveau = list(DATA_COMPETENCES[comp]["niveaux"].keys())[0]
|
|
couleur = "\\textcolor{compC" + string.ascii_uppercase[noc] + "}"
|
|
chaine += (
|
|
"\\multicolumn{%d}{|l|}{\hyperlink{comp:%s}{%s{\\bfseries %s - %s }}} \\\\"
|
|
% (nbre_colonnes, comp, couleur, comp, nom_comp.replace("&", "\&"))
|
|
)
|
|
chaine += "\\multicolumn{%d}{|l|}{\small Niveau 1 - %s} \\\\" % (
|
|
nbre_colonnes,
|
|
niveau.replace("&", "\&"),
|
|
)
|
|
chaine += "\\hline \n"
|
|
for (k, ac) in enumerate(DATA_ACS[comp]):
|
|
chaine += couleur + "{" + ac + "}" + " & " + "\n"
|
|
chaine += "\\begin{tabular}{p{%scm}} " % (str(longueur - 0.2))
|
|
chaine += "\\tiny{" + DATA_ACS[comp][ac] + "}"
|
|
chaine += "\\end{tabular} & \n"
|
|
|
|
croix = []
|
|
indice_ac = les_codes_acs.index(ac)
|
|
for (i, s) in enumerate(saesem): # pour chaque SAE
|
|
croix.append("$\\times$" if matrice[indice_ac][i] == True else "")
|
|
chaine += " & ".join(croix) + "\n"
|
|
chaine += " & "
|
|
croix = []
|
|
for (j, r) in enumerate(ressem): # pour chaque SAE
|
|
croix.append(
|
|
"$\\times$" if matrice[indice_ac][nbre_saes + j] == True else ""
|
|
)
|
|
chaine += " & ".join(croix) + "\\\\ \n"
|
|
# if k < len(DATA_ACS[comp]) -1:
|
|
# chaine += "\\cline{2-%d}" % (nbre_saes+ nbre_ressources+3)
|
|
chaine += "\\hline \n"
|
|
chaine += "\\hline \n"
|
|
|
|
chaine += "\\end{tabular}"
|
|
return chaine
|
|
|
|
|
|
def to_latex_matrice_coeffs(matrice_vols, matrice_coeffs, saes, ressources, sem):
|
|
"""Renvoie le tableau latex affichant la matrice"""
|
|
|
|
def str_coeff(val):
|
|
if val == None:
|
|
return ""
|
|
else:
|
|
return str(val)
|
|
|
|
def str_volume(val):
|
|
if val:
|
|
return str(val) + "h"
|
|
else:
|
|
return " "
|
|
|
|
comps = ["RT1", "RT2", "RT3"]
|
|
lettresem = "A" if sem == "S1" else "B"
|
|
sem_id = int(sem[1:])
|
|
saesem = saes[sem] # les saé du semestre
|
|
ressem = ressources[sem] # les ressources du semestre
|
|
|
|
nbre_saes = len(saesem)
|
|
nbre_colonnes = len(comps) + 2
|
|
|
|
chaine = (
|
|
"\\begin{tabular}[c]{|rp{6cm}|"
|
|
+ "c|" * 2
|
|
+ "c|"
|
|
+ "c|" * (len(comps))
|
|
+ "}"
|
|
+ "\n"
|
|
)
|
|
chaine += "\\hline \n" # % (nbre_saes + nbre_ressources+1)+ "\n"
|
|
# le début
|
|
chaine += " & & " + "\\multicolumn{3}{c|}{\\bfseries Volumes} \n"
|
|
chaine += " & " + "\\multicolumn{3}{c|}{\\bfseries Coefficients} \n"
|
|
chaine += " \\\\ \\hline \n"
|
|
# l'entete
|
|
chaine += " & & "
|
|
# Volume
|
|
chaine += rotation_entete_colonne("\\bfseries Heures de formation encadrée") + " & "
|
|
chaine += rotation_entete_colonne("\\bfseries Heures de TPs") + " & "
|
|
chaine += rotation_entete_colonne("\\bfseries Heures de projets") + " & "
|
|
# les noms des comps
|
|
noms = []
|
|
for (i, comp) in enumerate(comps): # pour chaque compétence
|
|
contenu = "\\begin{tabular}{p{5cm}}\n"
|
|
couleur = "\\textcolor{compC" + string.ascii_uppercase[i] + "}"
|
|
contenu += (
|
|
"\\hyperlink{comp:" + comp + "}{"
|
|
+ couleur
|
|
+ "{\\bfseries "
|
|
+ comp
|
|
+ "}} - "
|
|
+ DATA_COMPETENCES[comp]["nom"].replace("&", "\&")
|
|
+ "\\\\ \n"
|
|
)
|
|
niveau = list(DATA_COMPETENCES[comp]["niveaux"].keys())[0]
|
|
contenu += " \\small Niveau 1 - " + niveau.replace("&", "\&") + "\n"
|
|
contenu += "\\end{tabular}\n"
|
|
noms.append(rotation_entete_colonne(contenu) + "\n")
|
|
chaine += " & ".join(noms) + "\n"
|
|
chaine += "\\\\ \n"
|
|
|
|
chaine += "\\hline"
|
|
chaine += "\\hline"
|
|
|
|
chaine += (
|
|
"\multicolumn{%d}{|l}{\\textcolor{saeC}{\\bfseries SAÉs}}" % (nbre_colonnes)
|
|
+ "\n"
|
|
)
|
|
chaine += "\\\\ \n"
|
|
chaine += "\\hline "
|
|
# le nom des SAE
|
|
for (i, s) in enumerate(saesem): # pour chaque SAE
|
|
chaine += "\\hyperlink{sae:" + s.sae["code"] + "}{"
|
|
chaine += "\\textcolor{saeC}{" + s.sae["code"] + "}"
|
|
chaine += "}"
|
|
chaine += " & " + "\n"
|
|
chaine += (
|
|
"\\begin{tabular}{p{5.7cm}} \\tiny{"
|
|
+ s.sae["titre"]
|
|
+ "} \\end{tabular} & \n"
|
|
)
|
|
chaine += str_volume(matrice_vols[i][0]) + " & "
|
|
chaine += str_volume(matrice_vols[i][1]) + " & "
|
|
chaine += str_volume(matrice_vols[i][2]) + " & "
|
|
chaine += " & ".join(
|
|
[str_coeff(matrice_coeffs[i][j]) for j in range(len(comp))]
|
|
)
|
|
chaine += "\\\\ \n"
|
|
chaine += "\\hline "
|
|
# Les ressources et les coeff
|
|
chaine += (
|
|
"\multicolumn{%d}{|l}{\\textcolor{ressourceC}{\\bfseries Ressources}}"
|
|
% (nbre_colonnes)
|
|
+ "\n"
|
|
)
|
|
chaine += "\\\\ \n"
|
|
chaine += "\\hline "
|
|
|
|
for (i, r) in enumerate(ressem): # pour chaque SAE
|
|
chaine += "\hyperlink{res:" + r.ressource["code"] + "}{"
|
|
chaine += "\\textcolor{ressourceC}{" + r.ressource["code"] + "}"
|
|
chaine += "}"
|
|
chaine += " & " + "\n"
|
|
|
|
chaine += "\\begin{tabular}{p{5.7cm}}"
|
|
chaine += "\\tiny{" + r.ressource["nom"] + "}"
|
|
chaine += " \\end{tabular} & \n"
|
|
chaine += str_volume(matrice_vols[i + nbre_saes][0]) + " & "
|
|
chaine += str_volume(matrice_vols[i + nbre_saes][1]) + " & "
|
|
chaine += " & "
|
|
chaine += " & ".join(
|
|
[str_coeff(matrice_coeffs[i + nbre_saes][j]) for j in range(len(comp))]
|
|
)
|
|
chaine += "\\\\ \n"
|
|
chaine += "\\hline "
|
|
|
|
# Total
|
|
total_heures = get_total_nbre_heures(matrice_vols)
|
|
total_heures_sae = get_total_nbre_heures_saes(matrice_vols, sem)
|
|
total_heures_ressources = get_total_nbre_heures_ressources(matrice_vols, sem)
|
|
total_coeffs = get_total_coeffs(matrice_coeffs)
|
|
total_coeffs_sae = get_total_coeffs_saes(matrice_coeffs, sem)
|
|
total_coeffs_ressources = get_total_coeffs_ressources(matrice_coeffs, sem)
|
|
|
|
chaine += "\\hline "
|
|
chaine += "\multicolumn{%d}{|l|}{\\bfseries Total}" % (nbre_colonnes) + "\n"
|
|
chaine += "\\\\ \n"
|
|
chaine += "\\hline "
|
|
# sous-total SAE
|
|
chaine += "\multicolumn{2}{|r|}{\\textit{SAÉs}} "
|
|
for i in range(3):
|
|
chaine += " & \\textit{" + str(total_heures_sae[i]) + "h}"
|
|
for i in range(3):
|
|
chaine += " & \\textit{" + str(total_coeffs_sae[i]) + "}"
|
|
chaine += "\\\\ \hline "
|
|
chaine += "\multicolumn{2}{|r|}{\\textit{Ressources}} "
|
|
for i in range(3):
|
|
chaine += " & \\textit{" + str(total_heures_ressources[i]) + "h}"
|
|
for i in range(3):
|
|
chaine += " & \\textit{" + str(total_coeffs_ressources[i]) + "}"
|
|
chaine += "\\\\ \hline "
|
|
chaine += "\multicolumn{2}{|r|}{\\bfseries SAÉs + Ressources}"
|
|
for i in range(3):
|
|
chaine += " & {\\bfseries " + str(total_heures[i]) + "h}"
|
|
for i in range(3):
|
|
chaine += " & {\\bfseries " + str(total_coeffs[i]) + "}"
|
|
chaine += "\\\\ \\hline"
|
|
|
|
# ECTS
|
|
chaine += r"""\multicolumn{5}{l}{~}\\
|
|
\multicolumn{5}{l}{\bfseries Crédits ECTS}\\
|
|
\hline
|
|
\multicolumn{5}{|l|}{} & RT1 & RT2 & \multicolumn{1}{c|}{RT3} \\
|
|
\hline
|
|
\multicolumn{5}{|l|}{} & %d & %d & %d \\
|
|
\hline
|
|
""" % tuple(Config.ECTS[sem_id][ue] for ue in Config.ECTS[sem_id])
|
|
chaine += "\\end{tabular}"
|
|
return chaine
|
|
|
|
|
|
def get_total_nbre_heures(matrice_heures):
|
|
"""Calcul le nombre d'heures total des SAé d'après la matrice"""
|
|
sommes = [
|
|
sum(
|
|
[
|
|
matrice_heures[i][j]
|
|
for i in range(len(matrice_heures))
|
|
if matrice_heures[i][j]
|
|
]
|
|
)
|
|
for j in range(3)
|
|
]
|
|
return sommes
|
|
|
|
|
|
def get_total_nbre_heures_saes(matrice_heures, sem):
|
|
"""Calcul le nombre d'heures total des SAé d'après la matrice"""
|
|
nbre_sae = len(DATA_SAES[sem])
|
|
sommes = [
|
|
sum([matrice_heures[i][j] for i in range(nbre_sae) if matrice_heures[i][j]])
|
|
for j in range(3)
|
|
]
|
|
return sommes
|
|
|
|
|
|
def get_total_nbre_heures_ressources(matrice_heures, sem):
|
|
"""Calcul le nombre d'heures total des SAé d'après la matrice"""
|
|
nbre_sae = len(DATA_SAES[sem])
|
|
sommes = [
|
|
sum(
|
|
[
|
|
matrice_heures[i][j]
|
|
for i in range(nbre_sae, len(matrice_heures))
|
|
if matrice_heures[i][j]
|
|
]
|
|
)
|
|
for j in range(3)
|
|
]
|
|
return sommes
|
|
|
|
|
|
def get_total_coeffs(matrice_coeffs):
|
|
sommes = [
|
|
sum(
|
|
[
|
|
matrice_coeffs[i][j]
|
|
for i in range(len(matrice_coeffs))
|
|
if matrice_coeffs[i][j]
|
|
]
|
|
)
|
|
for j in range(3)
|
|
]
|
|
return sommes
|
|
|
|
|
|
def get_total_coeffs_saes(matrice_coeffs, sem):
|
|
nbre_sae = len(DATA_SAES[sem])
|
|
sommes = [
|
|
sum([matrice_coeffs[i][j] for i in range(nbre_sae) if matrice_coeffs[i][j]])
|
|
for j in range(3)
|
|
]
|
|
return sommes
|
|
|
|
|
|
def get_total_coeffs_ressources(matrice_coeffs, sem):
|
|
nbre_sae = len(DATA_SAES[sem])
|
|
sommes = [
|
|
sum(
|
|
[
|
|
matrice_coeffs[i][j]
|
|
for i in range(nbre_sae, len(matrice_coeffs))
|
|
if matrice_coeffs[i][j]
|
|
]
|
|
)
|
|
for j in range(3)
|
|
]
|
|
return sommes
|
|
|
|
|
|
def str_latex_abbreviations():
|
|
"""Renvoie le code latex d'un tableau pour les abbréviations"""
|
|
liste = [
|
|
[cle, DATA_ABBREVIATIONS[lettre][cle]]
|
|
for lettre in DATA_ABBREVIATIONS
|
|
for cle in DATA_ABBREVIATIONS[lettre]
|
|
]
|
|
nbre_abbreviations = len(liste)
|
|
chaine = ""
|
|
for i in range(nbre_abbreviations):
|
|
chaine += "\\begin{tabular}{rp{6.5cm}} \n"
|
|
chaine += (
|
|
"\makebox[1.5cm][r]{\\textabbrv{"
|
|
+ liste[i][0]
|
|
+ "}} & "
|
|
+ liste[i][1]
|
|
+ "\\\\ \n"
|
|
)
|
|
chaine += "\\end{tabular}\n\n"
|
|
return chaine |