forked from viennet/Referentiels
débute le traitement des saé
This commit is contained in:
parent
2bb604b77a
commit
bb4bd79b6d
@ -63,7 +63,9 @@ Aucun
|
|||||||
% {\bfseries Ancrage et contexte professionnel :} \\
|
% {\bfseries Ancrage et contexte professionnel :} \\
|
||||||
\csname ressourceancrage\CODE\endcsname \\
|
\csname ressourceancrage\CODE\endcsname \\
|
||||||
{\bfseries Contenus :} \\
|
{\bfseries Contenus :} \\
|
||||||
|
%{\setlength{\extrarowheight}{1pt}
|
||||||
\csname ressourcecontenudetaille\CODE\endcsname
|
\csname ressourcecontenudetaille\CODE\endcsname
|
||||||
|
%}
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,9 @@ import docx2python
|
|||||||
from ressourcedocx import *
|
from ressourcedocx import *
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from tools import get_indice, get_indice_sans_accent_ni_espace
|
||||||
|
|
||||||
__LOGGER = logging.getLogger(__name__)
|
__LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
REPERTOIRE = "import"
|
REPERTOIRE = "import"
|
||||||
@ -19,22 +22,6 @@ nbre_ressources = 0
|
|||||||
|
|
||||||
ENTETES = ["Nom", "Code", "Semestre", "Heures de formation", "dont heures de TP",
|
ENTETES = ["Nom", "Code", "Semestre", "Heures de formation", "dont heures de TP",
|
||||||
"SAÉ", "Prérequis", "Descriptif", "Mots"]
|
"SAÉ", "Prérequis", "Descriptif", "Mots"]
|
||||||
def get_indice(champ):
|
|
||||||
"""Récupère l'indice d'une entête"""
|
|
||||||
for (i, entete) in enumerate(ENTETES):
|
|
||||||
if entete in champ:
|
|
||||||
return i
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_indice_sans_accent_ni_espace(champ):
|
|
||||||
"""Récupère l'indice d'une entête en se débarrassant des majuscules/caractères spéciaux/espace"""
|
|
||||||
champ_purge = supprime_accent_espace(champ)
|
|
||||||
for (i, entete) in enumerate(ENTETES):
|
|
||||||
entete_purge = supprime_accent_espace(entete)
|
|
||||||
if entete_purge in champ_purge:
|
|
||||||
return i
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Format du parsing issu de docx2python
|
Format du parsing issu de docx2python
|
||||||
@ -75,7 +62,7 @@ for i in range(2, len(docu)): # A priori un tableau
|
|||||||
ligne = res[j]
|
ligne = res[j]
|
||||||
if len(ligne) == 2: # ligne de données classique champ => valeur
|
if len(ligne) == 2: # ligne de données classique champ => valeur
|
||||||
champ = ligne[0][0] # le nom du champ
|
champ = ligne[0][0] # le nom du champ
|
||||||
i = get_indice_sans_accent_ni_espace(champ) # l'indice de l'entete dans ENTETES
|
i = get_indice_sans_accent_ni_espace(champ, ENTETES) # l'indice de l'entete dans ENTETES
|
||||||
if i != None:
|
if i != None:
|
||||||
data[i] = "\n".join(res[j][1])
|
data[i] = "\n".join(res[j][1])
|
||||||
if champ == "Prérequis" and not data[i]:
|
if champ == "Prérequis" and not data[i]:
|
||||||
@ -99,7 +86,7 @@ for i in range(2, len(docu)): # A priori un tableau
|
|||||||
indice_champ = -1
|
indice_champ = -1
|
||||||
if indice_champ >= 0: # si le champ "Heures de formation (incluant les TP)" est trouvé
|
if indice_champ >= 0: # si le champ "Heures de formation (incluant les TP)" est trouvé
|
||||||
# tente de réinjecter les heures dans Heures encadrées si elles n'on pas déjà été renseignées
|
# tente de réinjecter les heures dans Heures encadrées si elles n'on pas déjà été renseignées
|
||||||
indice_heure = get_indice("formation encadrée")
|
indice_heure = get_indice("formation encadrée", ENTETES)
|
||||||
if not data[indice_heure]:
|
if not data[indice_heure]:
|
||||||
print(f"Dans \"{nom_ressource}\", réinjection de \"Heures de formation (incluant les TP)\" dans \"formation encadrée\"")
|
print(f"Dans \"{nom_ressource}\", réinjection de \"Heures de formation (incluant les TP)\" dans \"formation encadrée\"")
|
||||||
data[indice_heure] = champ[1]
|
data[indice_heure] = champ[1]
|
||||||
@ -131,8 +118,8 @@ ressources = {"S1" : [], "S2": []}
|
|||||||
|
|
||||||
for r in liste_ressources:
|
for r in liste_ressources:
|
||||||
nettoie_titre(r)
|
nettoie_titre(r)
|
||||||
nettoie_heure(r)
|
nettoie_heure_ressource(r)
|
||||||
nettoie_code(r)
|
nettoie_code(r, type="ressource")
|
||||||
nettoie_semestre(r)
|
nettoie_semestre(r)
|
||||||
nettoie_acs(r)
|
nettoie_acs(r)
|
||||||
nettoie_sae(r)
|
nettoie_sae(r)
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
|
|
||||||
import docx2python
|
import docx2python
|
||||||
from ressource import *
|
from ressourcedocx import *
|
||||||
|
from tools import *
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
__LOGGER = logging.getLogger(__name__)
|
__LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
REPERTOIRE = "import"
|
REPERTOIRE = "import"
|
||||||
DOCUMENT = "000 compilation-saes 2021-03-29T11_10_11.377Z"
|
DOCUMENT = "sae_v0"
|
||||||
|
|
||||||
# Ouverture du document
|
# Ouverture du document
|
||||||
docu = docx2python.docx2python(REPERTOIRE + "/" + DOCUMENT + ".docx")
|
docu = docx2python.docx2python(REPERTOIRE + "/" + DOCUMENT + ".docx")
|
||||||
@ -14,29 +15,16 @@ docu = docx2python.docx2python(REPERTOIRE + "/" + DOCUMENT + ".docx")
|
|||||||
docu = docu.body
|
docu = docu.body
|
||||||
docu[0] # Titre général
|
docu[0] # Titre général
|
||||||
docu[1] # Tableau de synthèse des ressources
|
docu[1] # Tableau de synthèse des ressources
|
||||||
nbre_ressources = 0
|
|
||||||
|
|
||||||
|
|
||||||
ENTETES_CHAPEAU = ["Titre", "Code", "Semestre", "Heures de formation", "dont heures de TP", "Heures \"projet",
|
|
||||||
"Description des objectifs",
|
ENTETES_CHAPEAU = ["Titre", "Code", "Semestre", "Heures de formation",
|
||||||
|
"dont heures de TP",
|
||||||
|
"Heures \"projet",
|
||||||
|
"Description",
|
||||||
"Liste des ressources", "Type de livrable", "Mots clefs"]
|
"Liste des ressources", "Type de livrable", "Mots clefs"]
|
||||||
ENTETES_EXEMPLES = ["Titre", "Compétence", "Description des objectifs", "Types"]
|
ENTETES_EXEMPLES = ["Titre", "Description", "Formes", "Quelle problématique",
|
||||||
def get_indice(champ):
|
"Modalités"]
|
||||||
"""Récupère l'indice d'une entête"""
|
|
||||||
for (i, entete) in enumerate(ENTETES):
|
|
||||||
if entete in champ:
|
|
||||||
return i
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_indice_sans_accent_ni_espace(champ):
|
|
||||||
"""Récupère l'indice d'une entête en se débarrassant des majuscules/caractères spéciaux/espace"""
|
|
||||||
champ_purge = supprime_accent_espace(champ)
|
|
||||||
for (i, entete) in enumerate(ENTETES):
|
|
||||||
entete_purge = supprime_accent_espace(entete)
|
|
||||||
if entete_purge in champ_purge:
|
|
||||||
return i
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Format du parsing issu de docx2python
|
Format du parsing issu de docx2python
|
||||||
@ -46,30 +34,35 @@ Format du parsing issu de docx2python
|
|||||||
[ # table A cell 1 <-- structure des tableaux
|
[ # table A cell 1 <-- structure des tableaux
|
||||||
"""
|
"""
|
||||||
|
|
||||||
liste_ressources = [] # la liste des ressources telle qu'extrait du docx
|
|
||||||
print("*Etape 1* : Parsing")
|
|
||||||
|
|
||||||
for i in range(2, len(docu)): # A priori un tableau
|
print("*Etape 1* : Parsing")
|
||||||
est_ressource = False
|
nbre_saes = 0
|
||||||
|
last_sae = None
|
||||||
|
liste_saes = [] # la liste des saes telle qu'extraite du docx
|
||||||
|
liste_exemples = {} # la liste des exemples de chaque SAé
|
||||||
|
|
||||||
|
for i in range(1, len(docu)): # A priori un tableau
|
||||||
|
est_sae, est_exemple = False, False
|
||||||
try:
|
try:
|
||||||
if "Nom de la ressource" in docu[i][0][0][0]: # [03][00][0][0]
|
if "Titre de la " in docu[i][0][0][0] or "Nom de la " in docu[i][0][0][0]: # [03][00][0][0]
|
||||||
est_ressource = True
|
if "Code" in docu[i][1][0][0]:
|
||||||
nbre_ressources += 1
|
est_sae = True
|
||||||
|
nbre_saes += 1
|
||||||
|
else: # c'est un exemple
|
||||||
|
est_exemple = True
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if est_ressource == True:
|
if est_sae == True:
|
||||||
res = docu[i] # la ressource
|
res = docu[i] # la ressource
|
||||||
nom_ressource = res[0][1][0]
|
nom_sae = res[0][1][0]
|
||||||
|
|
||||||
# Création de la ressource
|
# Création de la ressource
|
||||||
r = RessourceDocx(nom_ressource, res)
|
r = SAEDocx(nom_sae, res)
|
||||||
liste_ressources.append(r)
|
liste_saes.append(r)
|
||||||
|
|
||||||
# if len(res) != 15:
|
# Parsing des données brute de la sae
|
||||||
# __LOGGER.warning(f"Champs en trop ou manquants dans \"{nom_ressource}\"")
|
data = [None for i in range(len(ENTETES_CHAPEAU))] # les données attendues Nom, Code, ..., Mots clés
|
||||||
# Parsing des données brute de la ressource
|
|
||||||
data = [None for i in range(len(ENTETES))] # les données attendues Nom, Code, ..., Mots clés
|
|
||||||
apprentissages = [None for i in range(3)] # les apprentissages des 3 compétences
|
apprentissages = [None for i in range(3)] # les apprentissages des 3 compétences
|
||||||
|
|
||||||
non_interprete = []
|
non_interprete = []
|
||||||
@ -77,17 +70,17 @@ for i in range(2, len(docu)): # A priori un tableau
|
|||||||
ligne = res[j]
|
ligne = res[j]
|
||||||
if len(ligne) == 2: # ligne de données classique champ => valeur
|
if len(ligne) == 2: # ligne de données classique champ => valeur
|
||||||
champ = ligne[0][0] # le nom du champ
|
champ = ligne[0][0] # le nom du champ
|
||||||
i = get_indice_sans_accent_ni_espace(champ) # l'indice de l'entete dans ENTETES
|
if champ.startswith("Nom de la"):
|
||||||
|
champ = "Titre de la" # corrige les noms/titres
|
||||||
|
i = get_indice_sans_accent_ni_espace(champ, ENTETES_CHAPEAU) # l'indice de l'entete dans ENTETES
|
||||||
if i != None:
|
if i != None:
|
||||||
data[i] = "\n".join(res[j][1])
|
data[i] = "\n".join(res[j][1])
|
||||||
if champ == "Prérequis" and not data[i]:
|
|
||||||
data[i] = "aucun"
|
|
||||||
print(f"Dans {nom_ressource}, complète les prérequis à \"aucun\"")
|
|
||||||
else:
|
else:
|
||||||
non_interprete.append((champ, ligne[1][0]))
|
non_interprete.append((champ, ligne[1][0]))
|
||||||
else: # ligne de données soit chapeau (ex Compétences ciblées) soit détail par compétence
|
else: # ligne de données soit chapeau (ex Compétences ciblées) soit détail par compétence
|
||||||
champ = ligne[0][0]
|
champ = ligne[0][0]
|
||||||
if "Apprentissages" in champ: # les compétences ciblées sont déduites de la présence d'apprentissage critiques
|
|
||||||
|
if "Apprentissage(s)" in champ: # les compétences ciblées sont déduites de la présence d'apprentissage critiques
|
||||||
# j+1 = les ACs par compétences
|
# j+1 = les ACs par compétences
|
||||||
acs = res[j+2]
|
acs = res[j+2]
|
||||||
for k in range(len(acs)):
|
for k in range(len(acs)):
|
||||||
@ -95,105 +88,132 @@ for i in range(2, len(docu)): # A priori un tableau
|
|||||||
|
|
||||||
if non_interprete: # souvent Heures de formation (incluant les TP)
|
if non_interprete: # souvent Heures de formation (incluant les TP)
|
||||||
|
|
||||||
try:
|
__LOGGER.warning(f"Dans la saé \"{nom_sae}\", champs en trop non interprétés : " + ",".join(
|
||||||
indice_champ = [chp[0] for chp in non_interprete].index("Heures de formation (incluant les TP)")
|
|
||||||
except:
|
|
||||||
indice_champ = -1
|
|
||||||
if indice_champ >= 0: # si le champ "Heures de formation (incluant les TP)" est trouvé
|
|
||||||
# tente de réinjecter les heures dans Heures encadrées si elles n'on pas déjà été renseignées
|
|
||||||
indice_heure = get_indice("formation encadrée")
|
|
||||||
if not data[indice_heure]:
|
|
||||||
print(f"Dans \"{nom_ressource}\", réinjection de \"Heures de formation (incluant les TP)\" dans \"formation encadrée\"")
|
|
||||||
data[indice_heure] = champ[1]
|
|
||||||
non_interprete = non_interprete[:indice_champ] + non_interprete[indice_champ+1:] # supprime le champ
|
|
||||||
|
|
||||||
if non_interprete:
|
|
||||||
__LOGGER.warning(f"Dans \"{nom_ressource}\", champs en trop non interprétés : " + ",".join(
|
|
||||||
[chp[0] for chp in non_interprete]))
|
[chp[0] for chp in non_interprete]))
|
||||||
|
|
||||||
# Analyse des champs manquants
|
# Analyse des champs manquants
|
||||||
champ_manquants = []
|
champ_manquants = []
|
||||||
for (j, champ) in enumerate(ENTETES):
|
for (j, champ) in enumerate(ENTETES_CHAPEAU):
|
||||||
if not data[j]:
|
if not data[j]:
|
||||||
champ_manquants += [champ]
|
champ_manquants += [champ]
|
||||||
if champ_manquants:
|
if champ_manquants:
|
||||||
__LOGGER.warning(f"Dans \"{nom_ressource}\", champs manquants : " + ",".join(champ_manquants))
|
__LOGGER.warning(f"Dans \"{nom_sae}\", champs manquants : " + ",".join(champ_manquants))
|
||||||
|
|
||||||
# Sauvegarde des champs de la ressource
|
# Sauvegarde des champs de la ressource
|
||||||
info = tuple(data[1:])
|
info = tuple(data[1:])
|
||||||
r.charge_informations(*info)
|
r.charge_informations(*info)
|
||||||
r.charge_ac(apprentissages)
|
r.charge_ac(apprentissages)
|
||||||
|
|
||||||
|
# nettoie le titre et le code
|
||||||
|
nettoie_titre(r)
|
||||||
|
nettoie_code(r, type="sae")
|
||||||
|
|
||||||
|
last_sae = r.code
|
||||||
|
liste_exemples[r.code] = []
|
||||||
|
|
||||||
|
elif est_exemple == True:
|
||||||
|
res = docu[i] # la ressource
|
||||||
|
nom_exemple = res[0][1][0]
|
||||||
|
|
||||||
|
# Création de la ressource
|
||||||
|
r = ExempleSAEDocx(nom_exemple, res)
|
||||||
|
liste_exemples[last_sae].append(r)
|
||||||
|
|
||||||
|
# Parsing des données brute de la sae
|
||||||
|
data = [None for i in range(len(ENTETES_EXEMPLES))] # les données attendues Nom, Code, ..., Mots clés
|
||||||
|
apprentissages = [None for i in range(3)] # les apprentissages des 3 compétences
|
||||||
|
|
||||||
|
non_interprete = []
|
||||||
|
for j in range(len(res)): # parcours des entêtes du tableau décrivant la ressource
|
||||||
|
ligne = res[j]
|
||||||
|
if len(ligne) == 2: # ligne de données classique champ => valeur
|
||||||
|
champ = ligne[0][0] # le nom du champ
|
||||||
|
i = get_indice_sans_accent_ni_espace(champ, ENTETES_EXEMPLES) # l'indice de l'entete dans ENTETES
|
||||||
|
if i != None:
|
||||||
|
data[i] = "\n".join(res[j][1])
|
||||||
|
else:
|
||||||
|
non_interprete.append((champ, ligne[1][0]))
|
||||||
|
else: # ligne de données soit chapeau (ex Compétences ciblées) soit détail par compétence
|
||||||
|
print("??? plus de 2 colonnes ?")
|
||||||
|
|
||||||
|
if non_interprete: # souvent Heures de formation (incluant les TP)
|
||||||
|
|
||||||
|
__LOGGER.warning(f"Dans l'exemple \"{nom_exemple}\", champs en trop non interprétés : " + ",".join(
|
||||||
|
[chp[0] for chp in non_interprete]))
|
||||||
|
|
||||||
|
# Analyse des champs manquants
|
||||||
|
champ_manquants = []
|
||||||
|
for (j, champ) in enumerate(ENTETES_EXEMPLES):
|
||||||
|
if not data[j]:
|
||||||
|
champ_manquants += [champ]
|
||||||
|
if champ_manquants:
|
||||||
|
__LOGGER.warning(f"Dans \"{nom_exemple}\", champs manquants : " + ",".join(champ_manquants))
|
||||||
|
|
||||||
|
# Sauvegarde des champs de la ressource
|
||||||
|
info = tuple(data[1:])
|
||||||
|
r.charge_informations(*info)
|
||||||
|
|
||||||
# fin du parsing
|
# fin du parsing
|
||||||
print(f"{nbre_ressources} ressources")
|
print(f"{nbre_saes} saes")
|
||||||
|
for s in liste_exemples:
|
||||||
|
print(f"{s} :" + str(len(liste_exemples[s])) + " exemples")
|
||||||
|
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
|
|
||||||
# Post traitement des ressources => gestion des heures/des acs/ + tri par semestre
|
# Post traitement des saes => gestion des heures/des acs/ + tri par semestre
|
||||||
ressources = {"S1" : [], "S2": []}
|
saes = {"S1" : [], "S2": []}
|
||||||
|
|
||||||
for r in liste_ressources:
|
|
||||||
# Nettoie titre
|
|
||||||
nettoie_titre(r)
|
|
||||||
|
|
||||||
# Nettoie le champ heures_encadrees
|
|
||||||
nettoie_heure(r)
|
|
||||||
|
|
||||||
# Nettoie les codes
|
|
||||||
nettoie_code(r)
|
|
||||||
|
|
||||||
# Nettoie les semestres
|
|
||||||
nettoie_semestre(r)
|
|
||||||
|
|
||||||
# Remet en forme les ACs
|
|
||||||
nettoie_acs(r)
|
|
||||||
|
|
||||||
# Remet en forme les saé
|
|
||||||
nettoie_sae(r)
|
|
||||||
|
|
||||||
# Remet en forme les pré-requis
|
|
||||||
nettoie_prerequis(r)
|
|
||||||
|
|
||||||
# Remet en forme le descriptif
|
|
||||||
split_description(r)
|
|
||||||
nettoie_contenus(r)
|
|
||||||
|
|
||||||
# Remet en forme les mots-clés
|
|
||||||
# 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
|
|
||||||
# Le tableau des heures ressources
|
|
||||||
for sem in ressources: # parcours des semestres
|
|
||||||
# print(f"Semestre {sem}")
|
|
||||||
chaine = affiche_bilan_heures(ressources, sem)
|
|
||||||
|
|
||||||
|
|
||||||
# Matrice ACS/ressources
|
|
||||||
matrices = {}
|
|
||||||
les_codes_acs = [code for comp in DATA_ACS for code in DATA_ACS[comp]]
|
|
||||||
nbre_acs = len(les_codes_acs)
|
|
||||||
|
|
||||||
for sem in ressources:
|
|
||||||
# print("Matrice du semestre " + sem)
|
|
||||||
(matrices[sem], chaine) = get_matrices_ac_ressource(ressources, sem)
|
|
||||||
|
|
||||||
# Export yaml
|
|
||||||
WITH_EXPORT = True
|
|
||||||
for sem in ressources:
|
|
||||||
for r in ressources[sem]:
|
|
||||||
output = r.to_yaml()
|
|
||||||
if WITH_EXPORT and r.code:
|
|
||||||
fichier = "export/{}.yml".format(r.code)
|
|
||||||
with open(fichier, "w", encoding="utf8") as fid:
|
|
||||||
fid.write(output)
|
|
||||||
|
|
||||||
|
for s in liste_saes:
|
||||||
|
nettoie_heure_sae(s)
|
||||||
|
nettoie_semestre(s)
|
||||||
|
nettoie_acs(s)
|
||||||
|
nettoie_ressources(s)
|
||||||
|
print("ici")
|
||||||
|
#
|
||||||
|
# # Remet en forme les pré-requis
|
||||||
|
# nettoie_prerequis(r)
|
||||||
|
#
|
||||||
|
# # Remet en forme le descriptif
|
||||||
|
# split_description(r)
|
||||||
|
# nettoie_contenus(r)
|
||||||
|
#
|
||||||
|
# # Remet en forme les mots-clés
|
||||||
|
# # 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
|
||||||
|
# # Le tableau des heures ressources
|
||||||
|
# for sem in ressources: # parcours des semestres
|
||||||
|
# # print(f"Semestre {sem}")
|
||||||
|
# chaine = affiche_bilan_heures(ressources, sem)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# # Matrice ACS/ressources
|
||||||
|
# matrices = {}
|
||||||
|
# les_codes_acs = [code for comp in DATA_ACS for code in DATA_ACS[comp]]
|
||||||
|
# nbre_acs = len(les_codes_acs)
|
||||||
|
#
|
||||||
|
# for sem in ressources:
|
||||||
|
# # print("Matrice du semestre " + sem)
|
||||||
|
# (matrices[sem], chaine) = get_matrices_ac_ressource(ressources, sem)
|
||||||
|
#
|
||||||
|
# # Export yaml
|
||||||
|
# WITH_EXPORT = True
|
||||||
|
# for sem in ressources:
|
||||||
|
# for r in ressources[sem]:
|
||||||
|
# output = r.to_yaml()
|
||||||
|
# if WITH_EXPORT and r.code:
|
||||||
|
# fichier = "export/{}.yml".format(r.code)
|
||||||
|
# with open(fichier, "w", encoding="utf8") as fid:
|
||||||
|
# fid.write(output)
|
||||||
|
#
|
||||||
|
@ -93,28 +93,28 @@ def affiche_bilan_heures(ressources, sem):
|
|||||||
chaine += trait + "\n"
|
chaine += trait + "\n"
|
||||||
return chaine
|
return chaine
|
||||||
|
|
||||||
|
def get_officiel_name_by_code_using_dict(code, dico):
|
||||||
|
"""Extrait un nom à partir d'un code (pour les RESSOURCES ou les SAES)"""
|
||||||
|
for sem in dico:
|
||||||
|
for rcode in dico[sem]:
|
||||||
|
if rcode==code:
|
||||||
|
return dico[sem][code]
|
||||||
|
|
||||||
def get_officiel_ressource_name_by_code(code):
|
def get_officiel_ressource_name_by_code(code):
|
||||||
"""Pour un code valide, fournit le nom officiel de la ressource (sans connaissance du semestre)"""
|
"""Pour un code valide, fournit le nom officiel de la ressource (sans connaissance du semestre)"""
|
||||||
for sem in DATA_RESSOURCES:
|
return get_officiel_name_by_code_using_dict(code, DATA_RESSOURCES)
|
||||||
for rcode in DATA_RESSOURCES[sem]:
|
|
||||||
if rcode==code:
|
|
||||||
return DATA_RESSOURCES[sem][code]
|
|
||||||
|
|
||||||
def get_officiel_sae_name_by_code(code):
|
def get_officiel_sae_name_by_code(code):
|
||||||
"""Pour un code valide, fournit le nom officiel de la sae (sans connaissance du semestre)"""
|
"""Pour un code valide, fournit le nom officiel de la sae (sans connaissance du semestre)"""
|
||||||
for sem in DATA_SAES:
|
return get_officiel_name_by_code_using_dict(code, DATA_SAES)
|
||||||
for rcode in DATA_SAES[sem]:
|
|
||||||
if rcode==code:
|
|
||||||
return DATA_SAES[sem][code]
|
|
||||||
|
|
||||||
|
|
||||||
def get_code_from_nom(ressource):
|
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
|
"""Récupère le code d'une ressource d'après son nom en utilisant les noms officiels
|
||||||
des ressources du yaml"""
|
des ressources du yaml si dico == DATA_RESSOURCES ; sinon fait de même avec les SAE"""
|
||||||
nom = supprime_accent_espace(ressource.nom)
|
nom = supprime_accent_espace(ressource.nom)
|
||||||
for sem in DATA_RESSOURCES:
|
for sem in dico:
|
||||||
for code in DATA_RESSOURCES[sem]:
|
for code in dico[sem]:
|
||||||
nom_data = supprime_accent_espace(DATA_RESSOURCES[sem][code])
|
nom_data = supprime_accent_espace(dico[sem][code])
|
||||||
if nom.startswith(nom_data):
|
if nom.startswith(nom_data):
|
||||||
return code
|
return code
|
@ -9,7 +9,7 @@ S1:
|
|||||||
R108: "Bases des systèmes d'exploitation"
|
R108: "Bases des systèmes d'exploitation"
|
||||||
R109: "Introduction aux technologies Web"
|
R109: "Introduction aux technologies Web"
|
||||||
R110: "Anglais de communication et initiation au vocabulaire technique"
|
R110: "Anglais de communication et initiation au vocabulaire technique"
|
||||||
R111: "Expression-Culture-Communication Professionnelles (ECC1)"
|
R111: "Expression-Culture-Communication Professionnelles 1"
|
||||||
R112: "PPP: Connaître son champ d'activité"
|
R112: "PPP: Connaître son champ d'activité"
|
||||||
R113: "Mathématiques du signal"
|
R113: "Mathématiques du signal"
|
||||||
R114: "Mathématiques des transmissions"
|
R114: "Mathématiques des transmissions"
|
||||||
@ -24,8 +24,8 @@ S2:
|
|||||||
R207: "Sources de données"
|
R207: "Sources de données"
|
||||||
R208: "Analyse et traitement de données structurées"
|
R208: "Analyse et traitement de données structurées"
|
||||||
R209: "Initiation au développement Web"
|
R209: "Initiation au développement Web"
|
||||||
R210: "Développement de l'anglais technique"
|
R210: "Anglais de communication et développement de l'anglais technique"
|
||||||
R211: "Expression-Culture-Communication Professionnelles (ECC2)"
|
R211: "Expression-Culture-Communication Professionnelles 2"
|
||||||
R212: "PPP: Formalisation du projet"
|
R212: "PPP: Formalisation du projet"
|
||||||
R213: "Mathématiques des systèmes numériques"
|
R213: "Mathématiques des systèmes numériques"
|
||||||
R214: "Analyse des signaux"
|
R214: "Analyse mathématique des signaux"
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
S1:
|
S1:
|
||||||
SAÉ11: "Réseaux / cybersécurité / hygiène informatique"
|
SAÉ11: "Se sensibiliser à l'hygiène informatique et à la cybersécurité"
|
||||||
SAÉ12: "Réseau d'entreprise ou personnel"
|
SAÉ12: "S'initier aux réseaux informatiques"
|
||||||
SAÉ13: "Supports de transmission / calculs"
|
SAÉ13: "Découvrir un dispositif de transmission"
|
||||||
SAÉ14: "Se présenter sur Internet"
|
SAÉ14: "Se présenter sur Internet"
|
||||||
SAÉ15: "Traiter des données"
|
SAÉ15: "Traiter des données"
|
||||||
S2:
|
S2:
|
||||||
SAÉ21: "Construction d’un réseau informatique pour une petite structure"
|
SAÉ21: "Construire un réseau informatique pour une petite structure"
|
||||||
SAÉ22: "Mesures et caractérisation d’un signal ou d’un système"
|
SAÉ22: "Mesurer et caractériser un signal ou un système"
|
||||||
SAÉ23: "Mise en place d'une solution informatique pour l’entreprise"
|
SAÉ23: "Mettre en place une solution informatique pour l’entreprise"
|
||||||
SAÉ24: "Projet intégratif de S2"
|
SAÉ24: "Projet intégratif de S2"
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import re
|
import re
|
||||||
from officiel import *
|
from officiel import *
|
||||||
from modeles import *
|
from modeles import *
|
||||||
from officiel import supprime_accent_espace, get_code_from_nom
|
from officiel import supprime_accent_espace, get_code_from_nom_using_dict
|
||||||
import ruamel.yaml
|
import ruamel.yaml
|
||||||
from ruamel.yaml.scalarstring import FoldedScalarString as folded
|
from ruamel.yaml.scalarstring import FoldedScalarString as folded
|
||||||
|
|
||||||
@ -10,9 +10,9 @@ __LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class RessourceDocx():
|
class RessourceDocx():
|
||||||
"""Classe modélisant les ressources, lorsqu'elles sont extraites du docx"""
|
"""Classe modélisant les ressources, lorsqu'elles sont extraites du docx"""
|
||||||
def __init__(self, nom, brute):
|
def __init__(self, nom, brut):
|
||||||
self.nom = nom
|
self.nom = nom
|
||||||
self.brute = brute # les données brutes de la ressource
|
self.brut = brut # les données brutes de la ressource
|
||||||
|
|
||||||
def charge_informations(self, code, semestre, heures_encadrees, tp, sae, prerequis, description, mots):
|
def charge_informations(self, code, semestre, heures_encadrees, tp, sae, prerequis, description, mots):
|
||||||
self.code = code
|
self.code = code
|
||||||
@ -64,26 +64,28 @@ class RessourceDocx():
|
|||||||
output = output.replace("\n\n", "\n")
|
output = output.replace("\n\n", "\n")
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def nettoie_heure(r):
|
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]))
|
||||||
|
|
||||||
|
def nettoie_heure_ressource(r):
|
||||||
"""Nettoie le champ (horaire) (de la forme 46h ou 33...) pour en extraire la valeur numérique :
|
"""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
|
le champ peut contenir 2 volumes (heures formation puis heures tp), auquel cas les 2 valeurs sont renvoyées
|
||||||
dans un tuple"""
|
dans un tuple"""
|
||||||
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
|
if r.heures_encadrees: # si les heures encadrées sont renseignées
|
||||||
volumes = nettoie_champ_heure(r.heures_encadrees)
|
volumes = nettoie_champ_heure(r.heures_encadrees)
|
||||||
if r.tp:
|
if r.tp:
|
||||||
r.tp = nettoie_champ_heure(r.tp)
|
r.tp = nettoie_champ_heure(r.tp)
|
||||||
|
|
||||||
if isinstance(volumes, int):
|
if isinstance(volumes, int):
|
||||||
r.heures_encadrees = volumes
|
r.heures_encadrees = volumes
|
||||||
elif isinstance(volumes, tuple):
|
elif isinstance(volumes, tuple):
|
||||||
@ -97,11 +99,46 @@ def nettoie_heure(r):
|
|||||||
#else:
|
#else:
|
||||||
#__LOGGER.warning("Heures non détectées")
|
#__LOGGER.warning("Heures non détectées")
|
||||||
|
|
||||||
def nettoie_code(r):
|
|
||||||
"""Recherche les codes ressources de la forme RXXX dans champ"""
|
def nettoie_heure_sae(r):
|
||||||
|
"""Nettoie les champs (horaires) des saes"""
|
||||||
|
|
||||||
|
if r.heures_encadrees: # si les heures encadrées sont renseignées
|
||||||
|
r.heures_encadrees = nettoie_champ_heure(r.heures_encadrees)
|
||||||
|
else:
|
||||||
|
__LOGGER.warning(r"nettoie_heure_sae: dans {r.nom}, manque les heures de formation")
|
||||||
|
r.heures_encadrees = "???"
|
||||||
|
if r.tp:
|
||||||
|
r.tp = nettoie_champ_heure(r.tp)
|
||||||
|
else:
|
||||||
|
__LOGGER.warning(r"nettoie_heure_sae: dans {r.nom}, manque les heures de tp")
|
||||||
|
r.tp = "???"
|
||||||
|
|
||||||
|
if r.projet:
|
||||||
|
r.projet = nettoie_champ_heure(r.projet)
|
||||||
|
else:
|
||||||
|
__LOGGER.warning(r"nettoie_heure_sae: dans {r.nom}, manque les heures de projet")
|
||||||
|
r.projet = "???"
|
||||||
|
try:
|
||||||
|
if r.heures_encadrees < r.tp:
|
||||||
|
__LOGGER.warning(r"nettoie_heure_sae: dans {r.nom}, pb dans les heures formations/tp")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def nettoie_code(r, type = "ressource"):
|
||||||
|
"""Recherche les codes dans le champ:
|
||||||
|
* de la forme RXXX si type=ressource
|
||||||
|
* de la forme SAE|éXX si type=sae"""
|
||||||
|
|
||||||
champ = r.code
|
champ = r.code
|
||||||
if r.code:
|
if r.code:
|
||||||
codes = re.findall(r"(R[0-9][0-9][0-9])", champ)
|
if type == "ressource":
|
||||||
|
codes = re.findall(r"(R[0-9][0-9][0-9])", champ)
|
||||||
|
else: # type = "sae"
|
||||||
|
codes = re.findall(r"(SAE[0-9][0-9]|SAÉ[0-9][0-9])", champ)
|
||||||
|
# ajout des É
|
||||||
|
codes = [c.replace("E", "É") for c in codes]
|
||||||
# if len(codes) > 1:
|
# if len(codes) > 1:
|
||||||
# __LOGGER.warning("plusieurs codes trouvés :(")
|
# __LOGGER.warning("plusieurs codes trouvés :(")
|
||||||
#elif len(codes) == 0:
|
#elif len(codes) == 0:
|
||||||
@ -109,7 +146,10 @@ def nettoie_code(r):
|
|||||||
if len(codes) == 1:
|
if len(codes) == 1:
|
||||||
r.code = codes[0]
|
r.code = codes[0]
|
||||||
else:
|
else:
|
||||||
code_devine = get_code_from_nom(r)
|
if type == "ressource":
|
||||||
|
code_devine = get_code_from_nom_using_dict(r, DATA_RESSOURCES)
|
||||||
|
else:
|
||||||
|
code_devine = get_code_from_nom_using_dict(r, DATA_SAES)
|
||||||
if code_devine:
|
if code_devine:
|
||||||
__LOGGER.warning(f"nettoie_code : \"{r.nom}\" => code {code_devine}")
|
__LOGGER.warning(f"nettoie_code : \"{r.nom}\" => code {code_devine}")
|
||||||
r.code = code_devine
|
r.code = code_devine
|
||||||
@ -166,13 +206,21 @@ def nettoie_acs(r):
|
|||||||
r.apprentissages = dico # [comp] = acs_finaux
|
r.apprentissages = dico # [comp] = acs_finaux
|
||||||
|
|
||||||
def nettoie_sae(r):
|
def nettoie_sae(r):
|
||||||
"""Nettoie les sae en détectant les codes"""
|
"""Nettoie le champ SAe d'une ressource en détectant les codes"""
|
||||||
SAE_avec_code = devine_sae_by_code(r.sae)
|
SAE_avec_code = devine_sae_by_code(r.sae)
|
||||||
liste = [l.rstrip() for l in SAE_avec_code]
|
liste = [l.rstrip() for l in SAE_avec_code]
|
||||||
r.sae = liste
|
r.sae = liste
|
||||||
if not r.sae:
|
if not r.sae:
|
||||||
__LOGGER.warning(f"nettoie_sae: dans {r.nom} pas de SAE (:")
|
__LOGGER.warning(f"nettoie_sae: dans {r.nom} pas de SAE (:")
|
||||||
|
|
||||||
|
def nettoie_ressources(r):
|
||||||
|
"""Nettoie le champ ressource d'une sae en détectant les codes"""
|
||||||
|
ressources_avec_code = devine_ressources_by_code(r.ressources)
|
||||||
|
liste = [l.rstrip() for l in ressources_avec_code]
|
||||||
|
r.ressources = liste
|
||||||
|
if not r.ressources:
|
||||||
|
__LOGGER.warning(f"nettoie_ressources: dans {r.nom} pas de ressources (:")
|
||||||
|
|
||||||
def nettoie_prerequis(r):
|
def nettoie_prerequis(r):
|
||||||
"""Nettoie les prérequis (ressource) en les remplaçant par leur code de ressource"""
|
"""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_code = devine_ressources_by_code(r.prerequis)
|
||||||
@ -346,6 +394,40 @@ def caracteres_recalcitrants(contenu):
|
|||||||
contenu = contenu.replace('\xa0', ' ') # le nbsp
|
contenu = contenu.replace('\xa0', ' ') # le nbsp
|
||||||
return contenu
|
return contenu
|
||||||
|
|
||||||
|
|
||||||
|
class SAEDocx():
|
||||||
|
|
||||||
|
def __init__(self, nom, brut):
|
||||||
|
self.nom = nom
|
||||||
|
self.brut = brut # les données brutes de la ressource
|
||||||
|
|
||||||
|
def charge_informations(self, code, semestre, heures_encadrees, tp, projet, description, ressources, livrables, mots):
|
||||||
|
self.code = code
|
||||||
|
self.semestre = semestre # <--
|
||||||
|
self.heures_encadrees = heures_encadrees
|
||||||
|
self.tp = tp
|
||||||
|
self.projet = projet
|
||||||
|
self.description = description
|
||||||
|
self.ressources = ressources
|
||||||
|
self.livrables = livrables
|
||||||
|
self.mots = mots
|
||||||
|
|
||||||
|
def charge_ac(self, apprentissages):
|
||||||
|
self.apprentissages = apprentissages
|
||||||
|
|
||||||
|
class ExempleSAEDocx():
|
||||||
|
|
||||||
|
def __init__(self, nom, brut):
|
||||||
|
self.nom = nom
|
||||||
|
self.brut = brut # les données brutes de la ressource
|
||||||
|
|
||||||
|
def charge_informations(self, description, formes, problematique, modalite):
|
||||||
|
self.description = description
|
||||||
|
self.formes = formes # <--
|
||||||
|
self.problematique = problematique
|
||||||
|
self.modalite = modalite
|
||||||
|
|
||||||
|
|
||||||
if __name__=="__main__":
|
if __name__=="__main__":
|
||||||
# Eléments de test
|
# Eléments de test
|
||||||
for sem in DATA_RESSOURCES:
|
for sem in DATA_RESSOURCES:
|
||||||
|
19
python/tools.py
Normal file
19
python/tools.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
from officiel import supprime_accent_espace
|
||||||
|
|
||||||
|
|
||||||
|
def get_indice(champ, entetes):
|
||||||
|
"""Récupère l'indice d'une entête"""
|
||||||
|
for (i, entete) in enumerate(entetes):
|
||||||
|
if entete in champ:
|
||||||
|
return i
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_indice_sans_accent_ni_espace(champ, entetes):
|
||||||
|
"""Récupère l'indice d'une entête en se débarrassant des majuscules/caractères spéciaux/espace"""
|
||||||
|
champ_purge = supprime_accent_espace(champ).rstrip()
|
||||||
|
for (i, entete) in enumerate(entetes):
|
||||||
|
entete_purge = supprime_accent_espace(entete).rstrip()
|
||||||
|
if entete_purge in champ_purge:
|
||||||
|
return i
|
||||||
|
return None
|
Loading…
Reference in New Issue
Block a user