correction et ajout de fichiers de test
La partie 'analyse' du programme est fonctionnelle Ajout de fichiers intentionellement erronés dans le repertoire de test
This commit is contained in:
parent
dfd0c8850c
commit
c9bfc721d3
@ -9,6 +9,9 @@ NOTES :
|
|||||||
pas de problème, car je n'exécute pas QGIS. Je n'ai pas encore trouvé
|
pas de problème, car je n'exécute pas QGIS. Je n'ai pas encore trouvé
|
||||||
comment désactiver cette option dans Git.
|
comment désactiver cette option dans Git.
|
||||||
|
|
||||||
|
VOIR : mettre core.autocrlf à false pour avoir un comportement normal
|
||||||
|
(checkout-as-is, commit-as-is).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
David.
|
David.
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
PROJCS["RGF_1993_Lambert_93",GEOGCS["GCS_RGF_1993",DATUM["D_RGF_1993",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",700000.0],PARAMETER["False_Northing",6600000.0],PARAMETER["Central_Meridian",3.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",44.0],PARAMETER["Latitude_Of_Origin",46.5],UNIT["Meter",1.0]]
|
DADADADAPROJCS["RGF_1991_Lambert_93",GEOGCS["GCS_RGF_1993",DATUM["D_RGF_1993",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",700000.0],PARAMETER["False_Northing",6600000.0],PARAMETER["Central_Meridian",3.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",44.0],PARAMETER["Latitude_Of_Origin",46.5],UNIT["Meter",1.0]]
|
||||||
@ -2,9 +2,12 @@
|
|||||||
|
|
||||||
# Voir algorithme.txt pour plus de détails et commentaires
|
# Voir algorithme.txt pour plus de détails et commentaires
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os # getcwd(),
|
import os # getcwd(),
|
||||||
|
|
||||||
|
|
||||||
|
## TODO : voir le pb des dicos qui auraient plusieurs fois les memes clés (se qui n'est pas possible) à cause de plusieurs fichiers qui auraient la meme extension
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -43,42 +46,199 @@ class _Fichier:
|
|||||||
# "Non-conforme",
|
# "Non-conforme",
|
||||||
# "A-ignorer"}
|
# "A-ignorer"}
|
||||||
def afficher(self):
|
def afficher(self):
|
||||||
|
"""Affiche dans la sortie standard les éléments du fichier
|
||||||
|
"""
|
||||||
print("nom : ".center(16), self.nom)
|
print("nom : ".center(16), self.nom)
|
||||||
print("nom orig : ".center(16), self.nom_original)
|
print("nom orig : ".center(16), self.nom_original)
|
||||||
print("ext : ".center(16), self.extension)
|
print("ext : ".center(16), self.extension)
|
||||||
print("chemin : ".center(16), self.chemin)
|
print("chemin : ".center(16), self.chemin)
|
||||||
print("implication :".center(16), self.implication)
|
print("implication :".center(16), self.implication)
|
||||||
|
|
||||||
|
def impliquer(self):
|
||||||
|
"""Définir l'implication d'un fichier
|
||||||
|
|
||||||
|
Les fichiers nécessaires sont indispensables sinon l'importation
|
||||||
|
de la couche échoue.
|
||||||
|
Les fichiers optionels (ou auxiliaires) contiennent des données
|
||||||
|
supplémentaires lors de l'importation.
|
||||||
|
Les fichiers non conformes pourraient être importer dans QGIS. Mais,
|
||||||
|
ne sont pas conformes au cahier des charges.
|
||||||
|
Les fichiers ignorés ne fonctionnent pas dans QGIS.
|
||||||
|
L'implication est définie en fonction de l'extension du fichier.
|
||||||
|
"""
|
||||||
|
match self.extension:
|
||||||
|
case "dbf" | "cpg" | "prj" | "shx" | "shp":
|
||||||
|
self.implication = "Necessaire"
|
||||||
|
case "qix" | "qmd" | "qml":
|
||||||
|
self.implication = "Auxiliaire"
|
||||||
|
case "gpkg" | "sqlite":
|
||||||
|
self.implication = "Non-conforme"
|
||||||
|
case _:
|
||||||
|
self.implication = "A-ignorer"
|
||||||
|
# TODO : gerer la casse des extensions pour que le controle se fasse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## TODO Mettre les init de dico à vide {} plutot ??
|
||||||
class _Catalogue:
|
class _Catalogue:
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
necessaires="Pas de dico",
|
necessaires,
|
||||||
auxiliaires="Pas de dico",
|
auxiliaires,
|
||||||
non_conformes="Pas de dico"):
|
non_conformes
|
||||||
|
):
|
||||||
self.necessaires = necessaires # - son dictionnaire de fichiers nécessaires avec pour clé l'extention
|
self.necessaires = necessaires # - son dictionnaire de fichiers nécessaires avec pour clé l'extention
|
||||||
# de chaque fichier - dico de paire string : _Fichier
|
# de chaque fichier - dico de paire string : _Fichier
|
||||||
self.auxiliaires = auxiliaires # - son dictionnaire de fichiers auxiliaires avec pour clé l'extention
|
self.auxiliaires = auxiliaires # - son dictionnaire de fichiers auxiliaires avec pour clé l'extention
|
||||||
# de chaque fichier - dico de paire string : _Fichier
|
# de chaque fichier - dico de paire string : _Fichier
|
||||||
self.non_conformes = non_conformes # - son dictionnaire de fichiers non-conformes avec pour clé l'extention
|
self.non_conformes = non_conformes # - son dictionnaire de fichiers non-conformes avec pour clé l'extention
|
||||||
# de chaque fichier - dico de paire string : _Fichier
|
# de chaque fichier - dico de paire string : _Fichier
|
||||||
|
# PB : Pour le moment cette facon de representer des groupes de fichiers
|
||||||
|
# ne gèrent pas le fait qu'il y ai plusieurs fichiers avec la meme extension,
|
||||||
|
# en effet, je ne peux pas avoir plusieurs clés avec la meme extension
|
||||||
|
|
||||||
|
def afficher(self):
|
||||||
|
"""Affiche le catalogue dans la sortie standard
|
||||||
|
|
||||||
|
Affiche aussi un message si pour chaque dictionnaire vide
|
||||||
|
"""
|
||||||
|
if self.necessaires: # TODO renvoie False si dico = {} ou alors dois je écrire if necessaires == {}
|
||||||
|
print("fichiers nécessaires :".center(28))
|
||||||
|
for fichier in self.necessaires.values():
|
||||||
|
print(" ", fichier.nom, fichier.extension)
|
||||||
|
else:
|
||||||
|
print("Pas de Nécessaires".center(28))
|
||||||
|
if self.auxiliaires:
|
||||||
|
print("fichiers auxiliaires :".center(28))
|
||||||
|
for fichier in self.auxiliaires.values():
|
||||||
|
print(" ", fichier.nom, fichier.extension)
|
||||||
|
else:
|
||||||
|
print("Pas d'Auxiliaires".center(28))
|
||||||
|
if self.non_conformes:
|
||||||
|
print("fichiers non conformes :".center(28))
|
||||||
|
for fichier in self.non_conformes.values():
|
||||||
|
print(" ", fichier.non_conformes)
|
||||||
|
else:
|
||||||
|
print("Pas de Non-conformes".center(28))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class _Projet:
|
class _Projet:
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
nom="Pas de nom",
|
nom="Pas de nom",
|
||||||
catalogue="Pas de catalogue",
|
necessaires = {},
|
||||||
|
auxiliaires = {},
|
||||||
|
non_conformes = {},
|
||||||
nb_fichiers=0,
|
nb_fichiers=0,
|
||||||
conformite=False,
|
conformite="Non conforme",
|
||||||
projection="Pas de projection",
|
projection="Pas de projection",
|
||||||
encodage="Pas d'encodage"):
|
encodage="Pas d'encodage"):
|
||||||
self.nom = nom # - son nom - string
|
self.nom = nom # - son nom - string
|
||||||
self.catalogue = catalogue # - son catalogue - _Catalogue
|
self.necessaires = necessaires
|
||||||
|
self.auxiliaires = auxiliaires
|
||||||
|
self.non_conformes = non_conformes
|
||||||
self.nb_fichiers = nb_fichiers # - son nombre de fichiers - entier
|
self.nb_fichiers = nb_fichiers # - son nombre de fichiers - entier
|
||||||
self.conformite = conformite # - sa conformité - bool
|
self.conformite = conformite # - sa conformité - bool
|
||||||
self.projection = projection # - sa projection géodésique - string // ou énumération --> voir Constantes
|
self.projection = projection # - sa projection géodésique - string // ou énumération --> voir Constantes
|
||||||
self.encodage = encodage # - son type d'encodage prévu dans QGIS string
|
self.encodage = encodage # - son type d'encodage prévu dans QGIS string
|
||||||
# /* pour ce script, ce devrait être forcement "UTF8" */
|
# /* pour ce script, ce devrait être forcement "UTF8" */
|
||||||
|
|
||||||
|
def afficher(self):
|
||||||
|
"""Affiche dans la sortie standard le contenu d'un projet
|
||||||
|
"""
|
||||||
|
print("nom : ".center(16), self.nom)
|
||||||
|
print("nb fichiers :".center(16), self.nb_fichiers)
|
||||||
|
print("conformité :".center(16), self.conformite)
|
||||||
|
print("projection :".center(16), self.projection)
|
||||||
|
print("encodage :".center(16), self.encodage)
|
||||||
|
print("necessaires :".center(16), self.necessaires)
|
||||||
|
print("auxiliaires :".center(16), self.auxiliaires)
|
||||||
|
print("non_conformes :".center(16), self.non_conformes)
|
||||||
|
#self.catalogue.afficher()
|
||||||
|
|
||||||
|
def cataloguer(self, fichier):
|
||||||
|
"""Catalogue le fichier dans le projet
|
||||||
|
|
||||||
|
La méthode ajoute le fichier suivant son extension
|
||||||
|
dans un des dictionnaires du catalogue
|
||||||
|
"""
|
||||||
|
match fichier.implication:
|
||||||
|
case "Necessaire":
|
||||||
|
self.necessaires[fichier.extension] = fichier
|
||||||
|
case "Auxiliaire":
|
||||||
|
self.auxiliaires[fichier.extension] = fichier
|
||||||
|
case "Non-conforme":
|
||||||
|
self.non_conformes[fichier.extension] = fichier
|
||||||
|
|
||||||
|
def lire_projection(self):
|
||||||
|
"""Récupère la projection des données géomatiques définie.
|
||||||
|
|
||||||
|
Lis la première ligne du fichier *.PRJ du projet
|
||||||
|
et controle la présence de la chaine "RGF_1993_Lambert_93"
|
||||||
|
"""
|
||||||
|
if "prj" in self.necessaires:
|
||||||
|
df = open(self.necessaires["prj"].chemin)
|
||||||
|
chaine = df.readline()
|
||||||
|
df.close()
|
||||||
|
if "RGF_1993_Lambert_93" in chaine:
|
||||||
|
self.projection = "LAMBERT93"
|
||||||
|
else:
|
||||||
|
print(projet.nom, " : pas de PRJ trouvé --> pas de projection définie")
|
||||||
|
|
||||||
|
def lire_encodage(self):
|
||||||
|
"""Récupère l'encodage prévu pour les fichiers dans QGIS
|
||||||
|
|
||||||
|
Lis la première ligne du fichier *.CPG du projet
|
||||||
|
et controle la présence de la chaine "UTF-8"
|
||||||
|
"""
|
||||||
|
if "cpg" in self.necessaires:
|
||||||
|
df = open(self.necessaires["cpg"].chemin)
|
||||||
|
chaine = df.readline()
|
||||||
|
#print("encod lu : ", chaine)
|
||||||
|
df.close()
|
||||||
|
if "UTF-8" in chaine:
|
||||||
|
self.encodage = "UTF8"
|
||||||
|
else:
|
||||||
|
print(projet.nom, " : pas de CPG trouvé --> pas d'encodage définie")
|
||||||
|
|
||||||
|
def valider(self):
|
||||||
|
"""Valide la conformité du projet
|
||||||
|
|
||||||
|
Controle si les 5 fichiers differents nécessaires sont présents.
|
||||||
|
Controle si la projection est correcte (pour le moment Lambert93).
|
||||||
|
Controle si l'encodage défini pour l'import dans QGIS est bien UTF8.
|
||||||
|
Si ces 3 controles sont OK, alors le projet est défini comme valide.
|
||||||
|
"""
|
||||||
|
nb_controles_OK = 0
|
||||||
|
# Controle présences fichiers
|
||||||
|
valide = [False, False, False, False, False]
|
||||||
|
for extension in self.necessaires.keys():
|
||||||
|
match extension:
|
||||||
|
case "dbf":
|
||||||
|
valide[0] = True
|
||||||
|
case "cpg":
|
||||||
|
valide[1] = True
|
||||||
|
case "prj" :
|
||||||
|
valide[2] = True
|
||||||
|
case "shx" :
|
||||||
|
valide[3] = True
|
||||||
|
case "shp" :
|
||||||
|
valide[4] = True
|
||||||
|
if valide[0] and valide[1] and valide[2] and valide[3] and valide[4]:
|
||||||
|
nb_controles_OK += 1
|
||||||
|
|
||||||
|
# Controle projection
|
||||||
|
if self.projection == "LAMBERT93":
|
||||||
|
nb_controles_OK += 1
|
||||||
|
|
||||||
|
# Controle encodage
|
||||||
|
if self.encodage == "UTF8":
|
||||||
|
nb_controles_OK += 1
|
||||||
|
|
||||||
|
# Si les 3 controles sont OK ALors le projet est conforme
|
||||||
|
if nb_controles_OK == 3:
|
||||||
|
self.conformite = "Conforme"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# DEFINITIONS DE FONCTIONS
|
# DEFINITIONS DE FONCTIONS
|
||||||
|
|
||||||
@ -92,7 +252,7 @@ def formatter(chaine):
|
|||||||
Ne traite pas pour le moment le AE et OE ligaturé.
|
Ne traite pas pour le moment le AE et OE ligaturé.
|
||||||
"""
|
"""
|
||||||
#TODO : gérer les accents sur majuscules
|
#TODO : gérer les accents sur majuscules
|
||||||
#TODO : amélioration ou exercice, utiliser la méthode str.translate() et maketrans
|
#TODO : amélioration ou exercice, utiliser la méthode str.translate() et maketrans
|
||||||
resultat = ""
|
resultat = ""
|
||||||
for c in chaine:
|
for c in chaine:
|
||||||
match c:
|
match c:
|
||||||
@ -118,32 +278,6 @@ def formatter(chaine):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def impliquer(fichier):
|
|
||||||
"""Définir l'implication d'un fichier
|
|
||||||
|
|
||||||
Les fichiers nécessaires sont indispensables sinon l'importation
|
|
||||||
de la couche échoue.
|
|
||||||
Les fichiers optionels (ou auxiliaires) contiennent des données
|
|
||||||
supplémentaires lors de l'importation.
|
|
||||||
Les fichiers non conformes pourraient être importer dans QGIS. Mais,
|
|
||||||
ne sont pas conformes au cahier des charges.
|
|
||||||
Les fichiers ignorés ne fonctionnent pas dans QGIS.
|
|
||||||
L'implication est définie en fonction de l'extension du fichier.
|
|
||||||
"""
|
|
||||||
resultat = fichier
|
|
||||||
match fichier.extension:
|
|
||||||
case "dbf" | "cpg" | "prj" | "shx" | "shp":
|
|
||||||
resultat.implication = "Necessaire"
|
|
||||||
case "qix" | "qmd" | "qml":
|
|
||||||
resultat.implication = "Auxiliaire"
|
|
||||||
case "qpkg" | "sqlite":
|
|
||||||
resultat.implication = "Non-conforme"
|
|
||||||
case _:
|
|
||||||
resultat.implication = "A-ignorer"
|
|
||||||
return resultat
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# DEBUT DU PROGRAMME
|
# DEBUT DU PROGRAMME
|
||||||
|
|
||||||
@ -151,7 +285,7 @@ liste = [] # - une liste des fichiers list _Fichier
|
|||||||
dico = {} # - un dictionnaire des projets avec pour clé le nom de chaque projet
|
dico = {} # - un dictionnaire des projets avec pour clé le nom de chaque projet
|
||||||
# dico de paire string : Entité Projet
|
# dico de paire string : Entité Projet
|
||||||
racine = os.getcwd() # - un chemin absolue vers le repertoire racine à traiter string
|
racine = os.getcwd() # - un chemin absolue vers le repertoire racine à traiter string
|
||||||
print(racine)
|
print("Racine : ".center(18), racine)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -159,7 +293,7 @@ print(racine)
|
|||||||
# Si il y a PAS un dossier de traitement dans le working directory Alors
|
# Si il y a PAS un dossier de traitement dans le working directory Alors
|
||||||
pas_de_dossier = True
|
pas_de_dossier = True
|
||||||
|
|
||||||
for a in os.scandir("./"):
|
for a in os.scandir():
|
||||||
if a.is_dir():
|
if a.is_dir():
|
||||||
#il y a un dossier
|
#il y a un dossier
|
||||||
pas_de_dossier = False
|
pas_de_dossier = False
|
||||||
@ -175,64 +309,84 @@ else:
|
|||||||
|
|
||||||
# --analyser le dossier
|
# --analyser le dossier
|
||||||
# initialiser une liste de _Fichiers
|
# initialiser une liste de _Fichiers
|
||||||
liste = []
|
liste = []
|
||||||
# Pour Chaque fichier des dossiers et sous dossiers à explorer Faire
|
# Pour Chaque fichier des dossiers et sous dossiers à explorer Faire
|
||||||
for dossier_courant, list_dossiers, list_fichiers in os.walk(racine):
|
for dossier_courant, list_sousdossiers, list_fichiers in os.walk(racine): ##TODO voir la fonction fwalk qui renvoie un 4-tuple(dirpath, dirnames, filenames, dirfd), and it supports dir_fd
|
||||||
for fichier_courant in list_fichiers:
|
for fichier_courant in list_fichiers:
|
||||||
# --lire, analyser chaque fichier et peupler la liste
|
# --lire, analyser chaque fichier et peupler la liste
|
||||||
# initialiser un _Fichier
|
# initialiser un _Fichier
|
||||||
ce_Fichier = _Fichier()
|
ce_Fichier = _Fichier()
|
||||||
# lire son chemin
|
# lire son chemin
|
||||||
ce_Fichier.chemin = fichier_courant
|
ce_Fichier.chemin = dossier_courant + "\\" + fichier_courant
|
||||||
# déterminer son nom original et son extension
|
# déterminer son nom original et son extension
|
||||||
# lire le nom original
|
# lire le nom original
|
||||||
# lire son extension
|
# lire son extension
|
||||||
ce_Fichier.nom_original, ce_Fichier.extension = ce_Fichier.chemin.split(".")
|
ce_Fichier.nom_original, ce_Fichier.extension = fichier_courant.split(".")
|
||||||
# formatter et écrire le nom
|
# formatter et écrire le nom
|
||||||
ce_Fichier.nom = formatter(ce_Fichier.nom_original)
|
ce_Fichier.nom = formatter(ce_Fichier.nom_original)
|
||||||
# déterminer son implication
|
# déterminer son implication
|
||||||
ce_Fichier = impliquer(ce_Fichier) # TODO impliquer(), A VOIR si je peux passer juste l'implicatin et non l'ojbet en entier
|
ce_Fichier.impliquer()
|
||||||
# ajouter le _Fichier à la liste
|
# ajouter le _Fichier à la liste
|
||||||
liste.append(ce_Fichier)
|
liste.append(ce_Fichier)
|
||||||
# Fin Pour
|
# Fin Pour
|
||||||
|
|
||||||
# /* Ici la liste des _Fichiers doit être correctement remplie */
|
# /* Ici la liste des _Fichiers doit être correctement remplie */
|
||||||
#TEST affichage de la liste de fichier
|
#TEST affichage de la liste de fichier
|
||||||
for a in liste:
|
|
||||||
a.afficher()
|
|
||||||
print("\n\n")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
os.system("pause")
|
|
||||||
|
|
||||||
# initialiser un dictionnaire de _Projets avec comme clé leurs noms respectifs
|
# initialiser un dictionnaire de _Projets avec comme clé leurs noms respectifs
|
||||||
|
print("Init Dico\n")
|
||||||
|
dico = {}
|
||||||
# Pour Chaque fichier de la liste Faire
|
# Pour Chaque fichier de la liste Faire
|
||||||
|
for fichier_courant in liste:
|
||||||
|
if fichier_courant.implication not in "A-ignorer":
|
||||||
# --associer le fichier courant à un projet du dictionnaire
|
# --associer le fichier courant à un projet du dictionnaire
|
||||||
# /* Vérifier que le projet existe déjà dans le dico */
|
# /* Vérifier que le projet existe déjà dans le dico */
|
||||||
# Si le nom du fichier courant n'est pas dans le dico Alors
|
# Si le nom du fichier courant n'est pas dans le dico Alors
|
||||||
|
if fichier_courant.nom not in dico:
|
||||||
# initialiser un _Projet
|
# initialiser un _Projet
|
||||||
|
projet = _Projet()
|
||||||
|
projet.necessaires = {}
|
||||||
|
projet.auxiliaires = {}
|
||||||
|
projet.non_conformes = {}
|
||||||
|
projet.nom = fichier_courant.nom
|
||||||
|
print("création clé : ", projet.nom)
|
||||||
# ajouter le nom comme clé dans le dictionnaire
|
# ajouter le nom comme clé dans le dictionnaire
|
||||||
# associer le projet à cette clé
|
# associer le projet à cette clé
|
||||||
|
dico[projet.nom] = projet
|
||||||
|
|
||||||
|
#test contenu du dico
|
||||||
|
|
||||||
# Fin Si
|
# Fin Si
|
||||||
# cataloguer le fichier dans le projet concerné
|
# cataloguer le fichier dans le projet concerné
|
||||||
|
projet.cataloguer(fichier_courant)
|
||||||
# il y a un fichier de plus au projet
|
# il y a un fichier de plus au projet
|
||||||
|
projet.nb_fichiers += 1
|
||||||
|
else:
|
||||||
|
# sinon le fichier est a ignorer
|
||||||
|
print("Ignoré : ".center(16), fichier_courant.nom_original)
|
||||||
# Fin Pour
|
# Fin Pour
|
||||||
|
|
||||||
# Pour Chaque projet du dictionnaire Faire
|
# Pour Chaque projet du dictionnaire Faire
|
||||||
|
for projet in dico.values():
|
||||||
# --analyser et completer les infos du projet courant
|
# --analyser et completer les infos du projet courant
|
||||||
# /* conformité, projection, encodage etc */
|
# /* conformité, projection, encodage etc */
|
||||||
# lire la projection du projet courant
|
# lire la projection du projet courant
|
||||||
|
projet.lire_projection()
|
||||||
# lire l'encodage du projet courant
|
# lire l'encodage du projet courant
|
||||||
|
projet.lire_encodage()
|
||||||
# Si tous les fichiers nécessaires sont présents ET
|
# Si tous les fichiers nécessaires sont présents ET
|
||||||
# la projection est correcte ET
|
# la projection est correcte ET
|
||||||
# l'encodage est correct Alors
|
# l'encodage est correct Alors
|
||||||
# passer le projet à conforme
|
# passer le projet à conforme
|
||||||
|
projet.valider()
|
||||||
# Fin Si
|
# Fin Si
|
||||||
# Fin Pour
|
# Fin Pour
|
||||||
|
|
||||||
# /* Ici le dictionnaire des _Projets doit être correctement remplie */
|
# /* Ici le dictionnaire des _Projets doit être correctement remplie */
|
||||||
|
|
||||||
|
|
||||||
|
os.system("pause")
|
||||||
|
|
||||||
# --produire le rapport
|
# --produire le rapport
|
||||||
# créer un classeur Excel
|
# créer un classeur Excel
|
||||||
# /* Note : peut être utiliser un modèle pré-config */
|
# /* Note : peut être utiliser un modèle pré-config */
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user