from typing import Any, Dict, Tuple, List, Union, Optional import streamlit as st import networkx as nx from utils.translations import _ from utils.graph_utils import ( extraire_chemins_depuis, extraire_chemins_vers ) def selectionner_minerais(G: nx.DiGraph, noeuds_depart: List[Any]) -> List[Union[str, int]]: """Interface pour sélectionner les minerais si nécessaire. Args: G (nx.DiGraph): 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 ]) minerais_selection = st.multiselect( str(_("pages.plan_d_action.filter_by_minerals")), minerais_nodes, key="analyse_minerais" ) return minerais_selection def selectionner_noeuds( G: nx.DiGraph, 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.DiGraph): 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] noeuds_depart = st.multiselect(str(_("pages.plan_d_action.filter_start_nodes")), sorted(depart_nodes), key="analyse_noeuds_depart") noeuds_depart = noeuds_depart if noeuds_depart else None return noeuds_depart, noeuds_arrivee def extraire_chemins_selon_criteres( G: nx.DiGraph, 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.DiGraph): 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