"""The following functions can be used for input checks of :class:`.Graph`."""from__future__importannotationsfromtypingimportIterableimportnetworkxasnxfrompyrigi.data_typeimportEdge,Sequence,Vertexfrompyrigi.exceptionimportLoopErrorfrompyrigi.graphimport_generalasgraph_general
[docs]defno_loop(graph:nx.Graph)->None:""" Check whether the graph has loops and raise an error in case. """ifnx.number_of_selfloops(graph)>0:raiseLoopError()
[docs]defvertex_members(graph:nx.Graph,to_check:Iterable[Vertex]|Vertex,name:str="")->None:""" Check whether the elements of a list are indeed vertices of the graph and raise error otherwise. Parameters ---------- to_check: A vertex or ``Iterable`` of vertices for which the containment in the graph is checked. name: A name of the ``Iterable`` ``to_check`` can be picked. """ifnotisinstance(to_check,Iterable):ifnotgraph.has_node(to_check):raiseValueError(f"The element {to_check} is not a vertex of the graph!")else:forvertexinto_check:ifnotgraph.has_node(vertex):raiseValueError(f"The element {vertex} from "+name+f" {to_check} is not a vertex of the graph!")
[docs]defedge_format(graph:nx.Graph,edge:Edge,loopfree:bool=False)->None:""" Check if an ``edge`` is a pair of (distinct) vertices of the graph and raise an error otherwise. Parameters ---------- edge: Edge for which the containment in the given graph is checked. loopfree: If ``True``, an error is raised if ``edge`` is a loop. """ifnotisinstance(edge,list|tuple)ornotlen(edge)==2:raiseTypeError(f"The input {edge} must be a tuple or list of length 2!")vertex_members(graph,edge,"the input pair")ifloopfreeandedge[0]==edge[1]:raiseLoopError(f"The input {edge} must be two distinct vertices.")
[docs]defis_edge(graph:nx.Graph,edge:Edge,vertices:Sequence[Vertex]=None)->None:""" Check if the given input is an edge of the graph with endvertices in vertices and raise an error otherwise. Parameters ---------- edge: an edge to be checked vertices: Check if the endvertices of the edge are contained in the list ``vertices``. If ``None``, the function considers all vertices of the graph. """edge_format(graph,edge)ifverticesand(edge[0]notinverticesoredge[1]notinvertices):raiseValueError(f"The elements of the edge {edge} are not among vertices {vertices}!")ifnotgraph.has_edge(edge[0],edge[1]):raiseValueError(f"Edge {edge} is not contained in the graph!")
[docs]defis_edge_list(graph:nx.Graph,edges:Sequence[Edge],vertices:Sequence[Vertex]=None)->None:""" Apply :func:`~.is_edge` to all edges in a list. Parameters ---------- edges: A list of edges to be checked. vertices: Check if the endvertices of the edges are contained in the list ``vertices``. If ``None`` (default), the function considers all vertices of the graph. """foredgeinedges:is_edge(graph,edge,vertices)
[docs]defedge_format_list(graph:nx.Graph,edges:Sequence[Edge])->None:""" Apply :func:`~.edge_format` to all edges in a list. Parameters ---------- edges: A list of pairs to be checked. """foredgeinedges:edge_format(graph,edge)
[docs]defis_vertex_order(graph:nx.Graph,vertex_order:Sequence[Vertex],name:str="")->list[Vertex]:""" Check whether the provided ``vertex_order`` contains the same elements as the graph vertex set and raise an error otherwise. The ``vertex_order`` is also returned. Parameters ---------- vertex_order: List of vertices in the preferred order. If ``None``, then all vertices are returned using :meth:`~Graph.vertex_list`. """ifvertex_orderisNone:returngraph_general.vertex_list(graph)else:ifnotgraph.number_of_nodes()==len(vertex_order)ornotset(graph_general.vertex_list(graph))==set(vertex_order):raiseValueError("The vertices in `"+name+"` must be exactly "+"the same vertices as in the graph!")returnlist(vertex_order)
[docs]defis_edge_order(graph:nx.Graph,edge_order:Sequence[Edge],name:str="")->list[Edge]:""" Check whether the provided ``edge_order`` contains the same elements as the graph edge set and raise an error otherwise. The ``edge_order`` is also returned. Parameters ---------- edge_order: List of edges in the preferred order. If ``None``, then all edges are returned using :meth:`~Graph.edge_list`. """ifedge_orderisNone:returngraph_general.edge_list(graph)else:ifnotgraph.number_of_edges()==len(edge_order)ornotall([set(e)in[set(e)foreinedge_order]foreingraph_general.edge_list(graph)]):raiseValueError("The edges in `"+name+"` must be exactly ""the same edges as in the graph!")returnlist(edge_order)