2025-06-11 14:57:53 +02:00

157 lines
5.6 KiB
Python

from typing import Any, Dict, Tuple, List, Union, Optional
import streamlit as st
import networkx as nx
from utils.translations import _
from utils.persistance import maj_champ_statut, get_champ_statut, supprime_champ_statut
from utils.graph_utils import (
extraire_chemins_depuis,
extraire_chemins_vers
)
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'))}")
# Étape 1 : récupérer tous les nœuds descendants depuis les produits finaux
descendants = set()
for start in noeuds_depart:
descendants.update(nx.descendants(G, start)) # tous les successeurs (récursifs)
# Étape 2 : ne garder que les nœuds de niveau 2 parmi les descendants
minerais_nodes = sorted([
n for n in descendants
if G.nodes[n].get("niveau") and int(str(G.nodes[n].get("niveau")).strip('"')) == 2
])
# Initialiser depuis champ_statut si besoin
if "analyse_minerais" not in st.session_state:
anciens = []
i = 0
while True:
val = get_champ_statut(f"pages.plan_d_action.filter_by_minerals.{i}")
if not val:
break
anciens.append(val)
i += 1
st.session_state["analyse_minerais"] = anciens
# Afficher le multiselect
st.multiselect(
str(_("pages.plan_d_action.filter_by_minerals")),
minerais_nodes,
key="analyse_minerais"
)
minerais_selection = st.session_state["analyse_minerais"]
# Toujours purger, puis réécrire si nécessaire
supprime_champ_statut("pages.plan_d_action.filter_by_minerals")
if minerais_selection:
for i, val in enumerate(minerais_selection):
maj_champ_statut(f"pages.plan_d_action.filter_by_minerals.{i}", val)
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.
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'))}")
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]
if "analyse_noeuds_depart" not in st.session_state:
anciens = []
i = 0
while True:
val = get_champ_statut(f"pages.plan_d_action.filter_start_nodes.{i}")
if not val:
break
anciens.append(val)
i += 1
st.session_state["analyse_noeuds_depart"] = anciens
st.multiselect(
str(_("pages.plan_d_action.filter_start_nodes")),
sorted(depart_nodes),
key="analyse_noeuds_depart"
)
noeuds_depart = st.session_state["analyse_noeuds_depart"]
supprime_champ_statut("pages.plan_d_action.filter_start_nodes")
if noeuds_depart:
for i, val in enumerate(noeuds_depart):
maj_champ_statut(f"pages.plan_d_action.filter_start_nodes.{i}", val)
noeuds_depart = noeuds_depart if noeuds_depart else None
return noeuds_depart, noeuds_arrivee
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:
for na in noeuds_arrivee:
tous_chemins = extraire_chemins_depuis(G, nd)
chemins.extend([chemin for chemin in tous_chemins if na in chemin])
elif noeuds_depart:
for nd in noeuds_depart:
chemins.extend(extraire_chemins_depuis(G, nd))
elif noeuds_arrivee:
for na in noeuds_arrivee:
chemins.extend(extraire_chemins_vers(G, na, niveau_depart))
else:
sources_depart = [n for n in G.nodes() if niveaux.get(n) == niveau_depart]
for nd in sources_depart:
chemins.extend(extraire_chemins_depuis(G, nd))
if minerais:
chemins = [chemin for chemin in chemins if any(n in minerais for n in chemin)]
return chemins