a
    Sic8                     @   sn   d Z ddlZddlmZ ddlmZmZ ddlmZm	Z	 dZ
dd Zd	d
 ZG dd dZdd Zdd ZdS )a  
Cycler
======

Cycling through combinations of values, producing dictionaries.

You can add cyclers::

    from cycler import cycler
    cc = (cycler(color=list('rgb')) +
          cycler(linestyle=['-', '--', '-.']))
    for d in cc:
        print(d)

Results in::

    {'color': 'r', 'linestyle': '-'}
    {'color': 'g', 'linestyle': '--'}
    {'color': 'b', 'linestyle': '-.'}


You can multiply cyclers::

    from cycler import cycler
    cc = (cycler(color=list('rgb')) *
          cycler(linestyle=['-', '--', '-.']))
    for d in cc:
        print(d)

Results in::

    {'color': 'r', 'linestyle': '-'}
    {'color': 'r', 'linestyle': '--'}
    {'color': 'r', 'linestyle': '-.'}
    {'color': 'g', 'linestyle': '-'}
    {'color': 'g', 'linestyle': '--'}
    {'color': 'g', 'linestyle': '-.'}
    {'color': 'b', 'linestyle': '-'}
    {'color': 'b', 'linestyle': '--'}
    {'color': 'b', 'linestyle': '-.'}
    N)reduce)productcycle)muladdz0.10.0c                 C   s`   | durt t| ni }|dur,t t|ni }t| }t| }||@ rXtd||B S )a  
    Helper function to compose cycler keys.

    Parameters
    ----------
    left, right : iterable of dictionaries or None
        The cyclers to be composed.

    Returns
    -------
    keys : set
        The keys in the composition of the two cyclers.
    Nz"Can not compose overlapping cycles)nextitersetkeys
ValueError)leftrightZl_peekZr_peekZl_keyr_key r   B/var/www/html/django/DPS/env/lib/python3.9/site-packages/cycler.py_process_keys4   s    r   c                    sZ   | j |j kr.tdj| j |j @ | j |j A d|   | tt fdd| j D S )aS  
    Concatenate `Cycler`\s, as if chained using `itertools.chain`.

    The keys must match exactly.

    Examples
    --------
    >>> num = cycler('a', range(3))
    >>> let = cycler('a', 'abc')
    >>> num.concat(let)
    cycler('a', [0, 1, 2, 'a', 'b', 'c'])

    Returns
    -------
    `Cycler`
        The concatenated cycler.
    zBKeys do not match:
	Intersection: {both!r}
	Disjoint: {just_one!r})bothZjust_onec                 3   s$   | ]}t | | |  V  qd S N_cycler.0k_l_rr   r   	<genexpr>e       zconcat.<locals>.<genexpr>)r
   r   formatby_keyr   r   )r   r   r   r   r   concatK   s    

r    c                   @   s   e Zd ZdZdd Zd+ddZdd Zed	d
 Zdd Z	e
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d Zdd  Zd!d" ZdZd#d$ Zd%d& Zd'd( ZeZd)d* ZeZdS ),Cyclera  
    Composable cycles.

    This class has compositions methods:

    ``+``
      for 'inner' products (zip)

    ``+=``
      in-place ``+``

    ``*``
      for outer products (`itertools.product`) and integer multiplication

    ``*=``
      in-place ``*``

    and supports basic slicing via ``[]``.

    Parameters
    ----------
    left, right : Cycler or None
        The 'left' and 'right' cyclers.
    op : func or None
        Function which composes the 'left' and 'right' cyclers.
    c                 C   s   t | S r   )r   selfr   r   r   __call__   s    zCycler.__call__Nc                 C   s   t |tr t|j|j|j| _n |dur:dd |D | _nd| _t |tr`t|j|j|j| _n |durzdd |D | _nd| _t| j| j| _|| _dS )zf
        Semi-private init.

        Do not use this directly, use `cycler` function instead.
        Nc                 S   s   g | ]}t  |qS r   copyr   vr   r   r   
<listcomp>   r   z#Cycler.__init__.<locals>.<listcomp>c                 S   s   g | ]}t  |qS r   r%   r'   r   r   r   r)      r   )
isinstancer!   _left_right_opr   _keys)r#   r   r   opr   r   r   __init__   s    

zCycler.__init__c                 C   s
   || j v S r   )r.   )r#   r   r   r   r   __contains__   s    zCycler.__contains__c                 C   s
   t | jS )z!The keys this Cycler knows about.)r	   r.   r"   r   r   r   r
      s    zCycler.keysc                    s    krdS  | j v r(tdj d| j vrDtdj d| j  | j   | jdur| jjv r| j  n4t	| j
tr| j
  n fdd| j
D | _
dS )a  
        Change a key in this cycler to a new name.
        Modification is performed in-place.

        Does nothing if the old key is the same as the new key.
        Raises a ValueError if the new key is already a key.
        Raises a KeyError if the old key isn't a key.
        Nz6Can't replace {old} with {new}, {new} is already a key)oldnewz2Can't replace {old} with {new}, {old} is not a keyc                    s   g | ]} | iqS r   r   )r   entryr3   r2   r   r   r)      r   z%Cycler.change_key.<locals>.<listcomp>)r.   r   r   KeyErrorremover   r,   r
   
change_keyr*   r+   r!   )r#   r2   r3   r   r5   r   r8      s&    	

zCycler.change_keyc                    s,   | d}t  fdd|D |_ h|_|S )a  
        Class method to create 'base' Cycler objects
        that do not have a 'right' or 'op' and for which
        the 'left' object is not another Cycler.

        Parameters
        ----------
        label : str
            The property key.

        itr : iterable
            Finite length iterable of the property values.

        Returns
        -------
        `Cycler`
            New 'base' cycler.
        Nc                 3   s   | ]} |iV  qd S r   r   r'   labelr   r   r      r   z$Cycler._from_iter.<locals>.<genexpr>)listr+   r.   )clsr:   itrretr   r9   r   
_from_iter   s    zCycler._from_iterc                    s:   t  tr.|  }tt fdd| D S tdd S )Nc                 3   s    | ]\}}t ||  V  qd S r   r   r   r   r(   keyr   r   r      r   z%Cycler.__getitem__.<locals>.<genexpr>z+Can only use slices with Cycler.__getitem__)r*   slicer   r   r   itemsr   )r#   rB   transr   rA   r   __getitem__   s    
zCycler.__getitem__c                 c   s^   | j d u r"| jD ]}t|V  qn8| | j| j D ]&\}}i }|| || |V  q2d S r   )r,   r+   dictr-   update)r#   r   aboutr   r   r   __iter__   s    



zCycler.__iter__c                 C   s8   t | t |kr,tdt |  dt | t| |tS )z
        Pair-wise combine two equal length cyclers (zip).

        Parameters
        ----------
        other : Cycler
        z&Can only add equal length cycles, not z and )lenr   r!   zipr#   otherr   r   r   __add__   s    zCycler.__add__c                    sL   t  trt|  tS t  trD|  }tt fdd| D S tS dS )z
        Outer product of two cyclers (`itertools.product`) or integer
        multiplication.

        Parameters
        ----------
        other : Cycler or int
        c                 3   s    | ]\}}t ||  V  qd S r   r   r@   rP   r   r   r     r   z!Cycler.__mul__.<locals>.<genexpr>N)	r*   r!   r   intr   r   r   rD   NotImplemented)r#   rP   rE   r   rR   r   __mul__  s    	

zCycler.__mul__c                 C   s   | | S r   r   rO   r   r   r   __rmul__  s    zCycler.__rmul__c                 C   sD   t ttti}| jd u r t| jS t| j}t| j}|| j ||S r   )rN   minr   r   r,   rM   r+   r-   )r#   op_dictZl_lenZr_lenr   r   r   __len__  s    



zCycler.__len__c                 C   sL   t |tstdt| }t||| _|| _t| _t|j|j	|j| _	| S )z
        In-place pair-wise combine two equal length cyclers (zip).

        Parameters
        ----------
        other : Cycler
        z"Cannot += with a non-Cycler object)
r*   r!   	TypeErrorr&   r   r.   r+   rN   r-   r,   r#   rP   Zold_selfr   r   r   __iadd__#  s    

zCycler.__iadd__c                 C   sL   t |tstdt| }t||| _|| _t| _t|j|j	|j| _	| S )z
        In-place outer product of two cyclers (`itertools.product`).

        Parameters
        ----------
        other : Cycler
        z"Cannot *= with a non-Cycler object)
r*   r!   rZ   r&   r   r.   r+   r   r-   r,   r[   r   r   r   __imul__5  s    

zCycler.__imul__c                 C   s<   t | t |krdS | j|jA r$dS tdd t| |D S )NFc                 s   s   | ]\}}||kV  qd S r   r   )r   rI   rJ   r   r   r   r   L  r   z Cycler.__eq__.<locals>.<genexpr>)rM   r
   allrN   rO   r   r   r   __eq__G  s
    zCycler.__eq__c                 C   s
   | |k S r   r   rO   r   r   r   __ne__N  s    zCycler.__ne__c                    sr   t dtdi}| jd u rH| j  t fdd| D }d d|dS || jd}d	}|j| j	|| jd
S d S )N+*c                 3   s   | ]}|  V  qd S r   r   r'   labr   r   r   W  r   z"Cycler.__repr__.<locals>.<genexpr>zcycler(z, )?z({left!r} {op} {right!r}))r   r/   r   )
rN   r   r,   r
   popr;   getr-   r   r+   )r#   op_mapr=   r/   msgr   rc   r   __repr__S  s    

zCycler.__repr__c                 C   st   d}t | jtd}|D ]}|d|d7 }qt| D ]2}|d7 }|D ]}|d|| d7 }qD|d7 }q4|d	7 }|S )
Nz<table>rA   z<th>z</th>z<tr>z<td>z</td>z</tr>z</table>)sortedr
   reprr   )r#   outputsorted_keysrB   dr   r   r   r   _repr_html_^  s    
zCycler._repr_html_c                 C   s>   | j }dd |D }| D ] }|D ]}|| ||  q q|S )a  
        Values by key.

        This returns the transposed values of the cycler.  Iterating
        over a `Cycler` yields dicts with a single value for each key,
        this method returns a `dict` of `list` which are the values
        for the given key.

        The returned value can be used to create an equivalent `Cycler`
        using only `+`.

        Returns
        -------
        transpose : dict
            dict of lists of the values for each key.
        c                 S   s   i | ]}|t  qS r   )r;   r   r   r   r   
<dictcomp>  r   z!Cycler.by_key.<locals>.<dictcomp>)r
   append)r#   r
   rK   rp   r   r   r   r   r   l  s    zCycler.by_keyc                 C   s    |   }ttdd | D S )z
        Simplify the cycler into a sum (but no products) of cyclers.

        Returns
        -------
        simple : Cycler
        c                 s   s   | ]\}}t ||V  qd S r   r   r@   r   r   r   r     r   z"Cycler.simplify.<locals>.<genexpr>)r   r   r   rD   )r#   rE   r   r   r   simplify  s    zCycler.simplify)NN)__name__
__module____qualname____doc__r$   r0   r1   propertyr
   r8   classmethodr?   rF   rL   rQ   rU   rV   rY   r\   r]   r_   r`   __hash__rk   rq   r   
_transposert   r    r   r   r   r   r!   h   s4   

$
r!   c                  O   s   | r|rt dt| dkr>t| d ts2t dt| d S t| dkrRt|  S t| dkrft d|rttdd | D S t d	d
S )a  
    Create a new `Cycler` object from a single positional argument,
    a pair of positional arguments, or the combination of keyword arguments.

    cycler(arg)
    cycler(label1=itr1[, label2=iter2[, ...]])
    cycler(label, itr)

    Form 1 simply copies a given `Cycler` object.

    Form 2 composes a `Cycler` as an inner product of the
    pairs of keyword arguments. In other words, all of the
    iterables are cycled simultaneously, as if through zip().

    Form 3 creates a `Cycler` from a label and an iterable.
    This is useful for when the label cannot be a keyword argument
    (e.g., an integer or a name that has a space in it).

    Parameters
    ----------
    arg : Cycler
        Copy constructor for Cycler (does a shallow copy of iterables).
    label : name
        The property key. In the 2-arg form of the function,
        the label can be any hashable object. In the keyword argument
        form of the function, it must be a valid python identifier.
    itr : iterable
        Finite length iterable of the property values.
        Can be a single-property `Cycler` that would
        be like a key change, but as a shallow copy.

    Returns
    -------
    cycler : Cycler
        New `Cycler` for the given property

    zBcyl() can only accept positional OR keyword arguments -- not both.   r   zDIf only one positional argument given, it must be a Cycler instance.   zdOnly a single Cycler can be accepted as the lone positional argument. Use keyword arguments instead.c                 s   s   | ]\}}t ||V  qd S r   r   r@   r   r   r   r     r   zcycler.<locals>.<genexpr>z4Must have at least a positional OR keyword argumentsN)rZ   rM   r*   r!   r   r   r   rD   )argskwargsr   r   r   cycler  s    &r   c                    sN   t |trB|j}t|dkr(d}t||   fdd|D }t| |S )aD  
    Create a new `Cycler` object from a property name and iterable of values.

    Parameters
    ----------
    label : hashable
        The property key.
    itr : iterable
        Finite length iterable of the property values.

    Returns
    -------
    cycler : Cycler
        New `Cycler` for the given property
    r}   z2Can not create Cycler from a multi-property Cyclerc                 3   s   | ]}|  V  qd S r   r   r'   rc   r   r   r     r   z_cycler.<locals>.<genexpr>)r*   r!   r
   rM   r   rg   r?   )r:   r=   r
   rj   r   rc   r   r     s    
r   )rx   r&   	functoolsr   	itertoolsr   r   operatorr   r   __version__r   r    r!   r   r   r   r   r   r   <module>   s   +  9;