B
    ,[0                 @   s  d Z ddlmZ ddlmZ ddlZddlZddlZddlmZm	Z	 ddl
ZyddlmZ W n* ek
r   ddlZejfddZY nX ye W n ek
r   eZeZY nX d	d
 Zdd Zd4ddZdd Zejd dkZerdd Zndd Zdd Zdd Zd5ddZd6ddZd7ddZdd  Z d!d" Z!d#d$ Z"d8d&d'Z#d(d) Z$d*d+ Z%d9d,d-Z&G d.d/ d/e'Z(d:d0d1Z)d2d3 Z*dS );z
Miscellaneous Helpers for NetworkX.

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

>>> import networkx
>>> networkx.utils.is_string_like('spam')
True
    )defaultdict)dequeN)teechain)
accumulatec             c   sR   t | }yt|}W n tk
r(   d S X |V  x|D ]}|||}|V  q6W d S )N)iternextStopIteration)iterablefuncitZtotalelement r   2lib/python3.7/site-packages/networkx/utils/misc.pyr   )   s    

r   c             C   s
   t | tS )zCheck if obj is string.)
isinstance
basestring)objr   r   r   is_string_like@   s    r   c             C   s*   t | drdS yt|  W n
   dS dS )z: Return True if obj is iterable with a well-defined len().__iter__TF)hasattrlen)r   r   r   r   r
   E   s    
r
   c             C   s^   t | rt| r| S |dkr g }x2| D ]*}t |r:t|rF|| q&t|| q&W | |S )z@ Return flattened version of (possibly nested) iterable object. N)r
   r   appendflatten	__class__)r   resultitemr   r   r   r   P   s    
r   c             C   s.   t | tsdS x| D ]}t |tsdS qW dS )z( Return True if list is a list of ints. FT)r   listint)Zintlistir   r   r   is_list_of_ints^   s    


r      c             C   s    t | tr| S tt| dS dS )z&Return the string representation of t.zunicode-escapeN)r   unicodestr)xr   r   r   make_strj   s    

r$   c             C   s   t | S )z&Return the string representation of t.)r"   )r#   r   r   r   r$   y   s    c               C   s   t t S )z Generate a unique node label.)r"   uuidZuuid1r   r   r   r   generate_unique_node~   s    r&   c             C   sD   ddl m} dgdgdgddddgd	}|tj | g }|| d
S )zOpens `filename` using system's default program.

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

    r   )callopenzxdg-openzcmd.exez/Cstart )darwinZlinuxZlinux2Zwin32N)
subprocessr'   sysplatform)filenamer'   Zcmdscmdr   r   r   default_opener   s    	r1   c          	   C   s.   y
t | |S  ttfk
r(   t| |S X dS )zPConvert a dictionary of dictionaries to a numpy array
    with optional mapping.N)dict_to_numpy_array2AttributeError	TypeErrordict_to_numpy_array1)dmappingr   r   r   dict_to_numpy_array   s    
r8   c          
   C   s   ddl }|dkrVt|  }x"|  D ]\}}||  q&W tt|tt|}t|}|	||f}xX| D ]L\}}	xB| D ]6\}
}y| | |
 ||	|f< W q t
k
r   Y qX qW qvW |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)r6   r7   r9   skvnak1r   Zk2jr   r   r   r2      s    r2   c             C   sr   ddl }|dkr2t|  }tt|tt|}t|}||}x(| D ]\}}|| }| | ||< qNW |S )zTConvert a dictionary of numbers to a 1d numpy array
    with optional mapping.

    r   N)	r9   r:   r;   r>   r?   r@   r   rA   r<   )r6   r7   r9   rC   rF   rG   rH   r   r   r   r   r5      s    
r5   c             C   s$   t | dpt | d}t| | ko"|S )zMReturns True if and only if the given object is an iterator
    object.

    __next__r   )r   r   )r   Zhas_next_attrr   r   r   is_iterator   s    rK   c             C   s   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::

        >>> arbitrary_element({3, 2, 1})
        1
        >>> arbitrary_element('hello')
        'h'

    This function raises a :exc:`ValueError` if `iterable` is an
    iterator (because the current implementation of this function would
    consume an element from the iterator)::

        >>> iterator = iter([1, 2, 3])
        >>> arbitrary_element(iterator)
        Traceback (most recent call last):
            ...
        ValueError: cannot return an arbitrary item from an iterator

    z0cannot return an arbitrary item from an iterator)rK   
ValueErrorr   r   )r
   r   r   r   arbitrary_element   s    rM   c             C   s   t | dd dS )zConsume the iterator entirely.r   )maxlenN)r   )iteratorr   r   r   consume   s    rP   Fc             C   s:   t | \}}t|d}|dkr0t|t||fS t||S )z&s -> (s0, s1), (s1, s2), (s2, s3), ...NT)r   r   r?   r   )r
   ZcyclicrG   bfirstr   r   r   pairwise   s
    
rS   c             C   s4   t t}x"|  D ]\}}|| | qW 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.

    For example::

        >>> 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: {'d', 'e'}}

    )r   r:   r<   addr>   )Zmany_to_oneZone_to_manyrE   rD   r   r   r   groups   s    rU   c             C   s    t | ttfs| S ttt| S )zConverts lists to tuples.

    For example::

        >>> from networkx.utils import to_tuple
        >>> a_list = [1, 2, [1, 4]]
        >>> to_tuple(a_list)
        (1, 2, (1, 4))

    )r   tupler   mapto_tuple)r#   r   r   r   rX     s    rX   c             C   s`   ddl }| dks| |jkr$|jjjS t| |jjr6| S t| trL|j| S d}t||  dS )a  Returns a numpy.random.RandomState instance depending on input.

    Parameters
    ----------
    random_state : int or RandomState instance or None  optional (default=None)
        If int, return a numpy.random.RandomState instance set with seed=int.
        if numpy.random.RandomState instance, return it.
        if None or numpy.random, return the global random number generator used
        by numpy.random.
    r   NzA%r cannot be used to generate a numpy.random.RandomState instance)r9   randommtrand_randr   RandomStater   rL   )random_statenpmsgr   r   r   create_random_state%  s    

r`   c               @   s   e Zd ZydddZW n$ ek
r:   dZeee Y nX 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 )PythonRandomInterfaceNc             C   s&   dd l }|d kr|jjj| _|| _d S )Nr   )r9   rY   rZ   r[   _rng)selfrngr9   r   r   r   __init__>  s    zPythonRandomInterface.__init__z.numpy not found, only random.random available.c             C   s
   | j  S )N)rb   random_sample)rc   r   r   r   rY   G  s    zPythonRandomInterface.randomc             C   s   ||| | j    S )N)rb   rf   )rc   rG   rQ   r   r   r   uniformJ  s    zPythonRandomInterface.uniformc             C   s   | j ||S )N)rb   randint)rc   rG   rQ   r   r   r   	randrangeM  s    zPythonRandomInterface.randrangec             C   s   || j dt| S )Nr   )rb   rh   r   )rc   seqr   r   r   choiceP  s    zPythonRandomInterface.choicec             C   s   | j ||S )N)rb   Znormal)rc   ZmuZsigmar   r   r   gaussS  s    zPythonRandomInterface.gaussc             C   s   | j |S )N)rb   shuffle)rc   rj   r   r   r   rm   V  s    zPythonRandomInterface.shufflec             C   s   | j jt||fddS )NF)sizereplace)rb   rk   r   )rc   rj   rD   r   r   r   sample\  s    zPythonRandomInterface.samplec             C   s   | j ||d S )N   )rb   rh   )rc   rG   rQ   r   r   r   rh   _  s    zPythonRandomInterface.randintc             C   s   | j d| S )Nrq   )rb   Zexponential)rc   Zscaler   r   r   expovariatec  s    z!PythonRandomInterface.expovariatec             C   s   | j |S )N)rb   Zpareto)rc   shaper   r   r   paretovariateg  s    z#PythonRandomInterface.paretovariate)N)N)__name__
__module____qualname__re   ImportErrorr_   warningswarnImportWarningrY   rg   ri   rk   rl   rm   rp   rh   rr   rt   r   r   r   r   ra   <  s   
ra   c             C   s   ddl }yLddl}| |j kr*t|j jjS t| |j jr@t| S t| trN| S d}W n tk
rl   d}Y nX | dks~| |kr|jS t| |j	r| S t| t
r|	| S d}t||  dS )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 instance, return it wrapped in
        PythonRandomInterface
        if a PythonRandomInterface instance, return it
    r   NTFz6%r cannot be used to generate a random.Random instance)rY   r9   ra   rZ   r[   r   r\   rx   Z_instZRandomr   rL   )r]   rY   r^   Z	has_numpyr_   r   r   r   create_py_random_stateu  s(    




r|   c             C   s2   ddl m} ydd l}W n   |dY nX d S )Nr   )SkipTestzNumPy not available)Znoser}   r9   )moduler}   r9   r   r   r   setup_module  s
    r   )N)N)N)N)F)N)N)+__doc__collectionsr   r   ry   r-   r%   	itertoolsr   r   ZnetworkxZnxr   rx   operatorrT   r   	NameErrorr"   r!   r   r
   r   r   version_infoZPY2r$   r&   r1   r8   r2   r5   rK   rM   rP   rS   rU   rX   r`   objectra   r|   r   r   r   r   r   <module>
   sP   






	
	
9
(