2025-06-02 17:00:08 +02:00

148 lines
5.8 KiB
Python

"""
Version 1.0
Date 27/03/2025
Auteur : Stéphan Peccini
Ce script met à jour les valeurs ihh en fonction des données
de part de marché des pays où des acteurs.
https://fr.wikipedia.org/wiki/Indice_de_Herfindahl-Hirschmann
Important :
-----------------------
Pour faciliter le travail, tout est fait avec un graphe NetworkX et ensuite sauvé
au format DOT sans aucune structure hiérarchique.
Il suffit alors de passer le fichier résultat dans beautify.py pour avoir un fichier
DOT conforme aux attentes.
"""
import networkx as nx
from networkx.drawing.nx_pydot import write_dot
import sys
import re
def calcul_ihh(graphe, depart, arrivee):
ihh = 0
print("Appel à calcul_ihh")
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
print("Départ dans le nœud")
if arrivee not in list(graphe.successors(depart)):
depart_2 = list(graphe.predecessors(noeud))[0]
relation = graphe.get_edge_data(depart_2, noeud)
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))
return ihh
def mettre_a_jour_ihh(graph, noeuds):
for noeud in noeuds:
sous_graphe = nx.DiGraph()
try:
for chemin in nx.edge_bfs(graph, source=noeud):
sous_graphe.add_edge(*chemin)
# Ajouter les attributs des nœuds
for node in sous_graphe.nodes():
if node in graph.nodes():
sous_graphe.nodes[node].update(graph.nodes[node])
# Ajouter les attributs des arêtes
for edge in sous_graphe.edges():
if edge in graph.edges():
sous_graphe.edges[edge].update(graph.edges[edge])
niveaux_ihh = nx.get_node_attributes(sous_graphe, "niveau")
operation = noeud.split('_')[0]
# La hiérarchie Traitement est particulière. En effet, les acteurs du traitement se fournissent
# auprès des acteurs de l'extraction. Il y a une relations entre chaque acteur de traitement
# et les pays auprès desquels il se fournit en minerai.
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_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:
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")]
# Le calcul de l'indice de Herfindahl-Hirschmann se fait normalement au niveau d'une entreprise.
# Toutefois, il se fait au niveau des pays et au niveau des acteurs pour l'opération qui est menée.
ihh_pays = calcul_ihh(sous_graphe, noeud, noeuds_pays_ihh)
nx.set_node_attributes(graph, {noeud: {"ihh_pays": f"{ihh_pays}"}})
ihh_acteurs = calcul_ihh(sous_graphe, noeud, noeuds_acteurs_ihh)
nx.set_node_attributes(graph, {noeud: {"ihh_acteurs": f"{ihh_acteurs}"}})
except nx.NetworkXNoPath:
pass # Ignore les chemins inexistants
return graph
def mettre_a_jour_ihh_reserves(graph, noeuds):
for noeud in noeuds:
sous_graphe = nx.DiGraph()
try:
for chemin in nx.edge_bfs(graph, source=noeud):
sous_graphe.add_edge(*chemin)
# Ajouter les attributs des nœuds
for node in sous_graphe.nodes():
if node in graph.nodes():
sous_graphe.nodes[node].update(graph.nodes[node])
# Ajouter les attributs des arêtes
for edge in sous_graphe.edges():
if edge in graph.edges():
sous_graphe.edges[edge].update(graph.edges[edge])
niveaux_ihh = nx.get_node_attributes(sous_graphe, "niveau")
noeuds_pays_ihh = [n for n, v in niveaux_ihh.items() if (v == "11" or v == "1011")]
# Le calcul de l'indice de Herfindahl-Hirschmann se fait normalement au niveau d'une entreprise.
# Toutefois, il se fait au niveau des pays et au niveau des acteurs pour l'opération qui est menée.
ihh_pays = calcul_ihh(sous_graphe, noeud, noeuds_pays_ihh)
nx.set_node_attributes(graph, {noeud: {"ihh_pays": f"{ihh_pays}"}})
except nx.NetworkXNoPath:
pass # Ignore les chemins inexistants
return graph
def main():
""" Fonction principale pour interagir avec l'utilisateur. """
if len(sys.argv) != 3:
print("Usage: python ihh.py fichier_en_entree.dot fichier_en_sortie.dot")
return
fichier_en_entree = sys.argv[1]
fichier_en_sortie = sys.argv[2]
graph = nx.DiGraph(nx.nx_agraph.read_dot(fichier_en_entree))
niveaux = nx.get_node_attributes(graph, "niveau")
noeuds_niveau_10 = [n for n, v in niveaux.items() if (v == "10" or v == "1010") and not re.search(r'Reserves', n)]
noeuds_niveau_10.sort()
graphe = mettre_a_jour_ihh(graph, noeuds_niveau_10)
noeuds_niveau_10 = [n for n, v in niveaux.items() if (v == "10" or v == "1010") and re.search(r'Reserves', n)]
noeuds_niveau_10.sort()
graphe = mettre_a_jour_ihh_reserves(graphe, noeuds_niveau_10)
write_dot(graphe, fichier_en_sortie)
if __name__ == "__main__":
main()