3
dW.                 @   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dd Zdd	 Zd
d Zd1ddZdd Zdd Zdd Zdd Zdd Zd2ddZd3ddZd4ddZdd Zd d! Zd"d# Zd5d%d&Zd'd( Zd)d* Zd6d+d,ZG d-d. d.Zd7d/d0Z dS )8a  
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_list_of_ints([1, 2, 3])
True
>>> networkx.utils.is_list_of_ints([1, 2, "spam"])
False
    )defaultdict)dequeN)teechainc             C   s   d}t j|t t| tS )zCheck if obj is string.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   7/tmp/pip-build-7vycvbft/networkx/networkx/utils/misc.py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   iterable&   s    
r   c               c   s   f E dH  dS )z$ Return a generator with no members Nr   r   r   r   r   empty_generator1   s    r   c             C   sb   t |  st| r| S |dkr"g }x4| D ],}t | s>t|rJ|j| q(t|| q(W | j|S )z@ Return flattened version of (possibly nested) iterable object. N)r   r   appendflatten	__class__)r   resultitemr   r   r   r   6   s    
r   c             C   s   t | tstg }x`| D ]X}d| }yt|}W n  tk
rN   tj|dY nX ||krbtj||j| qW |S xrt| D ]f\}}d| }t |trq~yt|}W n  tk
r   tj|dY nX ||krtj||| |< q~W | 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nxZNetworkXErrorr   	enumerate)sequencer   ierrmsgiiZindxr   r   r   make_list_of_intsD   s0    	






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	   r   r   )Zintlistr    r   r   r   is_list_of_intsh   s    


r$   c             C   s   d}t j|t t| S )z'Returns the string representation of t.zCmake_str is deprecated and will be removed in 3.0. Use str instead.)r   r   r   r
   )xr   r   r   r   make_strr   s    r&   c               C   s   t tj S )z Generate a unique node label.)r
   uuiduuid1r   r   r   r   generate_unique_nodey   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 )darwinlinuxZlinux2win32N)
subprocessr*   sysplatform)filenamer*   Zcmdscmdr   r   r   default_opener~   s    	r6   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    
r=   c             C   s   ddl }|dkrVt| j }x"| j D ]\}}|j|j  q&W tt|tt|}t|}|j	||f}xX|j D ]L\}}	xB|j 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)r;   r<   r>   skvnak1r    Zk2jr   r   r   r7      s    r7   c             C   sr   ddl }|dkr2t| j }tt|tt|}t|}|j|}x(|j D ]\}}|| }| | ||< qNW |S )zTConvert a dictionary of numbers to a 1d numpy array
    with optional mapping.

    r   N)	r>   r?   r@   rC   rD   rE   r   rF   rA   )r;   r<   r>   rH   rK   rL   rM   r    r   r   r   r:      s    
r:   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__next)r   iter)r   Zhas_next_attrr   r   r   is_iterator   s    rR   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)rR   r   rP   rQ   )r   r   r   r   arbitrary_element   s    rS   c             C   s   t | dd dS )zConsume the iterator entirely.r   )maxlenN)r   )iteratorr   r   r   consume   s    rV   Fc             C   s:   t | \}}t|d}|dkr0t|t||fS t||S )z&s -> (s0, s1), (s1, s2), (s2, s3), ...NT)r   rP   rD   r   )r   ZcyclicrL   bfirstr   r   r   pairwise   s
    
rY   c             C   s4   t t}x"| j D ]\}}|| j| 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?   rA   addrC   )Zmany_to_oneZone_to_manyrJ   rI   r   r   r   groups   s    r[   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   r^     s    r^   c             C   sb   ddl }| dks| |jkr$|jjjS t| |jjr6| S t| trL|j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   Nz? cannot be used to generate a numpy.random.RandomState instance)r>   randommtrand_randr	   RandomStater   r   )random_statenpr   r   r   r   create_random_state$  s    


re   c               @   s   e Zd ZydddZW n$ ek
r:   dZej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   )r>   r_   r`   ra   _rng)selfrngr>   r   r   r   __init__@  s    zPythonRandomInterface.__init__z.numpy not found, only random.random available.c             C   s
   | j j S )N)rg   random_sample)rh   r   r   r   r_   K  s    zPythonRandomInterface.randomc             C   s   ||| | j j   S )N)rg   rk   )rh   rL   rW   r   r   r   uniformN  s    zPythonRandomInterface.uniformc             C   s   | j j||S )N)rg   randint)rh   rL   rW   r   r   r   	randrangeQ  s    zPythonRandomInterface.randrangec             C   s   || j jdt| S )Nr   )rg   rm   r   )rh   seqr   r   r   choiceT  s    zPythonRandomInterface.choicec             C   s   | j j||S )N)rg   Znormal)rh   musigmar   r   r   gaussW  s    zPythonRandomInterface.gaussc             C   s   | j j|S )N)rg   shuffle)rh   ro   r   r   r   rt   Z  s    zPythonRandomInterface.shufflec             C   s   | j jt||fddS )NF)sizereplace)rg   rp   r   )rh   ro   rI   r   r   r   sample`  s    zPythonRandomInterface.samplec             C   s   | j j||d S )N   )rg   rm   )rh   rL   rW   r   r   r   rm   c  s    zPythonRandomInterface.randintc             C   s   | j jd| S )Nrx   )rg   Zexponential)rh   Zscaler   r   r   expovariateg  s    z!PythonRandomInterface.expovariatec             C   s   | j j|S )N)rg   Zpareto)rh   shaper   r   r   paretovariatek  s    z#PythonRandomInterface.paretovariate)N)N)__name__
__module____qualname__rj   ImportErrorr   r   r   ImportWarningr_   rl   rn   rp   rs   rt   rw   rm   ry   r{   r   r   r   r   rf   =  s   
rf   c             C   s   ddl }yHddl}| |j kr*t|j jjS t| |j jr@t| S t| trN| S W n tk
rd   Y nX | dksv| |kr||jS t| |j	r| S t| t
r|j	| 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   Nz4 cannot be used to generate a random.Random instance)r_   r>   rf   r`   ra   r	   rb   r   _instRandomr   r   )rc   r_   rd   r   r   r   r   create_py_random_statez  s&    




r   )N)N)N)N)F)N)N)!__doc__collectionsr   r   r   r2   r'   	itertoolsr   r   Znetworkxr   r   r   r   r   r#   r$   r&   r)   r6   r=   r7   r:   rR   rS   rV   rY   r[   r^   re   rf   r   r   r   r   r   <module>   s8   

$



	
	
=