diff --git a/incomp_apogee/Incomp Info impair.xml.xlsx b/OLD_incomp_apogee/Incomp Info impair.xml.xlsx similarity index 100% rename from incomp_apogee/Incomp Info impair.xml.xlsx rename to OLD_incomp_apogee/Incomp Info impair.xml.xlsx diff --git a/incomp_apogee/Incomp math impair.xml.xlsx b/OLD_incomp_apogee/Incomp math impair.xml.xlsx similarity index 100% rename from incomp_apogee/Incomp math impair.xml.xlsx rename to OLD_incomp_apogee/Incomp math impair.xml.xlsx diff --git a/OLD_incomp_apogee/Incomp matiere info automne.xml.xlsx b/OLD_incomp_apogee/Incomp matiere info automne.xml.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..4601fa7fec4b62ef040b69dc9892b07f66412dd1 Binary files /dev/null and b/OLD_incomp_apogee/Incomp matiere info automne.xml.xlsx differ diff --git a/groupes_sillons/VET_JC_CLEAN.xlsx b/OLD_incomp_apogee/VET_JC_CLEAN.xlsx similarity index 100% rename from groupes_sillons/VET_JC_CLEAN.xlsx rename to OLD_incomp_apogee/VET_JC_CLEAN.xlsx diff --git a/OLD_incomp_apogee/VET_info.xlsx b/OLD_incomp_apogee/VET_info.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..4eafd59449d76df79e39546181df601a2784c901 Binary files /dev/null and b/OLD_incomp_apogee/VET_info.xlsx differ diff --git a/incomp_apogee/incomp LV.xml.xlsx b/OLD_incomp_apogee/incomp LV.xml.xlsx similarity index 100% rename from incomp_apogee/incomp LV.xml.xlsx rename to OLD_incomp_apogee/incomp LV.xml.xlsx diff --git a/incomp_apogee/incomp chimie impair.xlsx b/OLD_incomp_apogee/incomp chimie impair.xlsx similarity index 100% rename from incomp_apogee/incomp chimie impair.xlsx rename to OLD_incomp_apogee/incomp chimie impair.xlsx diff --git a/groupes_sillons/VET_Info_semP25.xlsx b/groupes_sillons/VET_Info_semP25.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..98b4f6638036a699c4ffd0292a4e2eba94c12080 Binary files /dev/null and b/groupes_sillons/VET_Info_semP25.xlsx differ diff --git a/groupes_sillons/VET_info.xlsx b/groupes_sillons/VET_info.xlsx deleted file mode 100644 index 92cdb2dc2d47a5435c74310c55f640b097287d47..0000000000000000000000000000000000000000 Binary files a/groupes_sillons/VET_info.xlsx and /dev/null differ diff --git a/incomp_apogee/Incomp Info info.xlsx b/incomp_apogee/Incomp Info info.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..a5897b204232f504d5b70b9a8003b577d5453a2a Binary files /dev/null and b/incomp_apogee/Incomp Info info.xlsx differ diff --git a/incomp_apogee/Incomp info.xlsx b/incomp_apogee/Incomp info.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..1ebd6d4a000d51f50b5ad8767099ab5d8d998a3f Binary files /dev/null and b/incomp_apogee/Incomp info.xlsx differ diff --git a/incompatibilites_manquantes.xlsx b/incompatibilites_manquantes.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..514877bc5592966cd9e846f8a29755437308fecd Binary files /dev/null and b/incompatibilites_manquantes.xlsx differ diff --git a/main.py b/main.py index 45d6b2d729a5be79b72f57fce03d1ed9b2c60f91..3445e7874cdeb7707fa0d54d017993a5738fac21 100644 --- a/main.py +++ b/main.py @@ -2,7 +2,7 @@ import pandas as pd import os from itertools import combinations -file_groupes_sillons = 'groupes_sillons/VET_Info.xlsx' +file_groupes_sillons = 'groupes_sillons/VET_Info_semP25.xlsx' directory_incomp_path = 'incomp_apogee' files_incomp_apogee = [os.path.join(directory_incomp_path, file) for file in os.listdir(directory_incomp_path) if file.endswith('.xlsx')] @@ -11,11 +11,11 @@ df['Sillon'] = df['Sillon'].ffill() df['CODE APOGEE'] = df['CODE APOGEE'].ffill() df['INTITULE MATIERE'] = df['INTITULE MATIERE'].ffill() -sillon_to_groups = {} -groupe_to_sillons = {} -groupe_to_ue = {} -groupe_to_intitule = {} -groupe_to_coll = {} +sillon_to_groups_with_ue = {} +groupe_with_ue_to_sillons = {} +groupe_with_ue_to_ue = {} +groupe_with_ue_to_intitule = {} +groupe_with_ue_to_coll = {} all_incompatibilities_apogee = set() all_incompatibilities_theory = set() @@ -27,7 +27,7 @@ def dic_creator(): for index, row in df.iterrows(): group_name = row['Groupe'].strip().upper() sillon = row['Sillon'] - ue = row['CODE APOGEE'] + ue = row['CODE APOGEE'].strip().upper() intitule = row['INTITULE MATIERE'] # si la cellule sillon est vide (cas fusion), on utilisera la dernière valeur connue @@ -40,31 +40,33 @@ def dic_creator(): if intitule: current_intitule = intitule + group_name_with_ue = current_ue + '-' + group_name sillons_list = str(current_sillon).split('+') for sillon in sillons_list: sillon = sillon.strip().upper() - if sillon and any(sillon == f"{i}{letter}" for i in range(1, 9) for letter in ['', 'A', 'B', 'a', 'b']): - if sillon in sillon_to_groups: - sillon_to_groups[sillon].append(group_name) + if sillon and any(sillon == f"{i}{letter}" for i in range(1, 9) for letter in ['', 'A', 'B']): + if sillon in sillon_to_groups_with_ue: + sillon_to_groups_with_ue[sillon].append(group_name_with_ue) else: - sillon_to_groups[sillon] = [group_name] + sillon_to_groups_with_ue[sillon] = [group_name_with_ue] else: - print(f"Sillon pas reconnu pour {group_name}") - groupe_to_sillons[group_name] = [s.strip().upper() for s in sillons_list] - groupe_to_ue[group_name] = current_ue - groupe_to_intitule[group_name] = current_intitule + print(f"Sillon pas reconnu pour {group_name_with_ue}") + groupe_with_ue_to_sillons[group_name_with_ue] = [s.strip().upper() for s in sillons_list] + groupe_with_ue_to_ue[group_name_with_ue] = current_ue + groupe_with_ue_to_intitule[group_name_with_ue] = current_intitule def print_infos(): print("--- Liste des groupes pour chaque sillon :") - for sillon, groupes in sillon_to_groups.items(): + for sillon, groupes in sillon_to_groups_with_ue.items(): print(f"Sillon {sillon}: {groupes}") print("\n--- Sillons pour chaque groupe :") - for groupe, sillons in groupe_to_sillons.items(): + for groupe, sillons in groupe_with_ue_to_sillons.items(): print(f"Groupe {groupe}: {sillons}") print("\n--- UE pour chaque groupe :") - for groupe, cours in groupe_to_ue.items(): - print(f"Groupe {groupe}: {cours}, {groupe_to_intitule[groupe]}") + for groupe, cours in groupe_with_ue_to_ue.items(): + print(f"Groupe {groupe}: {cours}, {groupe_with_ue_to_intitule[groupe]}") + print(f"Nombre de groupes : {len(groupe_with_ue_to_ue)}") # fonction pour vérifier si deux groupes donnés sont incompatibles (même sillon # en tenant compte des demi-sillons) @@ -87,38 +89,47 @@ def check_incompatibility(group1, group2, sillon_dict): # est affiché. def verifier_apogee_vs_theory(): for file in files_incomp_apogee: - df = pd.read_excel(file, engine='openpyxl') - for index, row in df.iterrows(): - group1 = row['COD_EXT_GPE'].upper() - group2 = row['COD_EXT_GPE1'].upper() - groupe_to_coll[group1] = row['COD_EXT_COL'].upper() - groupe_to_coll[group2] = row['COD_EXT_COL1'].upper() - - # on vérifie que les 2 groupes de l'incomp appartiennent à la VET - if (group1 in groupe_to_sillons and groupe_to_sillons[group1] - and group2 in groupe_to_sillons and groupe_to_sillons[group2]): - # normalisation de l'ordre pour garantir la cohérence - group_pair = tuple(sorted((group1, group2))) - - incompatibility, g1_sillons, g2_sillons = check_incompatibility(group1, group2, sillon_to_groups) - if incompatibility: - all_incompatibilities_apogee.add(group_pair) - else: - print(f"Erreur trouvée: {group1} ({groupe_to_ue[group1]}, {groupe_to_intitule[group1]}) et " - f"{group2} ({groupe_to_ue[group2]}, {groupe_to_intitule[group2]}) " - f"ne sont pas sur le même sillon mais déclarés incompatibles dans Apogee. " - f"Sillon(s) de {group1}: {g1_sillons}, Sillon(s) de {group2}: {g2_sillons}") + sheets = pd.read_excel(file, sheet_name=None, engine='openpyxl') # Charger tous les onglets + for sheet_name, df in sheets.items(): # Parcourir chaque onglet + print(f"Traitement de l'onglet : {sheet_name}") + for index, row in df.iterrows(): + group = row['COD_EXT_GPE'].upper() + group1 = row['COD_EXT_GPE1'].upper() + ue = row['COD_EXT_COL'].upper()[:8] + ue1 = row['COD_EXT_COL1'].upper()[:8] + + group_with_ue = ue + '-' + group + group1_with_ue1 = ue1 + '-' + group1 + + groupe_with_ue_to_coll[group_with_ue] = row['COD_EXT_COL'].upper() + groupe_with_ue_to_coll[group1_with_ue1] = row['COD_EXT_COL1'].upper() + + # on vérifie que les 2 groupes de l'incomp appartiennent à la VET + if (group_with_ue in groupe_with_ue_to_sillons and groupe_with_ue_to_sillons[group_with_ue] + and group1_with_ue1 in groupe_with_ue_to_sillons and groupe_with_ue_to_sillons[group1_with_ue1]): + # normalisation de l'ordre pour garantir la cohérence + group_pair = tuple(sorted((group_with_ue, group1_with_ue1))) + + incompatibility, g_sillons, g1_sillons = check_incompatibility(group_with_ue, group1_with_ue1, + sillon_to_groups_with_ue) + if incompatibility: + all_incompatibilities_apogee.add(group_pair) + else: + print(f"Erreur trouvée: {group} ({groupe_with_ue_to_ue[group_with_ue]}, {groupe_with_ue_to_intitule[group_with_ue]}) et " + f"{group1} ({groupe_with_ue_to_ue[group1_with_ue1]}, {groupe_with_ue_to_intitule[group1_with_ue1]}) " + f"ne sont pas sur le même sillon mais déclarés incompatibles dans Apogee. " + f"Sillon(s) de {group}: {g_sillons}, Sillon(s) de {group1}: {g1_sillons}") # fonction qui génére toutes les incomp d'après la théorie de l'association groupes/sillons def incomp_theory_creator(): - for sillon, groups in sillon_to_groups.items(): + for sillon, groups in sillon_to_groups_with_ue.items(): # ajout de toutes les paires du même sillon for group1, group2 in combinations(groups, 2): - if (groupe_to_ue[group1] != groupe_to_ue[group2]): # les groupes doivent appartenir à des UE différentes + if (groupe_with_ue_to_ue[group1] != groupe_with_ue_to_ue[group2]): # les groupes doivent appartenir à des UE différentes all_incompatibilities_theory.add(tuple(sorted((group1, group2)))) # ajout des paires entre demi-sillons A et non-A ou B et non-B base_sillon = ''.join(filter(str.isdigit, sillon)) - for other_sillon, other_groups in sillon_to_groups.items(): + for other_sillon, other_groups in sillon_to_groups_with_ue.items(): if other_sillon != sillon and ''.join(filter(str.isdigit, other_sillon)) == base_sillon: if not ((sillon.endswith('A') and other_sillon.endswith('B')) or (sillon.endswith('B') and other_sillon.endswith('A'))): for group1 in groups: @@ -132,30 +143,59 @@ def verifier_theory_vs_apogee(): if missing_incompatibilities: print("Oublis détectés dans les incompatibilités:") for group1, group2 in missing_incompatibilities: - print(f"{group1} ({groupe_to_ue[group1]}, {groupe_to_intitule[group1]}) et " - f"{group2} ({groupe_to_ue[group2]}, {groupe_to_intitule[group2]}) " + print(f"{group1.split('-')[0]} ({groupe_with_ue_to_ue[group1]}, {groupe_with_ue_to_intitule[group1]}) et " + f"{group2.split('-')[0]} ({groupe_with_ue_to_ue[group2]}, {groupe_with_ue_to_intitule[group2]}) " f"devraient être incompatibles mais ne sont pas listés dans Apogée.") else: print("Aucun oubli détecté.") +# vérifie que tous les groupes présents comme clés dans le dictionnaire `groupe_to_ue` +# apparaissent dans au moins une paire de `all_incompatibilities_apogee`. +def verify_group_names_are_in_apogee(): + missing_groups = set() + + for groupe in groupe_with_ue_to_ue.keys(): + # vérifie si le groupe est dans au moins une paire d'incompatibilités + if not any(groupe in pair for pair in all_incompatibilities_apogee): + missing_groups.add(groupe) + if missing_groups: + print(f"Les groupes suivants ne sont pas référencés dans Apogée : {missing_groups}") + else: + print("Tous les groupes souhaités sont référencés dans Apogée ") + + def export_missing_incomp(): missing_incompatibilities = all_incompatibilities_theory - all_incompatibilities_apogee if missing_incompatibilities: data = [] for group1, group2 in missing_incompatibilities: + # Vérification de la présence des collections + coll1 = groupe_with_ue_to_coll.get(group1, "???") + coll2 = groupe_with_ue_to_coll.get(group2, "???") + + # Afficher un message si une collection est inconnue + if coll1 == "???": + print(f"Attention, collection inconnue pour le groupe {group1}") + if coll2 == "???": + print(f"Attention, collection inconnue pour le groupe {group2}") + data.append([ - group1, groupe_to_ue[group1], groupe_to_intitule[group1], groupe_to_coll[group1], - group2, groupe_to_ue[group2], groupe_to_intitule[group2], groupe_to_coll[group2] + group1.split('-')[0], + groupe_with_ue_to_ue[group1], + groupe_with_ue_to_intitule[group1], + coll1, + group2.split('-')[0], + groupe_with_ue_to_ue[group2], + groupe_with_ue_to_intitule[group2], + coll2 ]) - # Creating a DataFrame df = pd.DataFrame(data, columns=[ 'Groupe 1', 'UE 1', 'Intitule 1', 'Coll 1', 'Groupe 2', 'UE 2', 'Intitule 2', 'Coll 2' ]) - # Writing to an Excel file df.to_excel('incompatibilites_manquantes.xlsx', index=False) print("Oublis détectés dans les incompatibilités et écrits dans 'incompatibilites_manquantes.xlsx'.") else: @@ -168,5 +208,9 @@ print("--- Apogee vs. theory:") verifier_apogee_vs_theory() print("--- Theory vs. apogee:") incomp_theory_creator() -verifier_theory_vs_apogee() -#export_missing_incomp() +verify_group_names_are_in_apogee() +print(f"Theory nb incomp : {len(all_incompatibilities_theory)}") +print(f"Apogee nb incomp : {len(all_incompatibilities_apogee)}") +#verifier_theory_vs_apogee() +export_missing_incomp() + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..ccdd6eda7737cb4fd63f32bb97841388975685f0 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,57 @@ +aiofiles==23.2.1 +anyio==4.1.0 +beautifulsoup4==4.12.3 +certifi==2023.5.7 +charset-normalizer==3.3.2 +ci-info==0.3.0 +click==8.1.7 +configobj==5.0.8 +configparser==6.0.0 +DateTime==5.4 +days==0.0.3 +et-xmlfile==1.1.0 +etelemetry==0.3.1 +filelock==3.13.1 +frontend==0.0.3 +future==0.18.3 +get-rankings==0.8 +h11==0.14.0 +httplib2==0.22.0 +idna==3.6 +isodate==0.6.1 +itsdangerous==2.1.2 +looseversion==1.3.0 +lxml==4.9.3 +networkx==3.2.1 +nibabel==5.1.0 +nipype==1.8.6 +numpy==1.25.2 +openpyxl==3.1.2 +packaging==23.2 +pandas==2.0.3 +parsedate==0.0.1 +pathlib==1.0.1 +pillow==10.3.0 +prov==2.0.0 +pydot==1.4.2 +PyMuPDF==1.23.7 +PyMuPDFb==1.23.7 +pyparsing==3.1.1 +PyPDF2==3.0.1 +python-dateutil==2.8.2 +pytz==2023.3 +pyxnat==1.6 +rdflib==7.0.0 +requests==2.31.0 +scipy==1.11.4 +simplejson==3.19.2 +six==1.16.0 +sniffio==1.3.0 +soupsieve==2.5 +starlette==0.33.0 +tqdm==4.66.1 +traits==6.3.2 +tzdata==2023.3 +urllib3==2.1.0 +uvicorn==0.24.0.post1 +zope.interface==6.1