From 35aa7d12fa93032a0b45f25592453462d5f9b80c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabrication=20du=20Num=C3=A9rique?= Date: Wed, 4 Jun 2025 21:24:56 +0200 Subject: [PATCH] Typage des fonctions de pda et documentation --- app/plan_d_action/interface.py | 14 +- app/plan_d_action/utils/data/config.py | 2 +- .../utils/data/data_processing.py | 9 + app/plan_d_action/utils/data/data_utils.py | 45 +++- app/plan_d_action/utils/data/pda_interface.py | 203 ++++++++++++------ app/plan_d_action/utils/data/plan_d_action.py | 118 +++++----- app/plan_d_action/utils/interface/export.py | 40 +++- .../utils/interface/niveau_utils.py | 15 +- app/plan_d_action/utils/interface/parser.py | 16 +- .../utils/interface/selection.py | 52 ++++- .../utils/interface/visualization.py | 17 +- app/plan_d_action/utils/jobs/f7e9ba2e.md | 76 +++---- batch_ia/utils/sections.py | 2 +- 13 files changed, 432 insertions(+), 177 deletions(-) diff --git a/app/plan_d_action/interface.py b/app/plan_d_action/interface.py index 2c6ff6f..d5275a3 100644 --- a/app/plan_d_action/interface.py +++ b/app/plan_d_action/interface.py @@ -1,5 +1,8 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# +import networkx as nx + """ Script pour générer un rapport factorisé des vulnérabilités critiques suivant la structure définie dans Remarques.md. @@ -37,7 +40,16 @@ from app.plan_d_action import ( inverse_niveau_labels = {v: k for k, v in niveau_labels.items()} -def interface_plan_d_action(G_temp): +def interface_plan_d_action(G_temp: nx.Graph) -> None: + """Interface pour planifier l'action de sélection des minerais. + + Args: + G_temp (nx.Graph): Le graphe temporaire à analyser. + + Returns: + None: Modifie le state du Streamlit avec les données nécessaires + pour la génération du rapport factorisé des vulnérabilités critiques. + """ if "sel_prod" not in st.session_state: st.session_state.sel_prod = None diff --git a/app/plan_d_action/utils/data/config.py b/app/plan_d_action/utils/data/config.py index 28716a7..9f4912f 100644 --- a/app/plan_d_action/utils/data/config.py +++ b/app/plan_d_action/utils/data/config.py @@ -132,7 +132,7 @@ INDICATEURS = { "Capacité libre des EMS (%) rapportée chaque vendredi." ], 'Modérée': [ - "Part du second fondeur dans la production du composant audio (%).", + "Part du second fondeur dans la production du composant (%).", "Nombre de PCB « design-for-substitution » validés." ], 'Difficile': [ diff --git a/app/plan_d_action/utils/data/data_processing.py b/app/plan_d_action/utils/data/data_processing.py index 159058f..f540267 100644 --- a/app/plan_d_action/utils/data/data_processing.py +++ b/app/plan_d_action/utils/data/data_processing.py @@ -1,6 +1,15 @@ import re def parse_chains_md(filepath: str) -> tuple[dict, dict, dict, list, dict, dict]: + """Lit et analyse un fichier Markdown contenant des informations sur les chaînes minérales. + + Args: + filepath (str): Chemin vers le fichier Markdown à analyser. + + Returns: + tuple: Un ensemble de dictionnaires et listes contenant les données extraites du fichier, + incluant les produits, composants, mineraux, chaînes et leurs descriptions détaillées. + """ re_start_section = re.compile(r"^##\s*Chaînes\s+avec\s+risque\s+critique", re.IGNORECASE) re_other_h2 = re.compile(r"^##\s+(?!(Chaînes\s+avec\s+risque\s+critique))") re_chain_heading = re.compile(r"^###\s*(.+)\s*→\s*(.+)\s*→\s*(.+)$") diff --git a/app/plan_d_action/utils/data/data_utils.py b/app/plan_d_action/utils/data/data_utils.py index 444064c..fb336ce 100644 --- a/app/plan_d_action/utils/data/data_utils.py +++ b/app/plan_d_action/utils/data/data_utils.py @@ -1,7 +1,16 @@ import yaml import streamlit as st -def get_seuil(seuils_dict, key): +def get_seuil(seuils_dict: dict, key: str) -> float|None: + """Récupère un seuil pour une clé donnée dans le dictionnaire. + + Args: + seuils_dict (dict): Dictionnaire contenant les seuils. + key (str): Clé du seuil à récupérer. + + Returns: + float|None: Le seuil si existant, sinon None. + """ try: if key in seuils_dict: data = seuils_dict[key] @@ -16,7 +25,19 @@ def get_seuil(seuils_dict, key): pass return None -def set_vulnerability(v1, v2, t1, t2, seuils): +def set_vulnerability(v1: int, v2: int, t1: str, t2: str, seuils: dict) -> tuple[int,str,str,str]: + """Calcule la vulnérabilité en fonction des seuils. + + Args: + v1 (int): Valeur de vulnérabilité 1. + v2 (int): Valeur de vulnérabilité 2. + t1 (str): Type 1. + t2 (str): Type 2. + seuils (dict): Dictionnaire des seuils. + + Returns: + tuple[int, str, str, str]: Poids et couleurs pour les deux types. + """ v1_poids = 1 v1_couleur = "Vert" if v1 > seuils[t1]["rouge"]["min"]: @@ -44,7 +65,15 @@ def set_vulnerability(v1, v2, t1, t2, seuils): return poids, couleur, v1_couleur, v2_couleur -def colorer_couleurs(la_couleur): +def colorer_couleurs(la_couleur: str) -> str: + """Convertit une couleur en badge Markdown. + + Args: + la_couleur (str): Couleur à convertir (rouge/difficile, orange/modérée, vert/facile). + + Returns: + str: Badge Markdown correspondant. + """ t = la_couleur.lower() if t == "rouge" or t == "difficile": return f":red-badge[{la_couleur}]" @@ -54,7 +83,15 @@ def colorer_couleurs(la_couleur): return f":green-badge[{la_couleur}]" return la_couleur -def initialiser_seuils(config_path): +def initialiser_seuils(config_path: str) -> dict: + """Charge les seuils depuis un fichier YAML de configuration. + + Args: + config_path (str): Chemin vers le fichier de configuration YAML. + + Returns: + dict: Dictionnaire des seuils chargés. + """ seuils = {} try: diff --git a/app/plan_d_action/utils/data/pda_interface.py b/app/plan_d_action/utils/data/pda_interface.py index 6f78595..ea61d96 100644 --- a/app/plan_d_action/utils/data/pda_interface.py +++ b/app/plan_d_action/utils/data/pda_interface.py @@ -1,7 +1,11 @@ import streamlit as st -def afficher_bloc_ihh_isg(titre, ihh, isg, details_content=""): - st.markdown(f"### {titre}") +def afficher_bloc_ihh_isg(titre, ihh, isg, details_content="", ui = True) -> str|None: + contenu_bloc = "" + if ui: + st.markdown(f"### {titre}") + else: + contenu_bloc = f"### {titre}\n" if not details_content: st.markdown("Données non disponibles") @@ -11,49 +15,74 @@ def afficher_bloc_ihh_isg(titre, ihh, isg, details_content=""): # 1. Afficher vulnérabilité combinée en premier if "#### Vulnérabilité combinée IHH-ISG" in details_content: - conteneur, = st.columns([1], gap="small", border=True) - with conteneur: - st.markdown("#### Vulnérabilité combinée IHH-ISG") - contenu = afficher_section_texte(lines, "#### Vulnérabilité combinée IHH-ISG", "###") - st.markdown(contenu) + contenu_md = "#### Vulnérabilité combinée IHH-ISG\n" + contenu_md += afficher_section_texte(lines, "#### Vulnérabilité combinée IHH-ISG", "###") + contenu_md += "\n" + if ui: + conteneur, = st.columns([1], gap="small", border=True) + with conteneur: + st.markdown(contenu_md) + else: + contenu_bloc += contenu_md # 2. Afficher ISG des pays impliqués if "##### ISG des pays impliqués" in details_content: - st.markdown("#### ISG des pays impliqués") - contenu = afficher_section_avec_tableau(lines, "##### ISG des pays impliqués") - st.markdown(contenu) - # Afficher le résumé ISG combiné for line in lines: if "**ISG combiné:" in line: st.markdown(line) break + contenu_md = "#### ISG des pays impliqués\n" + contenu_md += afficher_section_avec_tableau(lines, "##### ISG des pays impliqués") + contenu_md += "\n" + if ui: + st.markdown(contenu_md) + else: + contenu_bloc += contenu_md + # 3. Afficher la section IHH complète if "#### Indice de Herfindahl-Hirschmann" in details_content: - st.markdown("#### Indice de Herfindahl-Hirschmann") + contenu_md = "#### Indice de Herfindahl-Hirschmann\n" # Tableau de résumé IHH - contenu = afficher_section_avec_tableau(lines, "#### Indice de Herfindahl-Hirschmann") - st.markdown(contenu) + contenu_md += afficher_section_avec_tableau(lines, "#### Indice de Herfindahl-Hirschmann") + contenu_md += "\n" + if ui: + st.markdown(contenu_md) + else: + contenu_bloc += contenu_md # IHH par entreprise if "##### IHH par entreprise (acteurs)" in details_content: - st.markdown("##### IHH par entreprise (acteurs)") - contenu = afficher_section_texte(lines, "##### IHH par entreprise (acteurs)", "##### IHH par pays") - st.markdown(contenu) + contenu_md = "##### IHH par entreprise (acteurs)\n" + contenu_md += afficher_section_texte(lines, "##### IHH par entreprise (acteurs)", "##### IHH par pays") + st.markdown(contenu_md) # IHH par pays if "##### IHH par pays" in details_content: - st.markdown("##### IHH par pays") - contenu = afficher_section_texte(lines, "##### IHH par pays", "##### En résumé") - st.markdown(contenu) + contenu_md = "##### IHH par pays\n" + contenu_md += afficher_section_texte(lines, "##### IHH par pays", "##### En résumé") + contenu_md += "\n" + if ui: + st.markdown(contenu_md) + else: + contenu_bloc += contenu_md # En résumé if "##### En résumé" in details_content: - st.markdown("##### En résumé") - contenu = afficher_section_texte(lines, "##### En résumé", "####") - st.markdown(contenu) + contenu_md = "##### En résumé\n" + contenu_md += afficher_section_texte(lines, "##### En résumé", "####") + contenu_md += "\n" + if ui: + st.markdown(contenu_md) + else: + contenu_bloc += contenu_md + + if not ui: + return contenu_bloc + else: + return None def afficher_section_avec_tableau(lines, section_start, section_end=None): """Affiche une section contenant un tableau""" @@ -98,79 +127,117 @@ def afficher_section_texte(lines, section_start, section_end_marker=None): contenu = '\n'.join(contenu_md) return contenu -def afficher_description(titre, description): - st.markdown(f"## {titre}") - conteneur, = st.columns([1], gap="small", border=True) - with conteneur: - if description: - lines = description.split('\n') - description_lines = [] +def afficher_description(titre, description, ui = True) -> str|None: + contenu_bloc = "" + if ui: + st.markdown(f"### {titre}") + else: + contenu_bloc = f"### {titre}\n" - # Extraire le premier paragraphe descriptif - for line in lines: - line = line.strip() - if not line: - if description_lines: # Si on a déjà du contenu, une ligne vide termine le paragraphe - break - continue - # Arrêter aux titres de sections ou tableaux - if (line.startswith('####') or - line.startswith('|') or - line.startswith('**Unité')): + if description: + lines = description.split('\n') + description_lines = [] + + # Extraire le premier paragraphe descriptif + for line in lines: + line = line.strip() + if not line: + if description_lines: # Si on a déjà du contenu, une ligne vide termine le paragraphe break - description_lines.append(line) + continue + # Arrêter aux titres de sections ou tableaux + if (line.startswith('####') or + line.startswith('|') or + line.startswith('**Unité')): + break + description_lines.append(line) - if description_lines: - # Rejoindre les lignes en un seul paragraphe - full_description = ' '.join(description_lines) - st.markdown(full_description) - else: - st.markdown("Description non disponible") + if description_lines: + # Rejoindre les lignes en un seul paragraphe + contenu_md = ' '.join(description_lines) else: - st.markdown("Description non disponible") + contenu_md = "Description non disponible" + else: + contenu_md = "Description non disponible" -def afficher_caracteristiques_minerai(minerai, mineraux_data, details_content=""): - st.markdown("### Caractéristiques générales") + if ui: + conteneur, = st.columns([1], gap="small", border=True) + with conteneur: + st.markdown(contenu_md) + return None + else: + contenu_bloc += contenu_md + return contenu_bloc + +def afficher_caracteristiques_minerai(minerai, mineraux_data, details_content="", ui = True) -> str|None: + contenu_bloc = "" + if ui: + st.markdown("### Caractéristiques générales") + else: + contenu_bloc = "### Caractéristiques générales\n" if not details_content: - st.markdown("Données non disponibles") + if ui: + st.markdown("Données non disponibles") + else: + contenu_bloc += "Données non disponibles\n" return lines = details_content.split('\n') # 3. Afficher la vulnérabilité combinée ICS-IVC en dernier if "#### Vulnérabilité combinée ICS-IVC" in details_content: - conteneur, = st.columns([1], gap="small", border=True) - with conteneur: - st.markdown("#### Vulnérabilité combinée ICS-IVC") - contenu = afficher_section_texte(lines, "#### Vulnérabilité combinée ICS-IVC", "####") - st.markdown(contenu) + contenu_md = "#### Vulnérabilité combinée ICS-IVC\n" + contenu_md += afficher_section_texte(lines, "#### Vulnérabilité combinée ICS-IVC", "####") + contenu_md += "\n" + if ui: + conteneur, = st.columns([1], gap="small", border=True) + with conteneur: + st.markdown(contenu_md) + else: + contenu_bloc += contenu_md # 1. Afficher la section ICS complète if "#### ICS" in details_content: - st.markdown("#### ICS") + contenu_md = "#### ICS\n" # Afficher le premier tableau ICS (avec toutes les colonnes) - contenu = afficher_section_avec_tableau(lines, "#### ICS", "##### Valeurs d'ICS par composant") - st.markdown(contenu) + contenu_md += afficher_section_avec_tableau(lines, "#### ICS", "##### Valeurs d'ICS par composant concerné") + contenu_md += "\n" + if ui: + st.markdown(contenu_md) + else: + contenu_bloc += contenu_md # Afficher la sous-section "Valeurs d'ICS par composant" - if "##### Valeurs d'ICS par composant" in details_content: - st.markdown("##### Valeurs d'ICS par composant") - contenu = afficher_section_avec_tableau(lines, "##### Valeurs d'ICS par composant", "**ICS moyen") + if "##### Valeurs d'ICS par composant concerné" in details_content: + contenu_md = "##### Valeurs d'ICS par composant concerné\n" # Afficher le résumé ICS moyen for line in lines: if "**ICS moyen" in line: - contenu = contenu + line + contenu_md += line break - st.markdown(contenu) + contenu_md += "\n" + contenu_md += afficher_section_avec_tableau(lines, "##### Valeurs d'ICS par composant concerné", "**ICS moyen") + contenu_md += "\n" + + if ui: + st.markdown(contenu_md) + else: + contenu_bloc += contenu_md # 2. Afficher la section IVC complète if "#### IVC" in details_content: - st.markdown("#### IVC") + contenu_md = "#### IVC\n" # Afficher tous les détails de la section IVC - contenu = afficher_section_texte(lines, "#### IVC", "#### Vulnérabilité combinée ICS-IVC") - st.markdown(contenu) + contenu_md += afficher_section_texte(lines, "#### IVC", "#### Vulnérabilité combinée ICS-IVC") + contenu_md += "\n" + if ui: + st.markdown(contenu_md) + return None + else: + contenu_bloc += contenu_md + return contenu_bloc diff --git a/app/plan_d_action/utils/data/plan_d_action.py b/app/plan_d_action/utils/data/plan_d_action.py index d916ab9..8821a6e 100644 --- a/app/plan_d_action/utils/data/plan_d_action.py +++ b/app/plan_d_action/utils/data/plan_d_action.py @@ -14,7 +14,7 @@ from app.plan_d_action.utils.data import ( initialiser_seuils ) -def calcul_poids_chaine(poids_A, poids_F, poids_T, poids_E, poids_M): +def calcul_poids_chaine(poids_A: int, poids_F: int, poids_T: int, poids_E: int, poids_M: int) -> tuple[str,dict,int]: poids_total = (\ poids_A * poids_operation["Assemblage"] + \ poids_F * poids_operation["Fabrication"] + \ @@ -35,7 +35,7 @@ def calcul_poids_chaine(poids_A, poids_F, poids_T, poids_E, poids_M): return criticite_chaine, niveau_criticite, poids_total -def analyser_chaines(chaines, produits, composants, mineraux, seuils, top_n=None): +def analyser_chaines(chaines: list[dict], produits: dict, composants: dict, mineraux: dict, seuils: dict, top_n: int = 0) -> list[tuple[str, str, int]]: resultats = [] for chaine in chaines: @@ -64,7 +64,7 @@ def analyser_chaines(chaines, produits, composants, mineraux, seuils, top_n=None resultats.sort(key=lambda x: x["poids_total"], reverse=True) # Si top_n n'est pas spécifié, tout est retourné - if top_n is None or top_n >= len(resultats): + if top_n == 0 or top_n >= len(resultats): return resultats # Déterminer le seuil de coupure @@ -75,7 +75,7 @@ def analyser_chaines(chaines, produits, composants, mineraux, seuils, top_n=None return top_resultats -def tableau_de_bord(chains, produits, composants, mineraux, seuils): +def tableau_de_bord(chains: list[dict], produits: dict, composants: dict, mineraux: dict, seuils: dict): col_left, col_right = st.columns([2, 3], gap="small", border=True) with col_left: st.markdown("**Panneau de sélection**", unsafe_allow_html=True) @@ -139,7 +139,7 @@ def tableau_de_bord(chains, produits, composants, mineraux, seuils): couleur_A_ihh, couleur_A_isg, couleur_F_ihh, couleur_F_isg, couleur_T_ihh, couleur_T_isg,couleur_E_ihh, couleur_E_isg, couleur_M_ics, couleur_M_ivc ) -def afficher_criticites(produits, composants, mineraux, sel_prod, sel_comp, sel_miner, seuils): +def afficher_criticites(produits: dict, composants: dict, mineraux: dict, sel_prod: str, sel_comp: str, sel_miner: str, seuils: dict) -> None: with st.expander("Vue d’ensemble des criticités", expanded=True): st.markdown("## Vue d’ensemble des criticités", unsafe_allow_html=True) @@ -200,7 +200,7 @@ def afficher_criticites(produits, composants, mineraux, sel_prod, sel_comp, sel_ def afficher_explications_et_details( couleur_A, poids_A, couleur_F, poids_F, couleur_T, poids_T, couleur_E, poids_E, couleur_M, poids_M, produits, composants, mineraux, sel_prod, sel_comp, sel_miner, - couleur_A_ihh, couleur_A_isg, couleur_F_ihh, couleur_F_isg, couleur_T_ihh, couleur_T_isg,couleur_E_ihh, couleur_E_isg, couleur_M_ics, couleur_M_ivc): + couleur_A_ihh, couleur_A_isg, couleur_F_ihh, couleur_F_isg, couleur_T_ihh, couleur_T_isg,couleur_E_ihh, couleur_E_isg, couleur_M_ics, couleur_M_ivc, ui = True) -> str|None: with st.expander("Explications et détails", expanded = True): from collections import Counter couleurs = [couleur_A, couleur_F, couleur_T, couleur_E, couleur_M] @@ -209,7 +209,7 @@ def afficher_explications_et_details( nb_orange = compte["Orange"] nb_vert = compte["Vert"] - st.markdown(f""" + contenu_md = f""" Pour cette chaîne :blue-background[**{sel_prod} <-> {sel_comp} <-> {sel_miner}**], avec {nb_rouge} criticité(s) de niveau {colorer_couleurs("Rouge")}, {nb_orange} {colorer_couleurs("Orange")} et {nb_vert} {colorer_couleurs("Vert")}, les indices individuels par opération sont : * **{sel_prod} - Assemblage** : {colorer_couleurs(couleur_A)} ({poids_A}) @@ -230,31 +230,65 @@ def afficher_explications_et_details( * **{sel_miner} - Minerai** : {colorer_couleurs(couleur_M)} ({poids_M}) * ICS = {mineraux[sel_miner]["ICS"]} ({colorer_couleurs(couleur_M_ics)}) <-> IVC = {mineraux[sel_miner]["IVC"]} ({colorer_couleurs(couleur_M_ivc)}) * pondération de la Substitution dans le calcul de la criticité globale : 2 - """) + """ + contenu_md += "\n" + if ui: + st.markdown(contenu_md) + return None + else: + return contenu_md -def afficher_preconisations_et_indicateurs_generiques(niveau_criticite, poids_A, poids_F, poids_T, poids_E, poids_M): - with st.expander("Préconisations et indicateurs génériques"): - col_left, col_right = st.columns([1, 1], gap="small", border=True) - with col_left: - st.markdown("### Préconisations :\n\n") - st.markdown("Mise en œuvre : \n") - for niveau, contenu in PRECONISATIONS.items(): - if niveau in niveau_criticite: - contenu_md = f"* {colorer_couleurs(niveau)}\n" - for p in PRECONISATIONS[niveau]: - contenu_md += f" - {p}\n" - st.markdown(contenu_md) - with col_right: - st.markdown("### Indicateurs :\n\n") - st.markdown("Mise en œuvre : \n") - for niveau, contenu in INDICATEURS.items(): - if niveau in niveau_criticite: - contenu_md = f"* {colorer_couleurs(niveau)}\n" - for p in INDICATEURS[niveau]: - contenu_md += f" - {p}\n" - st.markdown(contenu_md) +def afficher_preconisations_et_indicateurs_generiques(niveau_criticite: dict, poids_A: int, poids_F: int, poids_T: int, poids_E: int, poids_M: int, ui: bool = True) -> tuple[str|None,str|None]: + contenu_md_left = "### Préconisations :\n\n" + contenu_md_left += "Mise en œuvre : \n" -def afficher_preconisations_et_indicateurs_specifiques(sel_prod, sel_comp, sel_miner, niveau_criticite_operation): + for niveau, contenu in PRECONISATIONS.items(): + if niveau in niveau_criticite: + contenu_md_left = f"* {colorer_couleurs(niveau)}\n" + for p in PRECONISATIONS[niveau]: + contenu_md_left += f" - {p}\n" + + contenu_md_right = "### Indicateurs :\n\n" + contenu_md_right += "Mise en œuvre : \n" + + for niveau, contenu in INDICATEURS.items(): + if niveau in niveau_criticite: + contenu_md_right = f"* {colorer_couleurs(niveau)}\n" + for p in INDICATEURS[niveau]: + contenu_md_right += f" - {p}\n" + + if ui: + with st.expander("Préconisations et indicateurs génériques"): + col_left, col_right = st.columns([1, 1], gap="small", border=True) + with col_left: + st.markdown(contenu_md_left) + with col_right: + st.markdown(contenu_md_right) + return None, None + else: + return contenu_md_left, contenu_md_right + +def afficher_preconisations_specifiques(operation: str, niveau_criticite_operation: dict) -> str: + contenu_md = "#### Préconisations :\n\n" + contenu_md += "Mise en œuvre : \n" + for niveau, contenu in PRECONISATIONS[operation].items(): + if niveau in niveau_criticite_operation[operation]: + contenu_md += f"* {colorer_couleurs(niveau)}\n" + for p in PRECONISATIONS[operation][niveau]: + contenu_md += f" - {p}\n" + return(contenu_md) + +def afficher_indicateurs_specifiques(operation: str, niveau_criticite_operation: dict) -> str: + contenu_md = "#### Indicateurs :\n\n" + contenu_md += "Mise en œuvre : \n" + for niveau, contenu in INDICATEURS[operation].items(): + if niveau in niveau_criticite_operation[operation]: + contenu_md += f"* {colorer_couleurs(niveau)}\n" + for p in INDICATEURS[operation][niveau]: + contenu_md += f" - {p}\n" + return(contenu_md) + +def afficher_preconisations_et_indicateurs_specifiques(sel_prod: str, sel_comp: str, sel_miner: str, niveau_criticite_operation: dict) -> None: for operation in ["Assemblage", "Fabrication", "Traitement", "Extraction"]: if operation == "Assemblage": item = sel_prod @@ -266,25 +300,11 @@ def afficher_preconisations_et_indicateurs_specifiques(sel_prod, sel_comp, sel_m st.markdown(f"### {operation} -> :blue-background[{item}]") col_left, col_right = st.columns([1, 1], gap="small", border=True) with col_left: - st.markdown("#### Préconisations :\n\n") - st.markdown("Mise en œuvre : \n") - for niveau, contenu in PRECONISATIONS[operation].items(): - if niveau in niveau_criticite_operation[operation]: - contenu_md = f"* {colorer_couleurs(niveau)}\n" - for p in PRECONISATIONS[operation][niveau]: - contenu_md += f" - {p}\n" - st.markdown(contenu_md) + st.markdown(afficher_preconisations_specifiques(operation, niveau_criticite_operation)) with col_right: - st.markdown("#### Indicateurs :\n\n") - st.markdown("Mise en œuvre : \n") - for niveau, contenu in INDICATEURS[operation].items(): - if niveau in niveau_criticite_operation[operation]: - contenu_md = f"* {colorer_couleurs(niveau)}\n" - for p in INDICATEURS[operation][niveau]: - contenu_md += f" - {p}\n" - st.markdown(contenu_md) + st.markdown(afficher_indicateurs_specifiques(operation, niveau_criticite_operation)) -def afficher_preconisations_et_indicateurs(niveau_criticite, sel_prod, sel_comp, sel_miner, poids_A, poids_F, poids_T, poids_E, poids_M): +def afficher_preconisations_et_indicateurs(niveau_criticite: dict, sel_prod: str, sel_comp: str, sel_miner: str, poids_A: int, poids_F: int, poids_T: int, poids_E: int, poids_M: int) -> None: st.markdown("## Préconisations et indicateurs") afficher_preconisations_et_indicateurs_generiques(niveau_criticite, poids_A, poids_F, poids_T, poids_E, poids_M) @@ -306,7 +326,7 @@ def afficher_preconisations_et_indicateurs(niveau_criticite, sel_prod, sel_comp, afficher_preconisations_et_indicateurs_specifiques(sel_prod, sel_comp, sel_miner, niveau_criticite_operation) -def afficher_details_operations(produits, composants, mineraux, sel_prod, sel_comp, sel_miner, details_sections): +def afficher_details_operations(produits, composants, mineraux, sel_prod, sel_comp, sel_miner, details_sections) -> None: st.markdown("## Détails des opérations") with st.expander(f"{sel_prod} et Assemblage"): @@ -332,7 +352,7 @@ def afficher_details_operations(produits, composants, mineraux, sel_prod, sel_co afficher_caracteristiques_minerai(sel_miner, mineraux[sel_miner], minerai_general) -def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"): +def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml") -> None: produits, composants, mineraux, chains, descriptions, details_sections = parse_chains_md(filepath) diff --git a/app/plan_d_action/utils/interface/export.py b/app/plan_d_action/utils/interface/export.py index 31edd24..5d105d5 100644 --- a/app/plan_d_action/utils/interface/export.py +++ b/app/plan_d_action/utils/interface/export.py @@ -1,7 +1,21 @@ +from typing import Dict, Tuple, Union, List, Set import networkx as nx -def exporter_graphe_filtre(G, liens_chemins): - """Gère l'export du graphe filtré au format DOT""" +def exporter_graphe_filtre( + G: nx.Graph, + liens_chemins: List[Tuple[Union[str, int], Union[str, int]]] +) -> nx.Graph: + """Gère l'export du graphe filtré au format DOT. + + Args: + G (nx.Graph): Le graphe d'origine à exporter. + liens_chemins (list): Liste des tuples contenant les paires de nœuds reliées + par un chemin dans le graphe, avec leurs attributs associés. + + Returns: + tuple: Un tuple contenant le graphe exporté sous forme de DiGraph + et le dictionnaire des attributs du graphe exporté. + """ G_export = nx.DiGraph() for u, v in liens_chemins: @@ -17,8 +31,26 @@ def exporter_graphe_filtre(G, liens_chemins): return(G_export) -def extraire_liens_filtres(chemins, niveaux, niveau_depart, niveau_arrivee, niveaux_speciaux): - """Extrait les liens des chemins en respectant les niveaux""" +def extraire_liens_filtres( + chemins: List[List[Union[str, int]]], + niveaux: Dict[str | int, int], + niveau_depart: int, + niveau_arrivee: int, + niveaux_speciaux: list[int] +) -> List[Tuple[Union[str, int], Union[str, int]]]: + """Extrait les liens des chemins en respectant les niveaux. + + Args: + chemins (list): Liste des chemins dans le graphe. + niveaux (dict): Dictionnaire associant chaque nœud au niveau correspondant. + niveau_depart (int): Niveau de départ pour la sélection des liens. + niveau_arrivee (int): Niveau d'arrivée pour la sélection des liens. + niveaux_speciaux (set): Ensemble des niveaux spéciaux à considérer dans le filtrage. + + Returns: + set: Ensemble des paires de nœuds constituant les liens du graphe filtré + en respectant les niveaux et les niveaux spéciaux demandés. + """ liens = set() for chemin in chemins: for i in range(len(chemin) - 1): diff --git a/app/plan_d_action/utils/interface/niveau_utils.py b/app/plan_d_action/utils/interface/niveau_utils.py index 8cba66b..39cd8f8 100644 --- a/app/plan_d_action/utils/interface/niveau_utils.py +++ b/app/plan_d_action/utils/interface/niveau_utils.py @@ -1,5 +1,16 @@ -def extraire_niveaux(G): - """Extrait les niveaux des nœuds du graphe""" +from typing import Dict +import networkx as nx + +def extraire_niveaux(G: nx.Graph) -> Dict[str | int, int]: + """Extrait les niveaux des nœuds du graphe. + + Args: + G (nx.Graph): Le graphe d'origine à analyser. + + Returns: + dict: Un dictionnaire associant chaque nœud au niveau correspondant. + Les valeurs sont des entiers représentant les niveaux. + """ niveaux = {} for node, attrs in G.nodes(data=True): niveau_str = attrs.get("niveau") diff --git a/app/plan_d_action/utils/interface/parser.py b/app/plan_d_action/utils/interface/parser.py index ffce8e3..2aa419f 100644 --- a/app/plan_d_action/utils/interface/parser.py +++ b/app/plan_d_action/utils/interface/parser.py @@ -1,5 +1,17 @@ -def preparer_graphe(G): - """Nettoie et prépare le graphe pour l'analyse.""" +from typing import Dict, Tuple, Union +import networkx as nx + +def preparer_graphe(G: nx.Graph) -> Tuple[nx.Graph, Dict[Union[str, int], int]]: + """Nettoie et prépare le graphe pour l'analyse. + + Args: + G (nx.Graph): Le graphe d'origine à nettoyer. + + Returns: + tuple: Un tuple contenant le graphe nettoyé et les niveaux temporels associés + aux nœuds du graphe. Le graphe nettoyé a eu ses nœuds qui ne respectaient + pas les critères d'admissibilité enlevés. + """ niveaux_temp = { node: int(str(attrs.get("niveau")).strip('"')) for node, attrs in G.nodes(data=True) diff --git a/app/plan_d_action/utils/interface/selection.py b/app/plan_d_action/utils/interface/selection.py index 544ac37..3c2b62f 100644 --- a/app/plan_d_action/utils/interface/selection.py +++ b/app/plan_d_action/utils/interface/selection.py @@ -1,3 +1,4 @@ +from typing import Any, Dict, Tuple, List, Union, Optional import streamlit as st import networkx as nx from utils.translations import _ @@ -7,8 +8,16 @@ from utils.graph_utils import ( extraire_chemins_vers ) -def selectionner_minerais(G, noeuds_depart): - """Interface pour sélectionner les minerais si nécessaire.""" +def selectionner_minerais(G: nx.Graph, noeuds_depart: List[Any]) -> List[Union[str, int]]: + """Interface pour sélectionner les minerais si nécessaire. + + Args: + G (nx.Graph): Le graphe des relations entre les nœuds. + noeuds_depart (list): Les nœuds de départ qui doivent être considérés. + + Returns: + list: La liste des nœuds sélectionnés comme minerais. + """ minerais_selection = None st.markdown(f"## {str(_('pages.plan_d_action.select_minerals'))}") @@ -32,9 +41,21 @@ def selectionner_minerais(G, noeuds_depart): return minerais_selection +def selectionner_noeuds( + G: nx.Graph, + niveaux_temp: Dict[Union[str, int], int], + niveau_depart: int +) -> Tuple[Optional[List[Union[str, int]]], List[Union[str, int]]]: + """Interface pour sélectionner les nœuds spécifiques de départ et d'arrivée. -def selectionner_noeuds(G, niveaux_temp, niveau_depart): - """Interface pour sélectionner les nœuds spécifiques de départ et d'arrivée.""" + Args: + G (nx.Graph): Le graphe des relations entre les nœuds. + niveaux_temp (dict): Dictionnaire contenant les niveaux des nœuds. + niveau_depart (int): Niveau à partir duquel commencer la sélection. + + Returns: + tuple: La paire de départ et d'arrivée des nœuds sélectionnés. + """ st.markdown("---") st.markdown(f"## {str(_('pages.plan_d_action.fine_selection'))}") @@ -49,8 +70,27 @@ def selectionner_noeuds(G, niveaux_temp, niveau_depart): return noeuds_depart, noeuds_arrivee -def extraire_chemins_selon_criteres(G, niveaux, niveau_depart, noeuds_depart, noeuds_arrivee, minerais): - """Extrait les chemins selon les critères spécifiés""" +def extraire_chemins_selon_criteres( + G: nx.Graph, + niveaux: Dict[str | int, int], + niveau_depart: int, + noeuds_depart: Optional[List[Union[str, int]]], + noeuds_arrivee: List[Union[str, int]], + minerais: Optional[List[Union[str, int]]] +) -> List[List[str | int]]: + """Extrait les chemins selon les critères spécifiés. + + Args: + G (nx.Graph): Le graphe des relations entre les nœuds. + niveaux (dict): Dictionnaire contenant les niveaux des nœuds. + niveau_depart (int): Niveau à partir duquel commencer la sélection. + noeuds_depart (list, optional): Les nœuds de départ qui doivent être considérés. + noeuds_arrivee (list): Les nœuds d'arrivée qui doivent être inclus dans les chemins. + minerais (list, optional): La liste des nœuds sélectionnés comme minerais. + + Returns: + list: Liste des chemins trouvés selon les critères spécifiés. + """ chemins = [] if noeuds_depart and noeuds_arrivee: for nd in noeuds_depart: diff --git a/app/plan_d_action/utils/interface/visualization.py b/app/plan_d_action/utils/interface/visualization.py index f02e070..b6b88e6 100644 --- a/app/plan_d_action/utils/interface/visualization.py +++ b/app/plan_d_action/utils/interface/visualization.py @@ -1,7 +1,22 @@ +from typing import Dict, Optional import re from app.plan_d_action.utils.interface import CORRESPONDANCE_COULEURS -def remplacer_par_badge(markdown_text, correspondance=CORRESPONDANCE_COULEURS): +def remplacer_par_badge( + markdown_text: str, + correspondance: Optional[Dict[str, str]] = CORRESPONDANCE_COULEURS +) -> str: + """Remplace certains mots par des badges colorés dans un texte Markdown. + + Args: + markdown_text (str): Le texte Markdown à modifier. + correspondance (dict, optional): Dictionnaire qui mappe les mots + à remplacer vers les couleurs de leurs badges. Si None, utilise + CORRESPONDANCE_COULEURS par défaut. + + Returns: + str: Le texte Markdown modifié avec des badges ajoutés. + """ # Échappe les mots à remplacer s'ils contiennent des accents ou espaces for mot, couleur in correspondance.items(): # Utilise des bords de mots (\b) pour éviter les remplacements partiels diff --git a/app/plan_d_action/utils/jobs/f7e9ba2e.md b/app/plan_d_action/utils/jobs/f7e9ba2e.md index e6276d9..304f787 100644 --- a/app/plan_d_action/utils/jobs/f7e9ba2e.md +++ b/app/plan_d_action/utils/jobs/f7e9ba2e.md @@ -3366,7 +3366,7 @@ Le hafnium est un métal de transition rare, gris-argenté, ductile et lustré, | SSDM2 | 0.80 | 0.80 | 0.80 | 0.80 | | StockageEMMC | 0.80 | 0.80 | 0.80 | 0.80 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -3550,7 +3550,7 @@ Le cuivre est un métal de transition rouge-brun, malléable et ductile, connu p | CarteMere | 0.81 | 0.90 | 0.80 | 0.70 | | Connecteurs | 0.81 | 0.90 | 0.80 | 0.70 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -3770,7 +3770,7 @@ Le germanium est un métalloïde gris-blanc, élément numéro 32 du tableau pé | ProcesseurASIC | 0.64 | 0.70 | 0.60 | 0.60 | | ProcesseurX86 | 0.64 | 0.70 | 0.60 | 0.60 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -3978,7 +3978,7 @@ Le silicium constitue un matériau stratégique pour de nombreux secteurs indust | SSDM2 | 0.90 | 0.90 | 0.90 | 0.90 | | StockageEMMC | 0.90 | 0.90 | 0.90 | 0.90 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -4184,7 +4184,7 @@ Le palladium n'existe pas à l'état natif dans la nature mais se trouve princip | ProcesseurARM | 0.50 | 0.50 | 0.40 | 0.60 | | ProcesseurX86 | 0.50 | 0.50 | 0.40 | 0.60 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -4385,7 +4385,7 @@ Le phosphore est un élément chimique non métallique, essentiel à toute forme | ProcesseurASIC | 0.50 | 0.50 | 0.40 | 0.60 | | ProcesseurX86 | 0.50 | 0.50 | 0.40 | 0.60 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -4597,7 +4597,7 @@ L'antimoine est un métalloïde blanc-argenté, cristallin et cassant, qui prés | ProcesseurASIC | 0.60 | 0.60 | 0.50 | 0.70 | | ProcesseurX86 | 0.60 | 0.60 | 0.50 | 0.70 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -4800,7 +4800,7 @@ Le tantale est un métal de transition rare, gris-bleu, dense et réfractaire, d | SSDM2 | 0.70 | 0.70 | 0.70 | 0.70 | | StockageEMMC | 0.64 | 0.70 | 0.60 | 0.60 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -4988,7 +4988,7 @@ L'argent est un métal précieux qui joue un rôle essentiel mais discret dans l | CarteMere | 0.61 | 0.70 | 0.50 | 0.60 | | Connecteurs | 0.61 | 0.70 | 0.50 | 0.60 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -5186,7 +5186,7 @@ L'étain est un métal gris-argent, malléable, moyennement ductile à températ | CarteMere | 0.60 | 0.60 | 0.60 | 0.60 | | Connecteurs | 0.60 | 0.60 | 0.60 | 0.60 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -5382,7 +5382,7 @@ Le lithium est un métal alcalin léger, blanc-argenté, qui se caractérise par | :-- | :--: | :--: | :--: | :--: | | Batterie | 0.51 | 0.60 | 0.50 | 0.40 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -5589,7 +5589,7 @@ Le nickel est un métal de transition gris-argenté, ferromagnétique, prisé po | Connecteurs | 0.50 | 0.50 | 0.40 | 0.60 | | Batterie | 0.44 | 0.50 | 0.40 | 0.40 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -5810,7 +5810,7 @@ Le gallium est un métal rare aux propriétés physico-chimiques remarquables, d | EcranSpecifique | 0.41 | 0.50 | 0.40 | 0.30 | | CreusetGraphite | 0.37 | 0.40 | 0.30 | 0.40 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -6005,7 +6005,7 @@ Le lanthane est un métal de transition appartenant à la famille des terres rar | Camera | 0.64 | 0.70 | 0.60 | 0.60 | | Batterie | 0.54 | 0.60 | 0.50 | 0.50 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -6196,7 +6196,7 @@ Le graphite existe sous deux formes principales : naturel (extrait de gisements | Batterie | 0.51 | 0.60 | 0.50 | 0.40 | | CreusetGraphite | 0.44 | 0.50 | 0.30 | 0.50 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -6396,7 +6396,7 @@ La demande mondiale continue d'être soutenue par le secteur de la galvanisation | Batterie | 0.30 | 0.30 | 0.20 | 0.40 | | Boitier | 0.30 | 0.30 | 0.20 | 0.40 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -6599,7 +6599,7 @@ Le cobalt est un métal de transition gris, brillant et ferromagnétique, décou | :-- | :--: | :--: | :--: | :--: | | Batterie | 0.57 | 0.60 | 0.60 | 0.50 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -6797,7 +6797,7 @@ Le manganèse est un métal de transition gris-argenté, dur et cassant, caract | Batterie | 0.40 | 0.40 | 0.30 | 0.50 | | Boitier | 0.40 | 0.40 | 0.30 | 0.50 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -7004,7 +7004,7 @@ Malgré sa rareté (production mondiale de quelques centaines de tonnes par an), | Capteurs | 0.70 | 0.70 | 0.70 | 0.70 | | DisqueDur | 0.64 | 0.70 | 0.60 | 0.60 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -7193,7 +7193,7 @@ Le titane est un métal de transition léger, résistant et de couleur gris arge | :-- | :--: | :--: | :--: | :--: | | Boitier | 0.67 | 0.70 | 0.60 | 0.70 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -7386,7 +7386,7 @@ Le scandium est un métal de transition léger appartenant au groupe IIIB du tab | ProcesseurASIC | 0.70 | 0.70 | 0.70 | 0.70 | | ProcesseurX86 | 0.70 | 0.70 | 0.70 | 0.70 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -7569,7 +7569,7 @@ Le chrome est un métal de transition de numéro atomique 24, symbole Cr, caract | :-- | :--: | :--: | :--: | :--: | | Boitier | 0.39 | 0.30 | 0.40 | 0.50 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -7759,7 +7759,7 @@ Le magnésium est un métal alcalino-terreux léger, blanc argenté, qui présen | :-- | :--: | :--: | :--: | :--: | | Boitier | 0.50 | 0.50 | 0.40 | 0.60 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -7966,7 +7966,7 @@ Le cérium est un métal lanthanide gris-argenté, malléable et ductile, décou | EcranLCD | 0.70 | 0.70 | 0.70 | 0.70 | | EcranOLED | 0.64 | 0.70 | 0.60 | 0.60 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -8148,7 +8148,7 @@ L'holmium est un métal de terre rare appartenant à la famille des lanthanides, | Camera | 0.84 | 0.90 | 0.80 | 0.80 | | Capteurs | 0.84 | 0.90 | 0.80 | 0.80 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -8333,7 +8333,7 @@ L'europium est un métal de la série des lanthanides, découvert en 1901 par Eu | EcranLCD | 0.81 | 0.90 | 0.80 | 0.70 | | EcranMiniLED | 0.81 | 0.90 | 0.80 | 0.70 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -8515,7 +8515,7 @@ Le terbium est un élément métallique du groupe des lanthanides, découvert en | EcranLCD | 0.81 | 0.90 | 0.80 | 0.70 | | EcranMiniLED | 0.81 | 0.90 | 0.80 | 0.70 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -8703,7 +8703,7 @@ L'yttrium est un métal de transition du groupe 3, souvent classé parmi les ter | EcranMiniLED | 0.74 | 0.80 | 0.70 | 0.70 | | EcranOLED | 0.70 | 0.70 | 0.70 | 0.70 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -8888,7 +8888,7 @@ Le béryllium est un métal alcalino-terreux léger, dur et fragile, découvert | Connecteurs | 0.64 | 0.70 | 0.60 | 0.60 | | Connectivite | 0.64 | 0.70 | 0.60 | 0.60 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -9069,7 +9069,7 @@ Le secteur technologique émerge comme nouveau pilier de croissance (+7% en 2024 | ProcesseurASIC | 0.60 | 0.60 | 0.60 | 0.60 | | ProcesseurX86 | 0.60 | 0.60 | 0.60 | 0.60 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -9258,7 +9258,7 @@ Le quartz ultra-pur 5N représente l'une des matières premières les plus criti | :-- | :--: | :--: | :--: | :--: | | CreusetQuartz | 0.74 | 0.80 | 0.70 | 0.70 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -9452,7 +9452,7 @@ Principalement utilisé dans la fabrication de carbures cémentés (50% des usag | ProcesseurASIC | 0.60 | 0.60 | 0.50 | 0.70 | | ProcesseurX86 | 0.60 | 0.60 | 0.50 | 0.70 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -9652,7 +9652,7 @@ Le samarium est un métal des terres rares du groupe des lanthanides, caractéri | Capteurs | 0.74 | 0.80 | 0.70 | 0.70 | | Connectivite | 0.64 | 0.70 | 0.60 | 0.60 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -9840,7 +9840,7 @@ Le gadolinium est un métal rare, blanc-argenté, appartenant à la famille des | :-- | :--: | :--: | :--: | :--: | | Capteurs | 0.74 | 0.80 | 0.70 | 0.70 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -10025,7 +10025,7 @@ L'erbium est un métal de transition appartenant au groupe des terres rares, dé | :-- | :--: | :--: | :--: | :--: | | Connectivite | 0.74 | 0.80 | 0.70 | 0.70 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -10212,7 +10212,7 @@ Le dysprosium est un métal lanthanide rare de couleur blanc-argenté, découver | :-- | :--: | :--: | :--: | :--: | | Audio | 0.70 | 0.70 | 0.70 | 0.70 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -10391,7 +10391,7 @@ Le néodyme est un métal de transition appartenant à la famille des lanthanide | :-- | :--: | :--: | :--: | :--: | | Audio | 0.47 | 0.50 | 0.50 | 0.40 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | @@ -10585,7 +10585,7 @@ Le praséodyme est un métal de la famille des lanthanides (terres rares), déco | :-- | :--: | :--: | :--: | :--: | | Audio | 0.41 | 0.50 | 0.40 | 0.30 | -##### Valeurs d'ICS par composant +##### Valeurs d'ICS par composant concerné | Composant | ICS | Criticité | | :-- | :-- | :-- | diff --git a/batch_ia/utils/sections.py b/batch_ia/utils/sections.py index cf064f8..751da48 100644 --- a/batch_ia/utils/sections.py +++ b/batch_ia/utils/sections.py @@ -400,7 +400,7 @@ def generate_minerals_section(data, results, config): ics_average = sum(ics_values) / len(ics_values) color, suffix = determine_threshold_color(ics_average, "ICS", config.get('thresholds')) - template.append("##### Valeurs d'ICS par composant\n") + template.append("##### Valeurs d'ICS par composant concerné\n") template.append("| Composant | ICS | Criticité |") template.append("| :-- | :-- | :-- |")