
    a8                     t    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 Zd Z G d	 d
          Zd Z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                 8   | t          t          |                     ni }|t          t          |                    ni }t          |                                          }t          |                                          }||z  rt	          d          ||z  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rightl_peekr_peekl_keyr_keys         &lib/python3.11/site-packages/cycler.py_process_keysr   4   s     "&!1T$t**rF"'"3T$u++FEEu} ?=>>>5=    c                 @   | j         |j         k    r>t          d                    | j         |j         z  | j         |j         z                      |                                 |                                t	          t
          f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})bothjust_onec              3   V   K   | ]#}t          ||         |         z             V  $d S N_cycler).0k_l_rs     r   	<genexpr>zconcat.<locals>.<genexpr>e   s9      EEa2a52a5=11EEEEEEr   )r   r   formatby_keyr   r   )r   r   r    r!   s     @@r   concatr%   K   s    $ yEJ 44:F"&)ej"8&*i%*&< 5; 5> 5>? ? 	?
 
B	B#EEEEE49EEEFFFr   c                       e Zd ZdZd ZddZd Zed             Zd Z	e
d             Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd ZdZd Zd Zd ZeZ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                      t          |           S r   )r   selfs    r   __call__zCycler.__call__   s    T{{r   Nc                    t          |t                    r&t          |j        |j        |j                  | _        n|d |D             | _        nd| _        t          |t                    r&t          |j        |j        |j                  | _        n|d |D             | _        nd| _        t          | j        | j                  | _        || _        dS )zf
        Semi-private init.

        Do not use this directly, use `cycler` function instead.
        Nc                 6    g | ]}t          j         |          S  copyr   vs     r   
<listcomp>z#Cycler.__init__.<locals>.<listcomp>   s     5551$)A,,555r   c                 6    g | ]}t          j         |          S r.   r/   r1   s     r   r3   z#Cycler.__init__.<locals>.<listcomp>   s     777A49Q<<777r   )
isinstancer'   _left_right_opr   _keys)r*   r   r   ops       r   __init__zCycler.__init__   s     dF## 	
DKBBDJJ 65555DJJDJeV$$ 	 elEIFFDKK 87777DKKDK"4:t{;;
r   c                     || j         v S r   )r9   )r*   r   s     r   __contains__zCycler.__contains__   s    DJr   c                 *    t          | j                  S )z!The keys this Cycler knows about.)r   r9   r)   s    r   r   zCycler.keys   s     4:r   c                 :   k    rdS | j         v r$t          d                                        | j         vr$t          d                                        | j                                        | j                                        | j        +| j        j        v r| j                                       dS t          | j
        t                    r| j
                                       dS f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                 $    g | ]}|         iS r.   r.   )r   entryrA   r@   s     r   r3   z%Cycler.change_key.<locals>.<listcomp>   s"    DDD3c
+DDDr   )r9   r   r#   KeyErrorremover   r7   r   
change_keyr5   r6   r'   )r*   r@   rA   s    ``r   rF   zCycler.change_key   s9    #::F$*HCS))   dj  O"FsF446 6 6 	
#
s;"sdk.>'>'>K""3,,,,, 
F++ 	EJ!!#s+++++
 EDDDDDDDDJJJr   c                 n     | d          }t          f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       K   | ]}|iV  	d S r   r.   )r   r2   labels     r   r"   z$Cycler._from_iter.<locals>.<genexpr>   s'      11%111111r   )listr6   r9   )clsrI   itrrets    `  r   
_from_iterzCycler._from_iter   sD    ( c$ii1111S11111	G	
r   c                     t          t                    rG|                                 }t          t          fd|                                D                       S t          d          )Nc              3   J   K   | ]\  }}t          ||                   V  d S r   r   )r   r   r2   keys      r   r"   z%Cycler.__getitem__.<locals>.<genexpr>   s5      MMtq!1S6 2 2MMMMMMr   z+Can only use slices with Cycler.__getitem__)r5   slicer$   r   r   itemsr   )r*   rQ   transs    ` r   __getitem__zCycler.__getitem__   s_    c5!! 	LKKMME#MMMMu{{}}MMMNNNJKKKr   c              #      K   | j         | j        D ]}t          |          V  d S |                     | j        | j                   D ]5\  }}i }|                    |           |                    |           |V  6d S r   )r7   r6   dictr8   update)r*   r   abouts        r   __iter__zCycler.__iter__   s      ;
 ! !4jj    ! ! T[99  1

1

1					 r   c                     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*   others     r   __add__zCycler.__add__   sr     t99E

"" A$'IIA A47JJA A B B BdE3'''r   c                     t          t                    rt          | t                    S t          t                    rG|                                 }t          t          fd|                                D                       S t          S )z
        Outer product of two cyclers (`itertools.product`) or integer
        multiplication.

        Parameters
        ----------
        other : Cycler or int
        c              3   D   K   | ]\  }}t          ||z            V  d S r   r   )r   r   r2   ra   s      r   r"   z!Cycler.__mul__.<locals>.<genexpr>  s5      NN11U7 3 3NNNNNNr   )	r5   r'   r   intr$   r   r   rS   NotImplemented)r*   ra   rT   s    ` r   __mul__zCycler.__mul__  s{     eV$$ 	"$w///s## 	"KKMME#NNNNNNNOOO!!r   c                     | |z  S r   r.   r`   s     r   __rmul__zCycler.__rmul__  s    e|r   c                     t           t          t          t          i}| j        t          | j                  S t          | j                  }t          | j                  } || j                 ||          S r   )r_   minr   r   r7   r^   r6   r8   )r*   op_dictl_lenr_lens       r   __len__zCycler.__len__  s[    Wc*;tz??"DJDK   wtx ...r   c                    t          |t                    st          d          t          j        |           }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)
r5   r'   	TypeErrorr0   r   r9   r6   r_   r8   r7   r*   ra   old_selfs      r   __iadd__zCycler.__iadd__#  sp     %(( 	B@AAA9T??"8U33

U[%,	BBr   c                    t          |t                    st          d          t          j        |           }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)
r5   r'   rq   r0   r   r9   r6   r   r8   r7   rr   s      r   __imul__zCycler.__imul__5  sp     %(( 	B@AAA9T??"8U33

U[%,	BBr   c                     t          |           t          |          k    rdS | j        |j        z  rdS t          d t          | |          D                       S )NFc              3   (   K   | ]\  }}||k    V  d S r   r.   )r   rY   rZ   s      r   r"   z Cycler.__eq__.<locals>.<genexpr>L  s*      77da16777777r   )r^   r   allr_   r`   s     r   __eq__zCycler.__eq__G  s[    t99E

""59uz! 	577c$&6&6777777r   c                     | |k     S r   r.   r`   s     r   __ne__zCycler.__ne__N  s    EM""r   c                 *   t           dt          di}| j        =| j                                        t          fd| D                       }dd|dS |                    | j        d          }d}|                    | j	        || j        	          S )
N+*c              3   (   K   | ]}|         V  d S r   r.   r   r2   labs     r   r"   z"Cycler.__repr__.<locals>.<genexpr>W  s'      ,,!qv,,,,,,r   zcycler(z, )?z({left!r} {op} {right!r}))r   r:   r   )
r_   r   r7   r   poprJ   getr8   r#   r6   )r*   op_maprL   r:   msgr   s        @r   __repr__zCycler.__repr__S  s    sGS);)--//C,,,,t,,,,,C.S..c....DHc**B-C::4:"DK:HHHr   c                     d}t          | j        t                    }|D ]}|d|dz  }t          |           D ] }|dz  }|D ]}|d||         dz  }|dz  }!|d	z  }|S )
Nz<table>)rQ   z<th>z</th>z<tr>z<td>z</td>z</tr>z</table>)sortedr   reprr
   )r*   outputsorted_keysrQ   dr   s         r   _repr_html_zCycler._repr_html_^  s    TYD111 	* 	*C)S))))FFd 	 	AfF  / /.1....gFF*r   c                     | j         }d |D             }| D ](}|D ]#}||                             ||                    $)|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                 ,    i | ]}|t                      S r.   )rJ   )r   r   s     r   
<dictcomp>z!Cycler.by_key.<locals>.<dictcomp>  s    '''Qq$&&'''r   )r   append)r*   r   r[   r   r   s        r   r$   zCycler.by_keyl  sc    * y''$''' 	$ 	$A $ $Aad####$
r   c                     |                                  }t          t          d |                                D                       S )z
        Simplify the cycler into a sum (but no products) of cyclers.

        Returns
        -------
        simple : Cycler
        c              3   <   K   | ]\  }}t          ||          V  d S r   r   r   r   r2   s      r   r"   z"Cycler.simplify.<locals>.<genexpr>  s.      DDdaGAqMMDDDDDDr   )r$   r   r   rS   )r*   rT   s     r   simplifyzCycler.simplify  s8     cDDekkmmDDDEEEr   )NN)__name__
__module____qualname____doc__r+   r;   r=   propertyr   rF   classmethodrN   rU   r\   rb   rg   ri   ro   rt   rv   rz   r|   __hash__r   r   r$   
_transposer   r%   r.   r   r   r'   r'   h   s        6     6     X"E "E "EH   [0L L L	 	 	( ( (" " ""  / / /  $  $8 8 8# # # H	I 	I 	I    < JF F F  FFFr   r'   c                     | r|rt          d          t          |           dk    r?t          | d         t                    st          d          t          | d                   S t          |           dk    r	t	          |  S t          |           dk    rt          d          |r1t          t          d |                                D                       S t          d          )	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              3   <   K   | ]\  }}t          ||          V  d S r   r   r   s      r   r"   zcycler.<locals>.<genexpr>  s.      EEdaGAqMMEEEEEEr   z4Must have at least a positional OR keyword arguments)rq   r^   r5   r'   r   r   r   rS   )argskwargss     r   cyclerr     s    L  2 2 1 2 2 	2 4yyA~~$q'6** 	5 4 5 5 5d1g	Ta~	TQ N O O 	O  GcEEfllnnEEEFFF
J
K
KKr   c                     t          |t                    rM|j        }t          |          dk    rd}t	          |          |                                f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   (   K   | ]}|         V  d S r   r.   r   s     r   r"   z_cycler.<locals>.<genexpr>  s'      ##!qv######r   )r5   r'   r   r^   r   r   rN   )rI   rL   r   r   r   s       @r   r   r     s|      #v 	$xt99>>FCS//!hhjj $###s###UC(((r   )r   r0   	functoolsr   	itertoolsr   r   operatorr   r   __version__r   r%   r'   r   r   r.   r   r   <module>r      s   ( (V        $ $ $ $ $ $ $ $          .G G G:t t t t t t t tn	8L 8L 8Lv) ) ) ) )r   