Finish the calc_grph_statistics function to compute the network diameter, characteristic path length (CPL), average clustering coefficient, transitivity, assortativity, and degree sequence (a list of all degrees for each node). Provide a dictionary of the results with the name of each statistic as the key.
Finish the sweep_louvaine_res function to detect community structures within the graph. Utilize the Louvain algorithm to determine the optimal partition. Utilize 10 different resolution parameters from min_resolution to max_resolution (inclusive), and compare the result of each partition to the ground truth (you can find the ground truth in the value field associated with each node in the graph) using the normalized mutual information function. Return the list of resolutions and NMIs from the resulting community assignments. Additionally, complete the plt_nmi_res function to exhibit the NMI for each resolution as a line plot.
import networkx as nx
from networkx.algorithms.community import louvain_communities
import numpy as np
import matplotlib.pyplot as plt
from typing import Tuple, List, Dict, Union
def ld_ftball_graph() -> nx.Graph:
" G = nx.read_gml(""ftball.gml"")"
return G
def calc
_
grph
_
statistics
(
G: nx
.
Graph
)

-
>
Dict
[
str
,
Union
[
float
,
List
[
int
]
]
]
:

"
"
"
Inputs:
G: NetworkX graph object

Returns:
Dictionary of graph statistics


"
"
"

return graph
_
statistics
def sweep_louvaine_res(G: nx.Graph, min_resolution: int=1, max_resolution: int=10) -> Tuple[List[int], List[float]]:
" """""""
Inputs:
G: NetworkX graph object
min_resolution : integer
max_resolution : integer

Returns:
Tuple of list of resolutions and list of NMIs
def plt_nmi_res(resolutions: List[int], nmis: List[float], save: bool=False) -> None:
" """""""
Inputs:
resolutions : list
nmis : list
save: boolean

Returns:
None

" """""""