o
    ˷eO                     @   sL  d Z ddlZddlZddlZddlmZmZ ddlmZm	Z	m
Z
 ddlmZmZ ddlZg dZdd Zd	d
 Zdd Zd<ddZdd Zdd Zdd Zdd Zdd Zd<ddZd<ddZd<ddZd<dd Zd<d!d"Zd#d$ Zd%d& Z d'd( Z!d=d*d+Z"d,d- Z#d.d/ Z$d<d0d1Z%G d2d3 d3Z&d<d4d5Z'd6d7 Z(d8d9 Z)d:d; Z*dS )>a  
Miscellaneous Helpers for NetworkX.

These are not imported into the base networkx namespace but
can be accessed, for example, as

>>> import networkx
>>> networkx.utils.make_list_of_ints({1, 2, 3})
[1, 2, 3]
>>> networkx.utils.arbitrary_element({5, 1, 7})  # doctest: +SKIP
1
    N)defaultdictdeque)IterableIteratorSized)chaintee)is_string_likeiterableempty_generatorflattenmake_list_of_intsis_list_of_intsmake_strgenerate_unique_nodedefault_openerdict_to_numpy_arraydict_to_numpy_array1dict_to_numpy_array2is_iteratorarbitrary_elementconsumepairwisegroupsto_tuplecreate_random_statecreate_py_random_statePythonRandomInterfacenodes_equaledges_equalgraphs_equalc                 C   s   d}t |t t| tS )zvCheck if obj is string.

    .. deprecated:: 2.6
        This is deprecated and will be removed in NetworkX v3.0.
    zYis_string_like is deprecated and will be removed in 3.0.Use isinstance(obj, str) instead.)warningswarnDeprecationWarning
isinstancestrobjmsg r)   J/var/www/ideatree/venv/lib/python3.10/site-packages/networkx/utils/misc.pyr	   8   s   
r	   c                 C   s:   d}t |t t| drdS zt|  W dS    Y dS )zReturn True if obj is iterable with a well-defined len().

    .. deprecated:: 2.6
        This is deprecated and will be removed in NetworkX v3.0.
    ziterable is deprecated and will be removed in 3.0.Use isinstance(obj, (collections.abc.Iterable, collections.abc.Sized)) instead.__iter__TF)r!   r"   r#   hasattrlenr&   r)   r)   r*   r
   F   s   

r
   c                   C   s   t dt dd dD S )zAReturn a generator with no members.

    .. deprecated:: 2.6
    z:empty_generator is deprecated and will be removed in v3.0.c                 s   s    | ]}|V  qd S Nr)   ).0ir)   r)   r*   	<genexpr>b   s    z"empty_generator.<locals>.<genexpr>r)   )r!   r"   r#   r)   r)   r)   r*   r   Z   s   r   c                 C   sh   t | ttfrt | tr| S |du rg }| D ]}t |ttfr$t |tr*|| qt|| qt|S )z>Return flattened version of (possibly nested) iterable object.N)r$   r   r   r%   appendr   tuple)r'   resultitemr)   r)   r*   r   e   s   r   c              	   C   s   t | ts5g }| D ])}d| }zt|}W n ty#   t|dw ||kr-t||| q	|S t| D ]0\}}d| }t |trHq9zt|}W n ty[   t|dw ||kret||| |< q9| S )a*  Return list of ints from sequence of integral numbers.

    All elements of the sequence must satisfy int(element) == element
    or a ValueError is raised. Sequence is iterated through once.

    If sequence is a list, the non-int values are replaced with ints.
    So, no new list is created
    zsequence is not all integers: N)r$   listint
ValueErrornxNetworkXErrorr2   	enumerate)sequencer4   r0   errmsgiiindxr)   r)   r*   r   s   s4   
	





r   c                 C   s@   d}t j|tdd t| tsdS | D ]
}t|ts dS qdS )zReturn True if list is a list of ints.

    .. deprecated:: 2.6
        This is deprecated and will be removed in NetworkX v3.0.
    zhis_list_of_ints is deprecated and will be removed in 3.0.See also: ``networkx.utils.make_list_of_ints.``   
stacklevelFT)r!   r"   r#   r$   r6   r7   )intlistr(   r0   r)   r)   r*   r      s   

r   c                 C   s   d}t |t t| S )zReturns the string representation of t.

    .. deprecated:: 2.6
        This is deprecated and will be removed in NetworkX v3.0.
    zCmake_str is deprecated and will be removed in 3.0. Use str instead.)r!   r"   r#   r%   )xr(   r)   r)   r*   r      s   r   c                  C   s   d} t | t tt S )z|Generate a unique node label.

    .. deprecated:: 2.6
        This is deprecated and will be removed in NetworkX v3.0.
    zVgenerate_unique_node is deprecated and will be removed in 3.0. Use uuid.uuid4 instead.)r!   r"   r#   r%   uuiduuid4)r(   r)   r)   r*   r      s   r   c                 C   sL   t dt ddlm} dgdgdgg dd}|tj | g }|| dS )	a  Opens `filename` using system's default program.

    .. deprecated:: 2.6
       default_opener is deprecated and will be removed in version 3.0.
       Consider an image processing library to open images, such as Pillow::

           from PIL import Image
           Image.open(filename).show()

    Parameters
    ----------
    filename : str
        The path of the file to be opened.

    zAdefault_opener is deprecated and will be removed in version 3.0. r   )callopenzxdg-open)zcmd.exez/Cstart )darwinlinuxlinux2win32N)r!   r"   r#   
subprocessrG   sysplatform)filenamerG   cmdscmdr)   r)   r*   r      s   r   c              	   C   s.   zt | |W S  ttfy   t| | Y S w )zPConvert a dictionary of dictionaries to a numpy array
    with optional mapping.)_dict_to_numpy_array2AttributeError	TypeError_dict_to_numpy_array1)dmappingr)   r)   r*   r      s
   r   c                 C      d}t j|tdd t| |S )zConvert a dict of dicts to a 2d numpy array with optional mapping.

    .. deprecated:: 2.8

       dict_to_numpy_array2 is deprecated and will be removed in networkx 3.0.
       Use `dict_to_numpy_array` instead.
    zhdict_to_numpy_array2 is deprecated and will be removed in networkx 3.0.
Use dict_to_numpy_array instead.r@   rA   )r!   r"   r#   rU   rY   rZ   r(   r)   r)   r*   r         	
r   c              
   C   s   ddl }|du r)t|  }|  D ]\}}||  qtt|tt|}t|}|	||f}| D ]"\}}	| D ]\}
}z| | |
 ||	|f< W q@ t
yY   Y q@w q8|S )zYConvert a dictionary of dictionaries to a 2d numpy array
    with optional mapping.

    r   N)numpysetkeysitemsupdatedictzipranger-   zerosKeyError)rY   rZ   npskvnak1r0   k2jr)   r)   r*   rU      s"   rU   c                 C   r[   )zConvert a dict of numbers to a 1d numpy array with optional mapping.

    .. deprecated:: 2.8

       dict_to_numpy_array1 is deprecated and will be removed in networkx 3.0.
       Use dict_to_numpy_array instead.
    zhdict_to_numpy_array1 is deprecated and will be removed in networkx 3.0.
Use dict_to_numpy_array instead.r@   rA   )r!   r"   r#   rX   r\   r)   r)   r*   r     r]   r   c                 C   sn   ddl }|du rt|  }tt|tt|}t|}||}| D ]\}}|| }| | ||< q&|S )zJConvert a dictionary of numbers to a 1d numpy array with optional mapping.r   N)	r^   r_   r`   rc   rd   re   r-   rf   ra   )rY   rZ   rh   ri   rl   rm   rn   r0   r)   r)   r*   rX   $  s   
rX   c                 C   s8   d}t j|tdd t| dpt| d}t| | u o|S )zReturns True if and only if the given object is an iterator object.

    .. deprecated:: 2.6.0
        Deprecated in favor of ``isinstance(obj, collections.abc.Iterator)``
    zxis_iterator is deprecated and will be removed in version 3.0. Use ``isinstance(obj, collections.abc.Iterator)`` instead.r@   rA   __next__next)r!   r"   r#   r,   iter)r'   r(   has_next_attrr)   r)   r*   r   3  s
   r   c                 C   s   t | tr	tdtt| S )a  Returns an arbitrary element of `iterable` without removing it.

    This is most useful for "peeking" at an arbitrary element of a set,
    but can be used for any list, dictionary, etc., as well.

    Parameters
    ----------
    iterable : `abc.collections.Iterable` instance
        Any object that implements ``__iter__``, e.g. set, dict, list, tuple,
        etc.

    Returns
    -------
    The object that results from ``next(iter(iterable))``

    Raises
    ------
    ValueError
        If `iterable` is an iterator (because the current implementation of
        this function would consume an element from the iterator).

    Examples
    --------
    Arbitrary elements from common Iterable objects:

    >>> nx.utils.arbitrary_element([1, 2, 3])  # list
    1
    >>> nx.utils.arbitrary_element((1, 2, 3))  # tuple
    1
    >>> nx.utils.arbitrary_element({1, 2, 3})  # set
    1
    >>> d = {k: v for k, v in zip([1, 2, 3], [3, 2, 1])}
    >>> nx.utils.arbitrary_element(d)  # dict_keys
    1
    >>> nx.utils.arbitrary_element(d.values())   # dict values
    3

    `str` is also an Iterable:

    >>> nx.utils.arbitrary_element("hello")
    'h'

    :exc:`ValueError` is raised if `iterable` is an iterator:

    >>> iterator = iter([1, 2, 3])  # Iterator, *not* Iterable
    >>> nx.utils.arbitrary_element(iterator)
    Traceback (most recent call last):
        ...
    ValueError: cannot return an arbitrary item from an iterator

    Notes
    -----
    This function does not return a *random* element. If `iterable` is
    ordered, sequential calls will return the same value::

        >>> l = [1, 2, 3]
        >>> nx.utils.arbitrary_element(l)
        1
        >>> nx.utils.arbitrary_element(l)
        1

    z0cannot return an arbitrary item from an iterator)r$   r   r8   rr   rs   )r
   r)   r)   r*   r   B  s   
?r   c                 C   s$   d}t j|tdd t| dd dS )z}Consume the iterator entirely.

    .. deprecated:: 2.6
        This is deprecated and will be removed in NetworkX v3.0.
    zpconsume is deprecated and will be removed in version 3.0. Use ``collections.deque(iterator, maxlen=0)`` instead.r@   rA   r   )maxlenN)r!   r"   r#   r   )iteratorr(   r)   r)   r*   r     s   r   Fc                 C   s:   t | \}}t|d}|du rt|t||fS t||S )z&s -> (s0, s1), (s1, s2), (s2, s3), ...NT)r   rr   rd   r   )r
   cyclicrm   bfirstr)   r)   r*   r     s
   

r   c                 C   s0   t t}|  D ]\}}|| | qt|S )a  Converts a many-to-one mapping into a one-to-many mapping.

    `many_to_one` must be a dictionary whose keys and values are all
    :term:`hashable`.

    The return value is a dictionary mapping values from `many_to_one`
    to sets of keys from `many_to_one` that have that value.

    Examples
    --------
    >>> from networkx.utils import groups
    >>> many_to_one = {"a": 1, "b": 1, "c": 2, "d": 3, "e": 3}
    >>> groups(many_to_one)  # doctest: +SKIP
    {1: {'a', 'b'}, 2: {'c'}, 3: {'e', 'd'}}
    )r   r_   ra   addrc   )many_to_oneone_to_manyrk   rj   r)   r)   r*   r     s   r   c                 C   s0   t jdtdd t| ttfs| S ttt| S )a  Converts lists to tuples.

    .. deprecated:: 2.8

       to_tuple is deprecated and will be removed in NetworkX 3.0.

    Examples
    --------
    >>> from networkx.utils import to_tuple
    >>> a_list = [1, 2, [1, 4]]
    >>> to_tuple(a_list)
    (1, 2, (1, 4))
    z;to_tuple is deprecated and will be removed in NetworkX 3.0.r@   rA   )r!   r"   r#   r$   r3   r6   mapr   )rD   r)   r)   r*   r     s   r   c                 C   sp   ddl }| du s| |ju r|jjjS t| |jjr| S t| tr&|j| S t| |jjr/| S |  d}t|)a  Returns a numpy.random.RandomState or numpy.random.Generator instance
    depending on input.

    Parameters
    ----------
    random_state : int or NumPy RandomState or Generator instance, optional (default=None)
        If int, return a numpy.random.RandomState instance set with seed=int.
        if `numpy.random.RandomState` instance, return it.
        if `numpy.random.Generator` instance, return it.
        if None or numpy.random, return the global random number generator used
        by numpy.random.
    r   NzW cannot be used to create a numpy.random.RandomState or
numpy.random.Generator instance)	r^   randommtrand_randr$   RandomStater7   	Generatorr8   )random_staterh   r(   r)   r)   r*   r     s   

r   c                   @   sh   e Zd ZdddZdd Zdd Zddd	Zd
d Zdd Zdd Z	dd Z
dd Zdd Zdd ZdS )r   Nc                 C   sR   zdd l }W n ty   d}t|t Y nw |d u r$|jjj| _d S || _d S )Nr   z.numpy not found, only random.random available.)	r^   ImportErrorr!   r"   ImportWarningr~   r   r   _rng)selfrngrh   r(   r)   r)   r*   __init__  s   
zPythonRandomInterface.__init__c                 C   s
   | j  S r.   r   r~   )r   r)   r)   r*   r~     s   
zPythonRandomInterface.randomc                 C   s   ||| | j    S r.   r   )r   rm   rx   r)   r)   r*   uniform  s   zPythonRandomInterface.uniformc                 C   s4   dd l }t| j|jjr| j||S | j||S Nr   r^   r$   r   r~   r   integersrandintr   rm   rx   rh   r)   r)   r*   	randrange  s   zPythonRandomInterface.randrangec                 C   sL   dd l }t| j|jjr| jdt|}|| S | jdt|}|| S r   )r^   r$   r   r~   r   r   r-   r   )r   seqrh   idxr)   r)   r*   choice
  s   zPythonRandomInterface.choicec                 C   s   | j ||S r.   )r   normal)r   musigmar)   r)   r*   gauss  s   zPythonRandomInterface.gaussc                 C      | j |S r.   )r   shuffle)r   r   r)   r)   r*   r        zPythonRandomInterface.shufflec                 C   s   | j jt||fddS )NF)sizereplace)r   r   r6   )r   r   rj   r)   r)   r*   sample  s   zPythonRandomInterface.samplec                 C   s<   dd l }t| j|jjr| j||d S | j||d S )Nr      r   r   r)   r)   r*   r     s   zPythonRandomInterface.randintc                 C   s   | j d| S )Nr   )r   exponential)r   scaler)   r)   r*   expovariate'  s   z!PythonRandomInterface.expovariatec                 C   r   r.   )r   pareto)r   shaper)   r)   r*   paretovariate+  r   z#PythonRandomInterface.paretovariater.   )__name__
__module____qualname__r   r~   r   r   r   r   r   r   r   r   r   r)   r)   r)   r*   r     s    

		r   c                 C   s   ddl }z+ddl}| |j u rt|j jjW S t| |j j|j jfr&t| W S t| tr.| W S W n	 ty8   Y nw | du sA| |u rD|j	S t| |j
rL| S t| trV|
| S |  d}t|)a  Returns a random.Random instance depending on input.

    Parameters
    ----------
    random_state : int or random number generator or None (default=None)
        If int, return a random.Random instance set with seed=int.
        if random.Random instance, return it.
        if None or the `random` package, return the global random number
        generator used by `random`.
        if np.random package, return the global numpy random number
        generator wrapped in a PythonRandomInterface class.
        if np.random.RandomState or np.random.Generator instance, return it
        wrapped in PythonRandomInterface
        if a PythonRandomInterface instance, return it
    r   Nz4 cannot be used to generate a random.Random instance)r~   r^   r   r   r   r$   r   r   r   _instRandomr7   r8   )r   r~   rh   r(   r)   r)   r*   r   :  s*   





r   c              	   C   s\   t | }t |}zt|}t|}W ||kS  ttfy-   t|}t|}Y ||kS w )aU  Check if nodes are equal.

    Equality here means equal as Python objects.
    Node data must match if included.
    The order of nodes is not relevant.

    Parameters
    ----------
    nodes1, nodes2 : iterables of nodes, or (node, datadict) tuples

    Returns
    -------
    bool
        True if nodes are equal, False otherwise.
    )r6   rc   r8   rW   fromkeys)nodes1nodes2nlist1nlist2d1d2r)   r)   r*   r   b  s   

r   c                 C   s|  ddl m} |t}|t}d}t| D ].\}}|d |d }}|dd g}	||| v r6|| | |	 }	|	|| |< |	|| |< qd}
t|D ].\}
}|d |d }}|dd g}	||| v rk|| | |	 }	|	|| |< |	|| |< qI||
kr~dS | D ]9\}}| D ]0\}}||vr  dS ||| vr  dS || | }|D ]}	||	||	kr   dS qqqdS )a  Check if edges are equal.

    Equality here means equal as Python objects.
    Edge data must match if included.
    The order of the edges is not relevant.

    Parameters
    ----------
    edges1, edges2 : iterables of with u, v nodes as
        edge tuples (u, v), or
        edge tuples with data dicts (u, v, d), or
        edge tuples with keys and data dicts (u, v, k, d)

    Returns
    -------
    bool
        True if edges are equal, False otherwise.
    r   )r   r   r@   NFT)collectionsr   rc   r;   ra   count)edges1edges2r   r   r   c1eurk   datac2rl   nbrdictnbrdatalist
d2datalistr)   r)   r*   r   }  sF   
	r   c                 C   s$   | j |j ko| j|jko| j|jkS )a  Check if graphs are equal.

    Equality here means equal as Python objects (not isomorphism).
    Node, edge and graph data must match.

    Parameters
    ----------
    graph1, graph2 : graph

    Returns
    -------
    bool
        True if graphs are equal, False otherwise.
    )adjnodesgraph)graph1graph2r)   r)   r*   r      s
   

r    r.   )F)+__doc__rP   rE   r!   r   r   r   collections.abcr   r   r   	itertoolsr   r   networkxr9   __all__r	   r
   r   r   r   r   r   r   r   r   r   rU   r   rX   r   r   r   r   r   r   r   r   r   r   r   r    r)   r)   r)   r*   <module>   sF    !
$
 



F
	

L(7