Améliorations et corrections
This commit is contained in:
parent
d47e8608cc
commit
69272a44d6
@ -77,12 +77,17 @@ L'application utilise quatre indices clés pour évaluer les vulnérabilités da
|
|||||||
L'application est organisée en quatre onglets principaux, chacun offrant une perspective différente sur la chaîne de fabrication numérique :
|
L'application est organisée en quatre onglets principaux, chacun offrant une perspective différente sur la chaîne de fabrication numérique :
|
||||||
|
|
||||||
* Onglet Personnalisation : Créer et gérer des produits finaux personnalisés pour des analyses spécifiques.
|
* Onglet Personnalisation : Créer et gérer des produits finaux personnalisés pour des analyses spécifiques.
|
||||||
* À noter : Les produits personnalisés sont temporaires par défaut, mais peuvent être sauvegardés pour une utilisation ultérieure.
|
* À noter : Les produits personnalisés sont temporaires par défaut, mais peuvent être sauvegardés pour une utilisation ultérieure.
|
||||||
* Onglet Analyse : Explorer visuellement les relations entre les différents niveaux de la chaîne de fabrication.
|
* Onglet Analyse : Explorer visuellement les relations entre les différents niveaux de la chaîne de fabrication.
|
||||||
* Exemple d'utilisation : Pour comprendre les vulnérabilités liées aux composants d'un smartphone, sélectionnez « Produit final » comme niveau de départ, « Composant » comme niveau d'arrivée, puis spécifiez « Smartphone » comme item de produit final.
|
* Exemple d'utilisation : Pour comprendre les vulnérabilités liées aux composants d'un smartphone, sélectionnez « Produit final » comme niveau de départ, « Composant » comme niveau d'arrivée, puis spécifiez « Smartphone » comme item de produit final.
|
||||||
|
* Onglet IA'nalyse : Obtenez un rapport synthétique circonstancié d'une partie du schéma global.
|
||||||
|
* Cet onglet n'est accessible qu'aux personnes diposant d'un compte.
|
||||||
|
* Onglet Plan d'action : Visualiser toutes les criticités d'une chaîne Produit final <-> Composant <-> Minerai.
|
||||||
|
* À partir d'une sélection, toutes les chaînes critiques sont examinées à la loupe.
|
||||||
|
* Des propositions d'actions et d'indicateurs sont fournies selon les opérations et leur niveau de criticité.
|
||||||
* Onglet Visualisations : Observer les corrélations entre les différents indices et comprendre les tendances globales.
|
* Onglet Visualisations : Observer les corrélations entre les différents indices et comprendre les tendances globales.
|
||||||
* Indicateurs clés : Portez attention aux points situés dans les zones de haute valeur pour les deux indices, car ils représentent les vulnérabilités les plus critiques.
|
* Indicateurs clés : Portez attention aux points situés dans les zones de haute valeur pour les deux indices, car ils représentent les vulnérabilités les plus critiques.
|
||||||
* Onglet Fiches : Accéder à des informations détaillées sur chaque opération et minerai.
|
* Onglet Fiches : Accéder à des informations détaillées sur chaque opération et minerai.
|
||||||
* À explorer : Les fiches contiennent souvent des informations qui ne sont pas visibles directement dans les graphiques, comme des tendances historiques ou des prévisions futures ; n'hésitez pas à les consulter
|
* À explorer : Les fiches contiennent souvent des informations qui ne sont pas visibles directement dans les graphiques, comme des tendances historiques ou des prévisions futures ; n'hésitez pas à les consulter
|
||||||
|
|
||||||
En début de chacun des onglets, vous trouverez un mini-guide spécifique sur leur utilisation.
|
En début de chacun des onglets, vous trouverez un mini-guide spécifique sur leur utilisation.
|
||||||
|
|||||||
@ -148,7 +148,7 @@ def interface_analyse(G_temp):
|
|||||||
|
|
||||||
# Lancement de l'analyse
|
# Lancement de l'analyse
|
||||||
st.markdown("---")
|
st.markdown("---")
|
||||||
if st.button(str(_("pages.analyse.run_analysis")), type="primary", key="analyse_lancer"):
|
if st.button(str(_("pages.analyse.run_analysis")), type="primary", key="analyse_lancer", icon=":material/graph_4:"):
|
||||||
afficher_sankey(
|
afficher_sankey(
|
||||||
G_temp,
|
G_temp,
|
||||||
niveau_depart=niveau_depart,
|
niveau_depart=niveau_depart,
|
||||||
|
|||||||
@ -4,7 +4,7 @@ from utils.translations import get_translation as _
|
|||||||
|
|
||||||
def importer_exporter_graph(G):
|
def importer_exporter_graph(G):
|
||||||
st.markdown(f"## {_('pages.personnalisation.save_restore_config')}")
|
st.markdown(f"## {_('pages.personnalisation.save_restore_config')}")
|
||||||
if st.button(str(_("pages.personnalisation.export_config"))):
|
if st.button(str(_("pages.personnalisation.export_config")), icon=":material/save:"):
|
||||||
nodes = [n for n, d in G.nodes(data=True) if d.get("personnalisation") == "oui"]
|
nodes = [n for n, d in G.nodes(data=True) if d.get("personnalisation") == "oui"]
|
||||||
edges = [(u, v) for u, v in G.edges() if u in nodes]
|
edges = [(u, v) for u, v in G.edges() if u in nodes]
|
||||||
conf = {"nodes": nodes, "edges": edges}
|
conf = {"nodes": nodes, "edges": edges}
|
||||||
@ -13,7 +13,8 @@ def importer_exporter_graph(G):
|
|||||||
label=str(_("pages.personnalisation.download_json")),
|
label=str(_("pages.personnalisation.download_json")),
|
||||||
data=json_str,
|
data=json_str,
|
||||||
file_name="config_personnalisation.json",
|
file_name="config_personnalisation.json",
|
||||||
mime="application/json"
|
mime="application/json",
|
||||||
|
icon=":material/save:"
|
||||||
)
|
)
|
||||||
|
|
||||||
uploaded = st.file_uploader(str(_("pages.personnalisation.import_config")), type=["json"])
|
uploaded = st.file_uploader(str(_("pages.personnalisation.import_config")), type=["json"])
|
||||||
@ -37,7 +38,7 @@ def importer_exporter_graph(G):
|
|||||||
key="restaurer_selection"
|
key="restaurer_selection"
|
||||||
)
|
)
|
||||||
|
|
||||||
if st.button(str(_("pages.personnalisation.restore_selected")), type="primary"):
|
if st.button(str(_("pages.personnalisation.restore_selected")), type="primary", icon=":material/history:"):
|
||||||
for node in sel_nodes:
|
for node in sel_nodes:
|
||||||
if not G.has_node(node):
|
if not G.has_node(node):
|
||||||
G.add_node(node, niveau="0", personnalisation="oui", label=node)
|
G.add_node(node, niveau="0", personnalisation="oui", label=node)
|
||||||
|
|||||||
2
app/plan_d_action/__init__.py
Normal file
2
app/plan_d_action/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# __init__.py – app/fiches
|
||||||
|
from .interface import interface_plan_d_action
|
||||||
@ -21,7 +21,7 @@ from batch_ia import (
|
|||||||
generate_report,
|
generate_report,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .plan_d_actions import initialiser_interface
|
from .plan_d_action import initialiser_interface
|
||||||
|
|
||||||
from utils.graph_utils import (
|
from utils.graph_utils import (
|
||||||
extraire_chemins_depuis,
|
extraire_chemins_depuis,
|
||||||
@ -33,9 +33,9 @@ from pathlib import Path
|
|||||||
# Répertoire courant du script
|
# Répertoire courant du script
|
||||||
CURRENT_DIR = Path(__file__).resolve().parent
|
CURRENT_DIR = Path(__file__).resolve().parent
|
||||||
|
|
||||||
# Répertoire "jobs" dans app/plan_d_actions
|
# Répertoire "jobs" dans app/plan_d_action
|
||||||
JOBS = CURRENT_DIR / "jobs"
|
JOBS = CURRENT_DIR / "jobs"
|
||||||
JOBS.mkdir(parents=True, exist_ok=True)
|
JOBS.mkdir(exist_ok=True)
|
||||||
|
|
||||||
niveau_labels = {
|
niveau_labels = {
|
||||||
0: "Produit final",
|
0: "Produit final",
|
||||||
@ -66,7 +66,7 @@ def selectionner_minerais(G, noeuds_depart):
|
|||||||
"""Interface pour sélectionner les minerais si nécessaire."""
|
"""Interface pour sélectionner les minerais si nécessaire."""
|
||||||
minerais_selection = None
|
minerais_selection = None
|
||||||
|
|
||||||
st.markdown(f"## {str(_('pages.plan_d_actions.select_minerals'))}")
|
st.markdown(f"## {str(_('pages.plan_d_action.select_minerals'))}")
|
||||||
|
|
||||||
# Étape 1 : récupérer tous les nœuds descendants depuis les produits finaux
|
# Étape 1 : récupérer tous les nœuds descendants depuis les produits finaux
|
||||||
descendants = set()
|
descendants = set()
|
||||||
@ -80,7 +80,7 @@ def selectionner_minerais(G, noeuds_depart):
|
|||||||
])
|
])
|
||||||
|
|
||||||
minerais_selection = st.multiselect(
|
minerais_selection = st.multiselect(
|
||||||
str(_("pages.plan_d_actions.filter_by_minerals")),
|
str(_("pages.plan_d_action.filter_by_minerals")),
|
||||||
minerais_nodes,
|
minerais_nodes,
|
||||||
key="analyse_minerais"
|
key="analyse_minerais"
|
||||||
)
|
)
|
||||||
@ -91,12 +91,12 @@ def selectionner_minerais(G, noeuds_depart):
|
|||||||
def selectionner_noeuds(G, niveaux_temp, niveau_depart):
|
def selectionner_noeuds(G, niveaux_temp, niveau_depart):
|
||||||
"""Interface pour sélectionner les nœuds spécifiques de départ et d'arrivée."""
|
"""Interface pour sélectionner les nœuds spécifiques de départ et d'arrivée."""
|
||||||
st.markdown("---")
|
st.markdown("---")
|
||||||
st.markdown(f"## {str(_('pages.plan_d_actions.fine_selection'))}")
|
st.markdown(f"## {str(_('pages.plan_d_action.fine_selection'))}")
|
||||||
|
|
||||||
depart_nodes = [n for n in G.nodes() if niveaux_temp.get(n) == niveau_depart]
|
depart_nodes = [n for n in G.nodes() if niveaux_temp.get(n) == niveau_depart]
|
||||||
noeuds_arrivee = [n for n in G.nodes() if niveaux_temp.get(n) == 99]
|
noeuds_arrivee = [n for n in G.nodes() if niveaux_temp.get(n) == 99]
|
||||||
|
|
||||||
noeuds_depart = st.multiselect(str(_("pages.plan_d_actions.filter_start_nodes")),
|
noeuds_depart = st.multiselect(str(_("pages.plan_d_action.filter_start_nodes")),
|
||||||
sorted(depart_nodes),
|
sorted(depart_nodes),
|
||||||
key="analyse_noeuds_depart")
|
key="analyse_noeuds_depart")
|
||||||
|
|
||||||
@ -169,11 +169,11 @@ def extraire_liens_filtres(chemins, niveaux, niveau_depart, niveau_arrivee, nive
|
|||||||
liens.add((u, v))
|
liens.add((u, v))
|
||||||
return liens
|
return liens
|
||||||
|
|
||||||
def interface_plan_d_actions(G_temp):
|
def interface_plan_d_action(G_temp):
|
||||||
st.markdown(f"# {str(_('pages.plan_d_actions.title'))}")
|
st.markdown(f"# {str(_('pages.plan_d_action.title'))}")
|
||||||
|
|
||||||
if "plan_d_actions" not in st.session_state:
|
if "plan_d_action" not in st.session_state:
|
||||||
st.session_state["plan_d_actions"] = 0
|
st.session_state["plan_d_action"] = 0
|
||||||
if "g_md_done" not in st.session_state:
|
if "g_md_done" not in st.session_state:
|
||||||
st.session_state["g_md_done"] = False
|
st.session_state["g_md_done"] = False
|
||||||
if "uuid" not in st.session_state:
|
if "uuid" not in st.session_state:
|
||||||
@ -181,8 +181,8 @@ def interface_plan_d_actions(G_temp):
|
|||||||
st.session_state["G_dot"] = f"{JOBS}/{st.session_state["uuid"]}.dot"
|
st.session_state["G_dot"] = f"{JOBS}/{st.session_state["uuid"]}.dot"
|
||||||
st.session_state["G_md"] = f"{JOBS}/{st.session_state["uuid"]}.md"
|
st.session_state["G_md"] = f"{JOBS}/{st.session_state["uuid"]}.md"
|
||||||
|
|
||||||
if st.session_state["plan_d_actions"] == 0:
|
if st.session_state["plan_d_action"] == 0:
|
||||||
html_expander(f"{str(_('pages.plan_d_actions.help'))}", content="\n".join(_("pages.plan_d_actions.help_content")), open_by_default=False, details_class="details_introduction")
|
html_expander(f"{str(_('pages.plan_d_action.help'))}", content="\n".join(_("pages.plan_d_action.help_content")), open_by_default=False, details_class="details_introduction")
|
||||||
# Préparation du graphe
|
# Préparation du graphe
|
||||||
G_temp, niveaux_temp = preparer_graphe(G_temp)
|
G_temp, niveaux_temp = preparer_graphe(G_temp)
|
||||||
|
|
||||||
@ -208,13 +208,13 @@ def interface_plan_d_actions(G_temp):
|
|||||||
G_final = exporter_graphe_filtre(G_temp, liens_chemins)
|
G_final = exporter_graphe_filtre(G_temp, liens_chemins)
|
||||||
st.session_state["G_final"] = G_final
|
st.session_state["G_final"] = G_final
|
||||||
# formulaire ou sélection
|
# formulaire ou sélection
|
||||||
if st.button(str(_("pages.plan_d_actions.submit_request"))):
|
if st.button(str(_("pages.plan_d_action.submit_request")), icon=":material/play_arrow:"):
|
||||||
# On déclenche la suite — mais on NE traite rien maintenant
|
# On déclenche la suite — mais on NE traite rien maintenant
|
||||||
st.session_state["plan_d_actions"] = 1
|
st.session_state["plan_d_action"] = 1
|
||||||
st.rerun() # force la réexécution immédiatement avec état mis à jour
|
st.rerun() # force la réexécution immédiatement avec état mis à jour
|
||||||
|
|
||||||
|
|
||||||
elif st.session_state["plan_d_actions"] == 1:
|
elif st.session_state["plan_d_action"] == 1:
|
||||||
# Traitement lourd une seule fois
|
# Traitement lourd une seule fois
|
||||||
if not st.session_state["g_md_done"]:
|
if not st.session_state["g_md_done"]:
|
||||||
write_dot(st.session_state["G_final"], st.session_state["G_dot"])
|
write_dot(st.session_state["G_final"], st.session_state["G_dot"])
|
||||||
@ -228,8 +228,8 @@ def interface_plan_d_actions(G_temp):
|
|||||||
|
|
||||||
# Affichage de l’interface Streamlit
|
# Affichage de l’interface Streamlit
|
||||||
initialiser_interface(st.session_state["G_md"])
|
initialiser_interface(st.session_state["G_md"])
|
||||||
if (st.button("Réinitialiser")):
|
if (st.button("Réinitialiser", icon=":material/refresh:")):
|
||||||
st.session_state["plan_d_actions"] = 0
|
st.session_state["plan_d_action"] = 0
|
||||||
st.session_state["g_md_done"] = False
|
st.session_state["g_md_done"] = False
|
||||||
for f in JOBS.glob(f"*{st.session_state["uuid"]}*"):
|
for f in JOBS.glob(f"*{st.session_state["uuid"]}*"):
|
||||||
if f.is_file():
|
if f.is_file():
|
||||||
@ -40,24 +40,29 @@ PRECONISATIONS = {
|
|||||||
'Facile': [
|
'Facile': [
|
||||||
"Sécuriser un stock tampon sur site (90 jours).",
|
"Sécuriser un stock tampon sur site (90 jours).",
|
||||||
"Faire certifier la traçabilité chimique du concentré."
|
"Faire certifier la traçabilité chimique du concentré."
|
||||||
|
|
||||||
],
|
],
|
||||||
'Modérée': [
|
'Modérée': [
|
||||||
"Valider un second affineur dans une région politiquement stable.",
|
"Valider un second affineur dans une région politiquement stable.",
|
||||||
"Imposer des clauses « force-majeure » limitant l’arrêt total à 48 h."
|
"Imposer des clauses « force-majeure » limitant l’arrêt total à 48 h.",
|
||||||
|
"Explorer les possibilités de recyclage et d'économie circulaire"
|
||||||
],
|
],
|
||||||
'Difficile': [
|
'Difficile': [
|
||||||
"Co-développer un site de raffinage dans une zone « friend-shore ».",
|
"Co-développer un site de raffinage dans une zone « friend-shore ».",
|
||||||
"Financer un procédé de purification à rendement plus élevé (réduit la dépendance au minerai primaire)."
|
"Financer un procédé de purification à rendement plus élevé (réduit la dépendance au minerai primaire).",
|
||||||
|
"Constituer des réserves stratégiques pour les périodes de tension"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
'Fabrication': {
|
'Fabrication': {
|
||||||
'Facile': [
|
'Facile': [
|
||||||
"Mettre un seuil minimal de sécurité (45 jours) sur le composant critique en usine SMT.",
|
"Mettre un seuil minimal de sécurité (45 jours) sur le composant critique en usine SMT.",
|
||||||
"Suivre hebdomadairement la capacité libre des fondeurs/EMS."
|
"Suivre hebdomadairement la capacité libre des fondeurs/EMS.",
|
||||||
|
"Maintenir une veille technologique sur les évolutions du marché"
|
||||||
],
|
],
|
||||||
'Modérée': [
|
'Modérée': [
|
||||||
"Dual-sourcer le composant critique intégrant un minerai critique (au moins 30 % chez un second fondeur).",
|
"Dual-sourcer le composant critique intégrant un minerai critique (au moins 30 % chez un second fondeur).",
|
||||||
"Déployer le « design-for-substitution » : même PCB compatible avec le composant concerné."
|
"Déployer le « design-for-substitution » : même PCB compatible avec le composant concerné.",
|
||||||
|
"Optimiser les processus d'approvisionnement existants"
|
||||||
],
|
],
|
||||||
'Difficile': [
|
'Difficile': [
|
||||||
"Lancer un programme R&D de substitution ou d'alternative budgeté sur 3 ans.",
|
"Lancer un programme R&D de substitution ou d'alternative budgeté sur 3 ans.",
|
||||||
@ -75,7 +80,8 @@ PRECONISATIONS = {
|
|||||||
],
|
],
|
||||||
'Difficile': [
|
'Difficile': [
|
||||||
"Investir dans une plateforme d’assemblage flexible (robots modulaires) capable de basculer vers un composant de substitution en < 72 h.",
|
"Investir dans une plateforme d’assemblage flexible (robots modulaires) capable de basculer vers un composant de substitution en < 72 h.",
|
||||||
"Signer un accord gouvernemental pour un soutien logistique prioritaire (corridor aérien dédié) en cas de crise géopolitique."
|
"Signer un accord gouvernemental pour un soutien logistique prioritaire (corridor aérien dédié) en cas de crise géopolitique.",
|
||||||
|
"Mettre en place des contrats à long terme avec des clauses de garantie d'approvisionnement"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -551,6 +557,15 @@ def set_vulnerability(v1, v2, t1, t2, seuils):
|
|||||||
|
|
||||||
return poids, couleur, v1_couleur, v2_couleur
|
return poids, couleur, v1_couleur, v2_couleur
|
||||||
|
|
||||||
|
def colorer_couleurs(la_couleur):
|
||||||
|
if la_couleur.lower() == "rouge":
|
||||||
|
return f":red-badge[{la_couleur}]"
|
||||||
|
if la_couleur.lower() == "orange":
|
||||||
|
return f":orange-badge[{la_couleur}]"
|
||||||
|
if la_couleur.lower() == "vert":
|
||||||
|
return f":green-badge[{la_couleur}]"
|
||||||
|
return la_couleur
|
||||||
|
|
||||||
def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"):
|
def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"):
|
||||||
produits, composants, mineraux, chains, descriptions, details_sections = parse_chains_md(filepath)
|
produits, composants, mineraux, chains, descriptions, details_sections = parse_chains_md(filepath)
|
||||||
|
|
||||||
@ -584,11 +599,11 @@ def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"
|
|||||||
poids_E, couleur_E, couleur_E_ihh, couleur_E_isg = set_vulnerability(mineraux[sel_miner]["IHH_Extraction"], mineraux[sel_miner]["ISG_Extraction"], "IHH", "ISG", seuils)
|
poids_E, couleur_E, couleur_E_ihh, couleur_E_isg = set_vulnerability(mineraux[sel_miner]["IHH_Extraction"], mineraux[sel_miner]["ISG_Extraction"], "IHH", "ISG", seuils)
|
||||||
poids_M, couleur_M, couleur_M_ics, couleur_M_ivc = set_vulnerability(mineraux[sel_miner]["ICS"], mineraux[sel_miner]["IVC"], "ICS", "IVC", seuils)
|
poids_M, couleur_M, couleur_M_ics, couleur_M_ivc = set_vulnerability(mineraux[sel_miner]["ICS"], mineraux[sel_miner]["IVC"], "ICS", "IVC", seuils)
|
||||||
|
|
||||||
st.markdown(f"* **{sel_prod} - Assemblage** : {couleur_A} ({poids_A})")
|
st.markdown(f"* **{sel_prod} - Assemblage** : {colorer_couleurs(couleur_A)} ({poids_A})")
|
||||||
st.markdown(f"* **{sel_comp} - Fabrication** : {couleur_F} ({poids_F})")
|
st.markdown(f"* **{sel_comp} - Fabrication** : {colorer_couleurs(couleur_F)} ({poids_F})")
|
||||||
st.markdown(f"* **{sel_miner} - Traitement** : {couleur_T} ({poids_T})")
|
st.markdown(f"* **{sel_miner} - Traitement** : {colorer_couleurs(couleur_T)} ({poids_T})")
|
||||||
st.markdown(f"* **{sel_miner} - Extraction** : {couleur_E} ({poids_E})")
|
st.markdown(f"* **{sel_miner} - Extraction** : {colorer_couleurs(couleur_E)} ({poids_E})")
|
||||||
st.markdown(f"* **{sel_miner} - Minerai** : {couleur_M} ({poids_M})")
|
st.markdown(f"* **{sel_miner} - Minerai** : {colorer_couleurs(couleur_M)} ({poids_M})")
|
||||||
|
|
||||||
poids_operation = {
|
poids_operation = {
|
||||||
'Extraction': 1,
|
'Extraction': 1,
|
||||||
@ -616,7 +631,7 @@ def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"
|
|||||||
criticite_chaine = "Critique"
|
criticite_chaine = "Critique"
|
||||||
niveau_criticite = {"Facile", "Modérée", "Difficile"}
|
niveau_criticite = {"Facile", "Modérée", "Difficile"}
|
||||||
|
|
||||||
st.info(f"**Criticité globale : {criticite_chaine} ({poids_total})**")
|
st.error(f"**Criticité globale : {criticite_chaine} ({poids_total})**")
|
||||||
|
|
||||||
with st.expander("Vue d’ensemble des criticités", expanded=True):
|
with st.expander("Vue d’ensemble des criticités", expanded=True):
|
||||||
st.markdown("## Vue d’ensemble des criticités", unsafe_allow_html=True)
|
st.markdown("## Vue d’ensemble des criticités", unsafe_allow_html=True)
|
||||||
@ -668,11 +683,11 @@ def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"
|
|||||||
plt.tight_layout()
|
plt.tight_layout()
|
||||||
st.pyplot(fig2)
|
st.pyplot(fig2)
|
||||||
|
|
||||||
st.markdown("""
|
st.markdown(f"""
|
||||||
Les lignes pointillées vertes et rouges représentent les seuils des indices concernés.\n
|
Les lignes pointillées en {colorer_couleurs("vert")} ou {colorer_couleurs("rouge")} représentent les seuils des indices concernés.\n
|
||||||
Les indices ISG (stabilité géopolitique) et IVC (concurrence intersectorielle) influent sur la probabilité de survenance d'un risque.\n
|
Les indices ISG (stabilité géopolitique) et IVC (concurrence intersectorielle) influent sur la probabilité de survenance d'un risque.\n
|
||||||
Les indices IHH (concentration géographique) et ICS (capacité de substitution) influent sur le niveau d'impact d'un risque.\n
|
Les indices IHH (concentration géographique) et ICS (capacité de substitution) influent sur le niveau d'impact d'un risque.\n
|
||||||
Une opération se trouvant au-dessus des deux seuils a donc une forte probabilité d'être impactée avec un fort impact sur la capacité à continuer la production.
|
Une opération se trouvant au-dessus des deux seuils a donc une forte probabilité d'être impactée avec un niveau élevé sur l'incapacité à continuer la production.
|
||||||
""")
|
""")
|
||||||
|
|
||||||
with st.expander("Explications et détails", expanded = True):
|
with st.expander("Explications et détails", expanded = True):
|
||||||
@ -681,30 +696,33 @@ def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"
|
|||||||
compte = Counter(couleurs)
|
compte = Counter(couleurs)
|
||||||
nb_rouge = compte["Rouge"]
|
nb_rouge = compte["Rouge"]
|
||||||
nb_orange = compte["Orange"]
|
nb_orange = compte["Orange"]
|
||||||
|
nb_vert = compte["Vert"]
|
||||||
|
|
||||||
st.markdown(f"""
|
st.markdown(f"""
|
||||||
Pour cette chaîne **{sel_prod} => {sel_comp} => {sel_miner}**, avec {nb_rouge} criticité(s) Rouge(s), {nb_orange} criticité(s) Orange(s), les indices individuels par opération sont :
|
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** : {couleur_A} ({poids_A})
|
* **{sel_prod} - Assemblage** : {colorer_couleurs(couleur_A)} ({poids_A})
|
||||||
* IHH = {produits[sel_prod]["IHH_Assemblage"]} ({couleur_A_ihh}) — ISG = {produits[sel_prod]["ISG_Assemblage"]} ({couleur_A_isg})
|
* IHH = {produits[sel_prod]["IHH_Assemblage"]} ({colorer_couleurs(couleur_A_ihh)}) <-> ISG = {produits[sel_prod]["ISG_Assemblage"]} ({colorer_couleurs(couleur_A_isg)})
|
||||||
* pondération de l'Assemblage dans le calcul de la criticité globale : 1,5
|
* pondération de l'Assemblage dans le calcul de la criticité globale : 1,5
|
||||||
* se référer à **{sel_prod} et Assemblage** plus bas pour le détail complet
|
* se référer à **{sel_prod} et Assemblage** plus bas pour le détail complet
|
||||||
* **{sel_comp} - Fabrication** : {couleur_F} ({poids_F})
|
* **{sel_comp} - Fabrication** : {colorer_couleurs(couleur_F)} ({poids_F})
|
||||||
* IHH = {composants[sel_comp]["IHH_Fabrication"]} ({couleur_F_ihh}) — ISG = {composants[sel_comp]["ISG_Fabrication"]} ({couleur_F_isg})
|
* IHH = {composants[sel_comp]["IHH_Fabrication"]} ({colorer_couleurs(couleur_F_ihh)}) <-> ISG = {composants[sel_comp]["ISG_Fabrication"]} ({colorer_couleurs(couleur_F_isg)})
|
||||||
* pondération de la Fabrication dans le calcul de la criticité globale : 2
|
* pondération de la Fabrication dans le calcul de la criticité globale : 2
|
||||||
* se référer à **{sel_comp} et Fabrication** plus bas pour le détail complet
|
* se référer à **{sel_comp} et Fabrication** plus bas pour le détail complet
|
||||||
* **{sel_miner} - Traitement** : {couleur_A} ({poids_A})
|
* **{sel_miner} - Traitement** : {colorer_couleurs(couleur_A)} ({poids_A})
|
||||||
* IHH = {mineraux[sel_miner]["IHH_Traitement"]} ({couleur_T_ihh}) — ISG = {mineraux[sel_miner]["ISG_Traitement"]} ({couleur_T_isg})
|
* IHH = {mineraux[sel_miner]["IHH_Traitement"]} ({colorer_couleurs(couleur_T_ihh)}) <-> ISG = {mineraux[sel_miner]["ISG_Traitement"]} ({colorer_couleurs(couleur_T_isg)})
|
||||||
* pondération du Traitement dans le calcul de la criticité globale : 1,5
|
* pondération du Traitement dans le calcul de la criticité globale : 1,5
|
||||||
* se référer à **{sel_miner} — Vue globale** plus bas pour le détail complet de l'ensemble du minerai
|
* se référer à **{sel_miner} — Vue globale** plus bas pour le détail complet de l'ensemble du minerai
|
||||||
* **{sel_miner} - Extraction** : {couleur_F} ({poids_F})
|
* **{sel_miner} - Extraction** : {colorer_couleurs(couleur_E)} ({poids_E})
|
||||||
* IHH = {mineraux[sel_miner]["IHH_Extraction"]} ({couleur_E_ihh}) — ISG = {mineraux[sel_miner]["ISG_Extraction"]} ({couleur_E_isg})
|
* IHH = {mineraux[sel_miner]["IHH_Extraction"]} ({colorer_couleurs(couleur_E_ihh)}) <-> ISG = {mineraux[sel_miner]["ISG_Extraction"]} ({colorer_couleurs(couleur_E_isg)})
|
||||||
* pondération de l'Extraction dans le calcul de la criticité globale : 1
|
* pondération de l'Extraction dans le calcul de la criticité globale : 1
|
||||||
* **{sel_miner} - Minerai** : {couleur_F} ({poids_F})
|
* **{sel_miner} - Minerai** : {colorer_couleurs(couleur_M)} ({poids_M})
|
||||||
* ICS = {mineraux[sel_miner]["ICS"]} ({couleur_M_ics}) — IVC = {mineraux[sel_miner]["IVC"]} ({couleur_M_ivc})
|
* 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
|
* pondération de la Substitution dans le calcul de la criticité globale : 2
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
st.markdown("---")
|
||||||
|
|
||||||
with st.expander("Préconisations et indicateurs génériques"):
|
with st.expander("Préconisations et indicateurs génériques"):
|
||||||
col_left, col_right = st.columns([1, 1], gap="small", border=True)
|
col_left, col_right = st.columns([1, 1], gap="small", border=True)
|
||||||
with col_left:
|
with col_left:
|
||||||
@ -764,6 +782,8 @@ def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"
|
|||||||
contenu_md += f" - {p}\n"
|
contenu_md += f" - {p}\n"
|
||||||
st.markdown(contenu_md)
|
st.markdown(contenu_md)
|
||||||
|
|
||||||
|
st.markdown("---")
|
||||||
|
|
||||||
with st.expander(f"{sel_prod} et Assemblage"):
|
with st.expander(f"{sel_prod} et Assemblage"):
|
||||||
assemblage_details = details_sections.get(f"{sel_prod}_assemblage", "")
|
assemblage_details = details_sections.get(f"{sel_prod}_assemblage", "")
|
||||||
|
|
||||||
@ -786,3 +806,5 @@ def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"
|
|||||||
afficher_bloc_ihh_isg("Traitement", mineraux[sel_miner]["IHH_Traitement"], mineraux[sel_miner]["ISG_Traitement"], traitement_details)
|
afficher_bloc_ihh_isg("Traitement", mineraux[sel_miner]["IHH_Traitement"], mineraux[sel_miner]["ISG_Traitement"], traitement_details)
|
||||||
|
|
||||||
afficher_caracteristiques_minerai(sel_miner, mineraux[sel_miner], minerai_general)
|
afficher_caracteristiques_minerai(sel_miner, mineraux[sel_miner], minerai_general)
|
||||||
|
|
||||||
|
st.markdown("---")
|
||||||
@ -1,2 +0,0 @@
|
|||||||
# __init__.py – app/fiches
|
|
||||||
from .interface import interface_plan_d_actions
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@ def interface_visualisations(G_temp, G_temp_ivc):
|
|||||||
|
|
||||||
{str(_("pages.visualisations.ihh_criticality_desc"))}
|
{str(_("pages.visualisations.ihh_criticality_desc"))}
|
||||||
""")
|
""")
|
||||||
if st.button(str(_("buttons.run")), key="btn_ihh_ics"):
|
if st.button(str(_("buttons.run")), key="btn_ihh_ics", icon=":material/bubble_chart:"):
|
||||||
try:
|
try:
|
||||||
lancer_visualisation_ihh_ics(G_temp)
|
lancer_visualisation_ihh_ics(G_temp)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -28,7 +28,7 @@ def interface_visualisations(G_temp, G_temp_ivc):
|
|||||||
{str(_("pages.visualisations.ihh_ivc_desc"))}
|
{str(_("pages.visualisations.ihh_ivc_desc"))}
|
||||||
""")
|
""")
|
||||||
|
|
||||||
if st.button(str(_("buttons.run")), key="btn_ihh_ivc"):
|
if st.button(str(_("buttons.run")), key="btn_ihh_ivc", icon=":material/bubble_chart:"):
|
||||||
try:
|
try:
|
||||||
lancer_visualisation_ihh_ivc(G_temp_ivc)
|
lancer_visualisation_ihh_ivc(G_temp_ivc)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@ -44,7 +44,7 @@
|
|||||||
"personnalisation": "Customization",
|
"personnalisation": "Customization",
|
||||||
"analyse": "Analysis",
|
"analyse": "Analysis",
|
||||||
"ia_nalyse": "AI'nalysis",
|
"ia_nalyse": "AI'nalysis",
|
||||||
"plan_d_actions": "Actions plan",
|
"plan_d_action": "Actions plan",
|
||||||
"visualisations": "Visualizations",
|
"visualisations": "Visualizations",
|
||||||
"fiches": "Cards"
|
"fiches": "Cards"
|
||||||
},
|
},
|
||||||
@ -149,7 +149,7 @@
|
|||||||
"submit_request": "Submit your request",
|
"submit_request": "Submit your request",
|
||||||
"empty_graph": "The graph is empty. Please make another selection."
|
"empty_graph": "The graph is empty. Please make another selection."
|
||||||
},
|
},
|
||||||
"plan_d_actions": {
|
"plan_d_action": {
|
||||||
"title": "Graph analysis for action",
|
"title": "Graph analysis for action",
|
||||||
"help": "How to use this tab?",
|
"help": "How to use this tab?",
|
||||||
"help_content": [
|
"help_content": [
|
||||||
|
|||||||
@ -44,7 +44,7 @@
|
|||||||
"personnalisation": "Personnalisation",
|
"personnalisation": "Personnalisation",
|
||||||
"analyse": "Analyse",
|
"analyse": "Analyse",
|
||||||
"ia_nalyse": "IA'nalyse",
|
"ia_nalyse": "IA'nalyse",
|
||||||
"plan_d_actions": "Plan d'actions",
|
"plan_d_action": "Plan d'action",
|
||||||
"visualisations": "Visualisations",
|
"visualisations": "Visualisations",
|
||||||
"fiches": "Fiches"
|
"fiches": "Fiches"
|
||||||
},
|
},
|
||||||
@ -149,7 +149,7 @@
|
|||||||
"submit_request": "Soumettre votre demande",
|
"submit_request": "Soumettre votre demande",
|
||||||
"empty_graph": "Le graphe est vide. Veuillez faire une autre sélection."
|
"empty_graph": "Le graphe est vide. Veuillez faire une autre sélection."
|
||||||
},
|
},
|
||||||
"plan_d_actions": {
|
"plan_d_action": {
|
||||||
"title": "Analyse du graphe pour action",
|
"title": "Analyse du graphe pour action",
|
||||||
"help": "Comment utiliser cet onglet ?",
|
"help": "Comment utiliser cet onglet ?",
|
||||||
"help_content": [
|
"help_content": [
|
||||||
|
|||||||
@ -45,7 +45,7 @@ def connexion():
|
|||||||
# L'identifiant n'est donc pas utilisé par la suite ; il est caché en CSS
|
# L'identifiant n'est donc pas utilisé par la suite ; il est caché en CSS
|
||||||
identifiant = st.text_input(str(_("auth.username")), value="fabnum-connexion", key="nom_utilisateur")
|
identifiant = st.text_input(str(_("auth.username")), value="fabnum-connexion", key="nom_utilisateur")
|
||||||
token = st.text_input(str(_("auth.token")), type="password")
|
token = st.text_input(str(_("auth.token")), type="password")
|
||||||
submitted = st.form_submit_button(str(_("auth.login")))
|
submitted = st.form_submit_button(str(_("auth.login")), icon=":material/login:")
|
||||||
|
|
||||||
if submitted and token:
|
if submitted and token:
|
||||||
erreur = True
|
erreur = True
|
||||||
@ -101,7 +101,7 @@ def bouton_deconnexion():
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
st.sidebar.markdown(f"{str(_('auth.logged_as'))} `{st.session_state.username}`")
|
st.sidebar.markdown(f"{str(_('auth.logged_as'))} `{st.session_state.username}`")
|
||||||
if st.sidebar.button(str(_("auth.logout"))):
|
if st.sidebar.button(str(_("auth.logout")), icon=":material/logout:"):
|
||||||
st.session_state.logged_in = False
|
st.session_state.logged_in = False
|
||||||
st.session_state.username = ""
|
st.session_state.username = ""
|
||||||
st.session_state.token = ""
|
st.session_state.token = ""
|
||||||
|
|||||||
@ -22,7 +22,7 @@ def afficher_menu():
|
|||||||
str(_("navigation.personnalisation")),
|
str(_("navigation.personnalisation")),
|
||||||
str(_("navigation.analyse")),
|
str(_("navigation.analyse")),
|
||||||
*([str(_("navigation.ia_nalyse"))] if st.session_state.get("logged_in", False) else []),
|
*([str(_("navigation.ia_nalyse"))] if st.session_state.get("logged_in", False) else []),
|
||||||
*([str(_("navigation.plan_d_actions"))]),
|
*([str(_("navigation.plan_d_action"))]),
|
||||||
str(_("navigation.visualisations")),
|
str(_("navigation.visualisations")),
|
||||||
str(_("navigation.fiches"))
|
str(_("navigation.fiches"))
|
||||||
]
|
]
|
||||||
|
|||||||
@ -79,7 +79,7 @@ from app.visualisations import interface_visualisations
|
|||||||
from app.personnalisation import interface_personnalisation
|
from app.personnalisation import interface_personnalisation
|
||||||
from app.analyse import interface_analyse
|
from app.analyse import interface_analyse
|
||||||
from app.ia_nalyse import interface_ia_nalyse
|
from app.ia_nalyse import interface_ia_nalyse
|
||||||
from app.plan_d_actions import interface_plan_d_actions
|
from app.plan_d_action import interface_plan_d_action
|
||||||
|
|
||||||
# Initialisation des traductions (langue française par défaut)
|
# Initialisation des traductions (langue française par défaut)
|
||||||
init_translations()
|
init_translations()
|
||||||
@ -171,7 +171,7 @@ fiches_tab = _("navigation.fiches")
|
|||||||
personnalisation_tab = _("navigation.personnalisation")
|
personnalisation_tab = _("navigation.personnalisation")
|
||||||
analyse_tab = _("navigation.analyse")
|
analyse_tab = _("navigation.analyse")
|
||||||
ia_nalyse_tab = _("navigation.ia_nalyse")
|
ia_nalyse_tab = _("navigation.ia_nalyse")
|
||||||
plan_d_actions_tab = _("navigation.plan_d_actions")
|
plan_d_action_tab = _("navigation.plan_d_action")
|
||||||
visualisations_tab = _("navigation.visualisations")
|
visualisations_tab = _("navigation.visualisations")
|
||||||
|
|
||||||
if st.session_state.onglet == instructions_tab:
|
if st.session_state.onglet == instructions_tab:
|
||||||
@ -195,9 +195,9 @@ elif dot_file_path and st.session_state.onglet == ia_nalyse_tab:
|
|||||||
G_temp = st.session_state["G_temp"]
|
G_temp = st.session_state["G_temp"]
|
||||||
interface_ia_nalyse(G_temp)
|
interface_ia_nalyse(G_temp)
|
||||||
|
|
||||||
elif dot_file_path and st.session_state.onglet == plan_d_actions_tab:
|
elif dot_file_path and st.session_state.onglet == plan_d_action_tab:
|
||||||
G_temp = st.session_state["G_temp"]
|
G_temp = st.session_state["G_temp"]
|
||||||
interface_plan_d_actions(G_temp)
|
interface_plan_d_action(G_temp)
|
||||||
|
|
||||||
elif dot_file_path and st.session_state.onglet == visualisations_tab:
|
elif dot_file_path and st.session_state.onglet == visualisations_tab:
|
||||||
G_temp = st.session_state["G_temp"]
|
G_temp = st.session_state["G_temp"]
|
||||||
|
|||||||
22358
schema.txt
22358
schema.txt
File diff suppressed because one or more lines are too long
@ -24,12 +24,24 @@ import re
|
|||||||
|
|
||||||
def calcul_ihh(graphe, depart, arrivee):
|
def calcul_ihh(graphe, depart, arrivee):
|
||||||
ihh = 0
|
ihh = 0
|
||||||
|
print("Appel à calcul_ihh")
|
||||||
for noeud in arrivee:
|
for noeud in arrivee:
|
||||||
|
print(f"nœud : {noeud}")
|
||||||
|
print(depart)
|
||||||
|
print(arrivee)
|
||||||
if depart in noeud: # Gestion simplifiée de l'intégration des Connexes
|
if depart in noeud: # Gestion simplifiée de l'intégration des Connexes
|
||||||
|
print("Départ dans le nœud")
|
||||||
if arrivee not in list(graphe.successors(depart)):
|
if arrivee not in list(graphe.successors(depart)):
|
||||||
depart = list(graphe.predecessors(noeud))[0]
|
depart_2 = list(graphe.predecessors(noeud))[0]
|
||||||
relation = graphe.get_edge_data(depart, noeud)
|
relation = graphe.get_edge_data(depart_2, noeud)
|
||||||
ihh += int(int(relation['label'].strip("%"))**2)
|
else:
|
||||||
|
relation = graphe.get_edge_data(depart, noeud)
|
||||||
|
print(relation)
|
||||||
|
print(relation['label'])
|
||||||
|
ihh_inter = int(int(relation['label'].strip("%"))**2)
|
||||||
|
print(ihh_inter)
|
||||||
|
ihh += ihh_inter
|
||||||
|
print(ihh)
|
||||||
ihh = int(round(ihh/100))
|
ihh = int(round(ihh/100))
|
||||||
return ihh
|
return ihh
|
||||||
|
|
||||||
@ -58,7 +70,8 @@ def mettre_a_jour_ihh(graph, noeuds):
|
|||||||
# et les pays auprès desquels il se fournit en minerai.
|
# et les pays auprès desquels il se fournit en minerai.
|
||||||
if "Traitement" in operation:
|
if "Traitement" in operation:
|
||||||
noeuds_pays_ihh = [n for n, v in niveaux_ihh.items() if (v == "11" or v == "1011") and operation in n]
|
noeuds_pays_ihh = [n for n, v in niveaux_ihh.items() if (v == "11" or v == "1011") and operation in n]
|
||||||
noeuds_acteurs_ihh = [n for n, v in niveaux_ihh.items() if (v == "12" or v == "1012" and operation in list(sous_graphe.predecessors(n))[0]]
|
noeuds_acteurs_ihh = [n for n, v in niveaux_ihh.items() if (v == "12" or v == "1012") and operation in list(sous_graphe.predecessors(n))[0]]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
noeuds_pays_ihh = [n for n, v in niveaux_ihh.items() if (v == "11" or v == "1011")]
|
noeuds_pays_ihh = [n for n, v in niveaux_ihh.items() if (v == "11" or v == "1011")]
|
||||||
noeuds_acteurs_ihh = [n for n, v in niveaux_ihh.items() if (v == "12" or v == "1012")]
|
noeuds_acteurs_ihh = [n for n, v in niveaux_ihh.items() if (v == "12" or v == "1012")]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user