
    
_d?                        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 Zd'dZd	 Zd(d
Zd(dZd ZefdZd ZeZd Zd Z d Z!d(dZ"d Z#	 ddlm$Z% d Z$e#j                   e$_         d(dZ'd Z(d Z)d Z*d(dZ+d(dZ,d(dZ-d)dZ.ddd Z/d(d!Z0d" Z1d# Z2d$ Z3d% Z4d& Z5y# e&$ r e#Z$Y @w xY w)*a  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                 ,    t        t        ||             S )zReturn 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iterables     K/usr/lib/python3/dist-packages/setuptools/_vendor/more_itertools/recipes.pyr+   r+   <   s     x#$$    c                 ,    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starts     r3   r)   r)   L   s     xu&&r4   c                 .    t        t        ||             S )zReturn an iterator over the last *n* items of *iterable*.

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

    maxlen)iterr   r0   s     r3   r*   r*   ^   s     hq)**r4   c                 R    |t        | d       yt        t        | ||      d       y)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   r:   )r   nextr	   )iteratorr1   s     r3   r   r   i   s)    @ 	yhq! 	VHa#T*r4   c                 0    t        t        | |d      |      S )zReturns the nth item or a default value.

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

    N)r>   r	   )r2   r1   defaults      r3   r   r      s     xD)733r4   c                 N    t        |       }t        |d      xr 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>   )r2   gs     r3   r   r      s(     	A4=/a//r4   c                 ,    t        t        ||             S )zcReturn the how many times the predicate is true.

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

    )sumr6   )r2   preds     r3   r"   r"      s     s4"##r4   c                 ,    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
   r2   s    r3   r   r      s     6$<((r4   c                 R    t        j                  t        t        |       |            S )zvReturns the sequence elements *n* times

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

    )r   from_iterabler
   tuple)r2   r1   s     r3   r   r      s      veHoq9::r4   c                 J    t        t        t        j                  | |            S )zcReturns the dot product of the two iterables.

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

    )rE   r6   operatormul)vec1vec2s     r3   r   r      s     s8<<t,--r4   c                 ,    t        j                  |       S )zReturn 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   rJ   )listOfListss    r3   r   r      s     {++r4   c                 \    |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]

    )r   r
   )functimesargss      r3   r'   r'      s.    , }tVD\**4e,--r4   c              #   l   K   t        |       \  }}t        |d       t        ||      E d{    y7 w)zReturns 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)r2   abs      r3   	_pairwiser[     s-      x=DAqDM1ays   *424)r   c              #   6   K   t        |       E d {    y 7 wN)itertools_pairwiserH   s    r3   r   r     s     %h///s   c                     t        | t              rt        j                  dt               | |} }t        |       g|z  }t        |d|iS )zCollect 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DeprecationWarningr<   r   )r2   r1   r`   rV   s       r3   r   r     sL     (C 9;M	
 8NaDT222r4   c               '      K   t        |       }t        d | D              }|r	 |D ]  } |         	 |ryy# t        $ r |dz  }t        t        ||            }Y *w xY ww)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              3   F   K   | ]  }t        |      j                    y wr]   )r<   __next__).0its     r3   	<genexpr>zroundrobin.<locals>.<genexpr>9  s     8$r(##8s   !   N)lenr   StopIterationr	   )	iterablespendingnextsr>   s       r3   r(   r(   ,  sn      )nG8i88E
	2 f   	2qLG&01E	2s*    A"9 A"A"#AA"AA"c                 j      t           fd|D        }t        |      \  }}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, ' '])

    c              3   2   K   | ]  } |      |f  y wr]    )ri   xrF   s     r3   rk   zpartition.<locals>.<genexpr>Z  s     2ADGQ<2s   c              3   ,   K   | ]  \  }}|r	|  y wr]   rt   ri   condru   s      r3   rk   zpartition.<locals>.<genexpr>]  s     +yad+   
c              3   ,   K   | ]  \  }}|s	|  y wr]   rt   rw   s      r3   rk   zpartition.<locals>.<genexpr>^  s     'ya$'ry   )boolr   )rF   r2   evaluationst1t2s   `    r3   r   r   C  sA    ( |22KFB+B+'B' r4   c                     t        |       t        j                  fdt        t	              dz         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   6   K   | ]  }t        |        y wr]   )r   )ri   rss     r3   rk   zpowerset.<locals>.<genexpr>v  s     Ma|Aq1Ms   rl   )r/   r   rJ   rangerm   )r2   r   s    @r3   r    r    b  s2    & 	XAM5Q!;LMMMr4   c              #      K   t               }|j                  }g }|j                  }|du}| D ]  }|r ||      n|}	 ||vr ||       | ! y# t        $ r ||vr ||       | Y >w xY ww)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)	r2   keyseensetseenset_addseenlistseenlist_adduse_keyelementks	            r3   r,   r,   y  s     6 eG++KH??LoG 	#CL	A	  	 Q	s(   :A/AA/A,)A/+A,,A/c           
      p    t        t        t        t        j                  d      t	        | |                  S )zYields 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']

    rl   )r6   r>   rM   
itemgetterr   )r2   r   s     r3   r-   r-     s*     tS,,Q/31GHIIr4   c              #   N   K   	 |	 |        	  |         
# |$ r Y yw xY w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]

    Nrt   )rT   	exceptionfirsts      r3   r   r     s8     'M&L  s   % "%"%c                 .    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)r2   rA   rF   s      r3   r   r     s    " tX&00r4   rl   )r
   c                 h    |D cg c]  }t        |       c}| z  }t        d |D              S c c}w )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              3   2   K   | ]  }t        |        y wr]   )r   )ri   pools     r3   rk   z!random_product.<locals>.<genexpr>  s     0$0s   )rK   )r
   rV   r   poolss       r3   r&   r&     s3      &**TU4[*V3E0%000 +s   /c                 `    t        |       }|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)``.

    )rK   rm   r   )r2   r   r   s      r3   r%   r%     s-     ?DYD	AAa!!r4   c                     t        |       t              }t        t        t	        |      |            }t        fd|D              S )zReturn 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   (   K   | ]	  }|     y wr]   rt   ri   ir   s     r3   rk   z%random_combination.<locals>.<genexpr>       *Qa*   )rK   rm   sortedr   r   )r2   r   r1   indicesr   s       @r3   r$   r$     s=     ?DD	AVE!Ha()G*'***r4   c                     t        |       t              t        fdt        |      D              }t        f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   4   K   | ]  }t                y wr]   )r   )ri   r   r1   s     r3   rk   z6random_combination_with_replacement.<locals>.<genexpr>  s     4aYq\4s   c              3   (   K   | ]	  }|     y wr]   rt   r   s     r3   rk   z6random_combination_with_replacement.<locals>.<genexpr>  r   r   )rK   rm   r   r   )r2   r   r   r1   r   s      @@r3   r#   r#     s<     ?DD	A45844G*'***r4   c                    t        |       }t        |      }|dk  s||kD  rt        d}t        |||z
        }t	        d|dz         D ]  }|||z
  |z   z  |z  } |dk  r||z  }|dk  s||k\  rt
        g }|rL||z  |z  |dz
  |dz
  }}}||k\  r||z  }|||z
  z  |z  |dz
  }}||k\  r|j                  |d|z
            |rLt        |      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   rl   )rK   rm   
ValueErrorminr   
IndexErrorr   )	r2   r   indexr   r1   cr   r   results	            r3   r   r   "  s    ?DD	A	A1q5	AAq1uA1a!e_ !QOq ! qy
	uzF
a%1*a!eQUa1qjQJEA;!#QUqA qj 	d26l#  =r4   c                     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?   s     r3   r!   r!   L  s     %(##r4   c              #     K   t        |      ddd   }t        |      }t        dg|      |z  }t        | t	        d|dz
              D ]9  }|j                  |       t        t        t        j                  ||             ; yw)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   r:   rl   )
rK   rm   r   r   r
   r   rE   r6   rM   rN   )signalkernelr1   windowru   s        r3   r   r   [  s{      6]4R4 FFAA3q!A%F66!QU+, 5a#hllFF3445s   BB)r   r]   )NN)6__doc__rc   collectionsr   	itertoolsr   r   r   r   r   r	   r
   r   r   r   rM   randomr   r   r   __all__r+   r)   r*   r   r   r   r{   r"   r   r   r   r   r   r'   r[   r   r^   ImportErrorr   r(   r   r    r,   r-   r   r   r&   r%   r$   r#   r   r!   r   rt   r4   r3   <module>r      s
        , ,B% '$+%+P
40 ! $) ;.	,.6	)8
0 !((H3 2.>N.*Z	J*1( "# 1("$+ +"'T$5S
  Hs   'B8 8CC