o
    ƒ_¶a€?  ã                   @   sª  d Z ddlZddlmZ ddlmZmZmZmZm	Z	m
Z
mZmZmZmZ ddlZddlmZmZmZ g d¢Zdd„ ZdDd	d
„Zdd„ ZdEdd„ZdEdd„Zdd„ Zefdd„Zdd„ ZeZdd„ Zdd„ Z dd„ Z!dEdd„Z"dd „ Z#zdd!lm$Z% W n e&y…   e#Z$Y n	w d"d#„ Z$e#j e$_ dEd$d%„Z'd&d'„ Z(d(d)„ Z)d*d+„ Z*dEd,d-„Z+dEd.d/„Z,dEd0d1„Z-dFd2d3„Z.d4d5œd6d7„Z/dEd8d9„Z0d:d;„ Z1d<d=„ Z2d>d?„ Z3d@dA„ Z4dBdC„ Z5dS )Ga  Imported from the recipes section of the itertools documentation.

All functions taken from the recipes section of the itertools library docs
[1]_.
Some backward-compatible usability improvements have been made.

.. [1] http://docs.python.org/library/itertools.html#recipes

é    N)Údeque)
ÚchainÚcombinationsÚcountÚcycleÚgroupbyÚisliceÚrepeatÚstarmapÚteeÚzip_longest)Ú	randrangeÚsampleÚchoice)Ú	all_equalÚconsumeÚconvolveÚ
dotproductÚ
first_trueÚflattenÚgrouperÚiter_exceptÚncyclesÚnthÚnth_combinationÚpadnoneÚpad_noneÚpairwiseÚ	partitionÚpowersetÚprependÚquantifyÚ#random_combination_with_replacementÚrandom_combinationÚrandom_permutationÚrandom_productÚ
repeatfuncÚ
roundrobinÚtabulateÚtailÚtakeÚunique_everseenÚunique_justseenc                 C   ó   t t|| ƒƒS )zñReturn first *n* items of the iterable as a list.

        >>> take(3, range(10))
        [0, 1, 2]

    If there are fewer than *n* items in the iterable, all of them are
    returned.

        >>> take(10, range(3))
        [0, 1, 2]

    )Úlistr   ©ÚnÚiterable© r2   úK/usr/lib/python3/dist-packages/setuptools/_vendor/more_itertools/recipes.pyr*   <   s   r*   c                 C   s   t | t|ƒƒS )a©  Return an iterator over the results of ``func(start)``,
    ``func(start + 1)``, ``func(start + 2)``...

    *func* should be a function that accepts one integer argument.

    If *start* is not specified it defaults to 0. It will be incremented each
    time the iterator is advanced.

        >>> square = lambda x: x ** 2
        >>> iterator = tabulate(square, -3)
        >>> take(4, iterator)
        [9, 4, 1, 0]

    )Úmapr   )ÚfunctionÚstartr2   r2   r3   r(   L   s   r(   c                 C   s   t t|| d�ƒS )zƒReturn an iterator over the last *n* items of *iterable*.

    >>> t = tail(3, 'ABCDEFG')
    >>> list(t)
    ['E', 'F', 'G']

    ©Úmaxlen)Úiterr   r/   r2   r2   r3   r)   ^   s   r)   c                 C   s.   |du rt | dd� dS tt| ||ƒdƒ dS )aX  Advance *iterable* by *n* steps. If *n* is ``None``, consume it
    entirely.

    Efficiently exhausts an iterator without returning values. Defaults to
    consuming the whole iterator, but an optional second argument may be
    provided to limit consumption.

        >>> i = (x for x in range(10))
        >>> next(i)
        0
        >>> consume(i, 3)
        >>> next(i)
        4
        >>> consume(i)
        >>> next(i)
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        StopIteration

    If the iterator has fewer items remaining than the provided limit, the
    whole iterator will be consumed.

        >>> i = (x for x in range(3))
        >>> consume(i, 5)
        >>> next(i)
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        StopIteration

    Nr   r7   )r   Únextr   )Úiteratorr0   r2   r2   r3   r   i   s    r   c                 C   s   t t| |dƒ|ƒS )z…Returns the nth item or a default value.

    >>> l = range(10)
    >>> nth(l, 3)
    3
    >>> nth(l, 20, "zebra")
    'zebra'

    N)r:   r   )r1   r0   Údefaultr2   r2   r3   r   ‘   s   
r   c                 C   s   t | ƒ}t|dƒot|dƒ S )z 
    Returns ``True`` if all the elements are equal to each other.

        >>> all_equal('aaaa')
        True
        >>> all_equal('aaab')
        False

    TF)r   r:   )r1   Úgr2   r2   r3   r   ž   s   
r   c                 C   r-   )zcReturn the how many times the predicate is true.

    >>> quantify([True, False, True])
    2

    )Úsumr4   )r1   Úpredr2   r2   r3   r!   ¬   s   r!   c                 C   s   t | tdƒƒS )a   Returns the sequence of elements and then returns ``None`` indefinitely.

        >>> take(5, pad_none(range(3)))
        [0, 1, 2, None, None]

    Useful for emulating the behavior of the built-in :func:`map` function.

    See also :func:`padded`.

    N)r   r	   ©r1   r2   r2   r3   r   ¶   s   r   c                 C   s   t  tt| ƒ|ƒ¡S )zvReturns the sequence elements *n* times

    >>> list(ncycles(["a", "b"], 3))
    ['a', 'b', 'a', 'b', 'a', 'b']

    )r   Úfrom_iterabler	   Útuple)r1   r0   r2   r2   r3   r   Ç   s   r   c                 C   s   t ttj| |ƒƒS )zcReturns the dot product of the two iterables.

    >>> dotproduct([10, 10], [20, 20])
    400

    )r>   r4   ÚoperatorÚmul)Úvec1Úvec2r2   r2   r3   r   Ñ   s   r   c                 C   s
   t  | ¡S )zÜReturn an iterator flattening one level of nesting in a list of lists.

        >>> list(flatten([[0, 1], [2, 3]]))
        [0, 1, 2, 3]

    See also :func:`collapse`, which can flatten multiple levels of nesting.

    )r   rA   )ÚlistOfListsr2   r2   r3   r   Û   s   
	r   c                 G   s&   |du rt | t|ƒƒS t | t||ƒƒS )aG  Call *func* with *args* repeatedly, returning an iterable over the
    results.

    If *times* is specified, the iterable will terminate after that many
    repetitions:

        >>> from operator import add
        >>> times = 4
        >>> args = 3, 5
        >>> list(repeatfunc(add, times, *args))
        [8, 8, 8, 8]

    If *times* is ``None`` the iterable will not terminate:

        >>> from random import randrange
        >>> times = None
        >>> args = 1, 11
        >>> take(6, repeatfunc(randrange, times, *args))  # doctest:+SKIP
        [2, 4, 8, 1, 8, 4]

    N)r
   r	   )ÚfuncÚtimesÚargsr2   r2   r3   r&   ç   s   r&   c                 c   s,   � t | ƒ\}}t|dƒ t||ƒE dH  dS )zâReturns an iterator of paired items, overlapping, from the original

    >>> take(4, pairwise(count()))
    [(0, 1), (1, 2), (2, 3), (3, 4)]

    On Python 3.10 and above, this is an alias for :func:`itertools.pairwise`.

    N)r   r:   Úzip)r1   ÚaÚbr2   r2   r3   Ú	_pairwise  s   €	
rN   )r   c                 c   s   � t | ƒE d H  d S ©N)Úitertools_pairwiser@   r2   r2   r3   r     s   €r   c                 C   s<   t | tƒrt dt¡ | |}} t| ƒg| }t|d|iŽS )z˜Collect data into fixed-length chunks or blocks.

    >>> list(grouper('ABCDEFG', 3, 'x'))
    [('A', 'B', 'C'), ('D', 'E', 'F'), ('G', 'x', 'x')]

    z+grouper expects iterable as first parameterÚ	fillvalue)Ú
isinstanceÚintÚwarningsÚwarnÚDeprecationWarningr9   r   )r1   r0   rQ   rJ   r2   r2   r3   r     s   
ÿ
r   c                  g   sl   � t | ƒ}tdd„ | D ƒƒ}|r4z|D ]}|ƒ V  qW n ty/   |d8 }tt||ƒƒ}Y nw |sdS dS )aJ  Yields an item from each iterable, alternating between them.

        >>> list(roundrobin('ABC', 'D', 'EF'))
        ['A', 'D', 'E', 'B', 'F', 'C']

    This function produces the same output as :func:`interleave_longest`, but
    may perform better for some inputs (in particular when the number of
    iterables is small).

    c                 s   s   � | ]}t |ƒjV  qd S rO   )r9   Ú__next__)Ú.0Úitr2   r2   r3   Ú	<genexpr>9  ó   € zroundrobin.<locals>.<genexpr>é   N)Úlenr   ÚStopIterationr   )Ú	iterablesÚpendingÚnextsr:   r2   r2   r3   r'   ,  s   €
ÿþür'   c                    sF   ˆ du rt ‰ ‡ fdd„|D ƒ}t|ƒ\}}dd„ |D ƒdd„ |D ƒfS )a¯  
    Returns a 2-tuple of iterables derived from the input iterable.
    The first yields the items that have ``pred(item) == False``.
    The second yields the items that have ``pred(item) == True``.

        >>> is_odd = lambda x: x % 2 != 0
        >>> iterable = range(10)
        >>> even_items, odd_items = partition(is_odd, iterable)
        >>> list(even_items), list(odd_items)
        ([0, 2, 4, 6, 8], [1, 3, 5, 7, 9])

    If *pred* is None, :func:`bool` is used.

        >>> iterable = [0, 1, False, True, '', ' ']
        >>> false_items, true_items = partition(None, iterable)
        >>> list(false_items), list(true_items)
        ([0, False, ''], [1, True, ' '])

    Nc                 3   s   � | ]	}ˆ |ƒ|fV  qd S rO   r2   )rX   Úx©r?   r2   r3   rZ   Z  ó   € zpartition.<locals>.<genexpr>c                 s   s   � | ]	\}}|s|V  qd S rO   r2   ©rX   Úcondrb   r2   r2   r3   rZ   ]  rd   c                 s   s   � | ]	\}}|r|V  qd S rO   r2   re   r2   r2   r3   rZ   ^  rd   )Úboolr   )r?   r1   ÚevaluationsÚt1Út2r2   rc   r3   r   C  s   þr   c                    s,   t | ƒ‰ t ‡ fdd„ttˆ ƒd ƒD ƒ¡S )aœ  Yields all possible subsets of the iterable.

        >>> list(powerset([1, 2, 3]))
        [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]

    :func:`powerset` will operate on iterables that aren't :class:`set`
    instances, so repeated elements in the input will produce repeated elements
    in the output. Use :func:`unique_everseen` on the input to avoid generating
    duplicates:

        >>> seq = [1, 1, 0]
        >>> list(powerset(seq))
        [(), (1,), (1,), (0,), (1, 1), (1, 0), (1, 0), (1, 1, 0)]
        >>> from more_itertools import unique_everseen
        >>> list(powerset(unique_everseen(seq)))
        [(), (1,), (0,), (1, 0)]

    c                 3   s   � | ]}t ˆ |ƒV  qd S rO   )r   )rX   Úr©Úsr2   r3   rZ   v  r[   zpowerset.<locals>.<genexpr>r\   )r.   r   rA   Úranger]   r@   r2   rl   r3   r   b  s   $r   c           	   	   c   s€   � t ƒ }|j}g }|j}|du}| D ]+}|r||ƒn|}z||vr(||ƒ |V  W q ty=   ||vr;||ƒ |V  Y qw dS )a•  
    Yield unique elements, preserving order.

        >>> list(unique_everseen('AAAABBBCCDAABBB'))
        ['A', 'B', 'C', 'D']
        >>> list(unique_everseen('ABBCcAD', str.lower))
        ['A', 'B', 'C', 'D']

    Sequences with a mix of hashable and unhashable items can be used.
    The function will be slower (i.e., `O(n^2)`) for unhashable items.

    Remember that ``list`` objects are unhashable - you can use the *key*
    parameter to transform the list to a tuple (which is hashable) to
    avoid a slowdown.

        >>> iterable = ([1, 2], [2, 3], [1, 2])
        >>> list(unique_everseen(iterable))  # Slow
        [[1, 2], [2, 3]]
        >>> list(unique_everseen(iterable, key=tuple))  # Faster
        [[1, 2], [2, 3]]

    Similary, you may want to convert unhashable ``set`` objects with
    ``key=frozenset``. For ``dict`` objects,
    ``key=lambda x: frozenset(x.items())`` can be used.

    N)ÚsetÚaddÚappendÚ	TypeError)	r1   ÚkeyÚseensetÚseenset_addÚseenlistÚseenlist_addÚuse_keyÚelementÚkr2   r2   r3   r+   y  s(   €€€ýúr+   c                 C   s   t tt t d¡t| |ƒƒƒS )záYields elements in order, ignoring serial duplicates

    >>> list(unique_justseen('AAAABBBCCDAABBB'))
    ['A', 'B', 'C', 'D', 'A', 'B']
    >>> list(unique_justseen('ABBCcAD', str.lower))
    ['A', 'B', 'C', 'A', 'D']

    r\   )r4   r:   rC   Ú
itemgetterr   )r1   rs   r2   r2   r3   r,   ¦  s   	r,   c                 c   s4   � z|dur
|ƒ V  	 | ƒ V  q |y   Y dS w )aX  Yields results from a function repeatedly until an exception is raised.

    Converts a call-until-exception interface to an iterator interface.
    Like ``iter(func, sentinel)``, but uses an exception instead of a sentinel
    to end the loop.

        >>> l = [0, 1, 2]
        >>> list(iter_except(l.pop, IndexError))
        [2, 1, 0]

    Nr2   )rH   Ú	exceptionÚfirstr2   r2   r3   r   ²  s   €ÿÿr   c                 C   s   t t|| ƒ|ƒS )a�  
    Returns the first true value in the iterable.

    If no true value is found, returns *default*

    If *pred* is not None, returns the first item for which
    ``pred(item) == True`` .

        >>> first_true(range(10))
        1
        >>> first_true(range(10), pred=lambda x: x > 5)
        6
        >>> first_true(range(10), default='missing', pred=lambda x: x > 9)
        'missing'

    )r:   Úfilter)r1   r<   r?   r2   r2   r3   r   Ç  s   r   r\   )r	   c                 G   s$   dd„ |D ƒ|  }t dd„ |D ƒƒS )aÇ  Draw an item at random from each of the input iterables.

        >>> random_product('abc', range(4), 'XYZ')  # doctest:+SKIP
        ('c', 3, 'Z')

    If *repeat* is provided as a keyword argument, that many items will be
    drawn from each iterable.

        >>> random_product('abcd', range(4), repeat=2)  # doctest:+SKIP
        ('a', 2, 'd', 3)

    This equivalent to taking a random selection from
    ``itertools.product(*args, **kwarg)``.

    c                 S   s   g | ]}t |ƒ‘qS r2   ©rB   ©rX   Úpoolr2   r2   r3   Ú
<listcomp>ë  s    z"random_product.<locals>.<listcomp>c                 s   s   � | ]}t |ƒV  qd S rO   )r   r€   r2   r2   r3   rZ   ì  ó   € z!random_product.<locals>.<genexpr>r   )r	   rJ   Úpoolsr2   r2   r3   r%   Û  s   r%   c                 C   s*   t | ƒ}|du rt|ƒn|}t t||ƒƒS )ab  Return a random *r* length permutation of the elements in *iterable*.

    If *r* is not specified or is ``None``, then *r* defaults to the length of
    *iterable*.

        >>> random_permutation(range(5))  # doctest:+SKIP
        (3, 4, 0, 1, 2)

    This equivalent to taking a random selection from
    ``itertools.permutations(iterable, r)``.

    N)rB   r]   r   )r1   rk   r�   r2   r2   r3   r$   ï  s   r$   c                    s8   t | ƒ‰ tˆ ƒ}ttt|ƒ|ƒƒ}t ‡ fdd„|D ƒƒS )zÿReturn a random *r* length subsequence of the elements in *iterable*.

        >>> random_combination(range(5), 3)  # doctest:+SKIP
        (2, 3, 4)

    This equivalent to taking a random selection from
    ``itertools.combinations(iterable, r)``.

    c                 3   ó   � | ]}ˆ | V  qd S rO   r2   ©rX   Úi©r�   r2   r3   rZ     rƒ   z%random_combination.<locals>.<genexpr>)rB   r]   Úsortedr   rn   )r1   rk   r0   Úindicesr2   rˆ   r3   r#     s   
r#   c                    s@   t | ƒ‰tˆƒ‰ t‡ fdd„t|ƒD ƒƒ}t ‡fdd„|D ƒƒS )aS  Return a random *r* length subsequence of elements in *iterable*,
    allowing individual elements to be repeated.

        >>> random_combination_with_replacement(range(3), 5) # doctest:+SKIP
        (0, 0, 1, 2, 2)

    This equivalent to taking a random selection from
    ``itertools.combinations_with_replacement(iterable, r)``.

    c                 3   s   � | ]}t ˆ ƒV  qd S rO   )r   r†   )r0   r2   r3   rZ     rƒ   z6random_combination_with_replacement.<locals>.<genexpr>c                 3   r…   rO   r2   r†   rˆ   r2   r3   rZ     rƒ   )rB   r]   r‰   rn   )r1   rk   rŠ   r2   )r0   r�   r3   r"     s   r"   c           	      C   sú   t | ƒ}t|ƒ}|dk s||krt‚d}t||| ƒ}td|d ƒD ]}||| |  | }q"|dk r7||7 }|dk s?||krAt‚g }|ry|| | |d |d }}}||krn||8 }|||  | |d }}||ksY| |d|  ¡ |sEt |ƒS )a  Equivalent to ``list(combinations(iterable, r))[index]``.

    The subsequences of *iterable* that are of length *r* can be ordered
    lexicographically. :func:`nth_combination` computes the subsequence at
    sort position *index* directly, without computing the previous
    subsequences.

        >>> nth_combination(range(5), 3, 5)
        (0, 3, 4)

    ``ValueError`` will be raised If *r* is negative or greater than the length
    of *iterable*.
    ``IndexError`` will be raised if the given *index* is invalid.
    r   r\   éÿÿÿÿ)rB   r]   Ú
ValueErrorÚminrn   Ú
IndexErrorrq   )	r1   rk   Úindexr�   r0   Úcrz   r‡   Úresultr2   r2   r3   r   "  s,    þûr   c                 C   s   t | g|ƒS )a  Yield *value*, followed by the elements in *iterator*.

        >>> value = '0'
        >>> iterator = ['1', '2', '3']
        >>> list(prepend(value, iterator))
        ['0', '1', '2', '3']

    To prepend multiple values, see :func:`itertools.chain`
    or :func:`value_chain`.

    )r   )Úvaluer;   r2   r2   r3   r    L  s   r    c                 c   sj   � t |ƒddd… }t|ƒ}tdg|d�| }t| td|d ƒƒD ]}| |¡ tttj	||ƒƒV  q!dS )aB  Convolve the iterable *signal* with the iterable *kernel*.

        >>> signal = (1, 2, 3, 4, 5)
        >>> kernel = [3, 2, 1]
        >>> list(convolve(signal, kernel))
        [3, 8, 14, 20, 26, 14, 5]

    Note: the input arguments are not interchangeable, as the *kernel*
    is immediately consumed and stored.

    Nr‹   r   r7   r\   )
rB   r]   r   r   r	   rq   r>   r4   rC   rD   )ÚsignalÚkernelr0   Úwindowrb   r2   r2   r3   r   [  s   €
þr   )r   rO   )NN)6Ú__doc__rT   Úcollectionsr   Ú	itertoolsr   r   r   r   r   r   r	   r
   r   r   rC   Úrandomr   r   r   Ú__all__r*   r(   r)   r   r   r   rg   r!   r   r   r   r   r   r&   rN   r   rP   ÚImportErrorr   r'   r   r   r+   r,   r   r   r%   r$   r#   r"   r   r    r   r2   r2   r2   r3   Ú<module>   sV    	0!


(



ÿ


-


*