o
    #ez#                     @   s|   g d Z ddlZddlZddlmZ ddlmZ ddlm	Z	m
Z
 dd Zdd	 Zd
d Zdd ZG dd deZdd ZdS ))balanced	demo_dataLookupFactor    N)
PatsyError)C)no_picklingassert_no_picklingc                     s   |  dd}g }t| }|D ] |   }| fddtd|d D  qttj|  }i }t||D ]\ }t|| | < q4|S )aT  balanced(factor_name=num_levels, [factor_name=num_levels, ..., repeat=1])

    Create simple balanced factorial designs for testing.

    Given some factor names and the number of desired levels for each,
    generates a balanced factorial design in the form of a data
    dictionary. For example:

    .. ipython::

       In [1]: balanced(a=2, b=3)
       Out[1]:
       {'a': ['a1', 'a1', 'a1', 'a2', 'a2', 'a2'],
        'b': ['b1', 'b2', 'b3', 'b1', 'b2', 'b3']}

    By default it produces exactly one instance of each combination of levels,
    but if you want multiple replicates this can be accomplished via the
    `repeat` argument:

    .. ipython::

       In [2]: balanced(a=2, b=2, repeat=2)
       Out[2]:
       {'a': ['a1', 'a1', 'a2', 'a2', 'a1', 'a1', 'a2', 'a2'],
        'b': ['b1', 'b2', 'b1', 'b2', 'b1', 'b2', 'b1', 'b2']}
    repeat   c                    s   g | ]}d  |f qS )z%s%s ).0inamer   /lib/python3.10/site-packages/patsy/user_util.py
<listcomp>1   s    zbalanced.<locals>.<listcomp>)popsortedappendrangezip	itertoolsproductlist)kwargsr	   levelsnamesZlevel_countvaluesdatavaluer   r   r   r      s   $r   c                  C   sn   t ddd} | d g dksJ | d g dksJ t dddd} | d g d	ks+J | d g d
ks5J d S )N      )abr"   )a1r$   r$   a2r%   r%   r#   )b1b2b3r&   r'   r(   )r"   r#   r	   )r$   r$   r$   r%   r%   r%   r$   r$   r$   r%   r%   r%   )r&   r'   r(   r&   r'   r(   r&   r'   r(   r&   r'   r(   )r   )r   r   r   r   test_balanced9   s   r)   c                  O   s   | dd}| dd}|rtd|f t }i }| D ]}|d dv r)|||< q|d dv r5|| qtd	|f tjt| t	d
}t	t
|d | }|| }	tdd|i|}
tjd}t|D ]
}|j|	d|
|< qi|
S )a?  demo_data(*names, nlevels=2, min_rows=5)

    Create simple categorical/numerical demo data.

    Pass in a set of variable names, and this function will return a simple
    data set using those variable names.

    Names whose first letter falls in the range "a" through "m" will be made
    categorical (with `nlevels` levels). Those that start with a "p" through
    "z" are numerical.

    We attempt to produce a balanced design on the categorical variables,
    repeating as necessary to generate at least `min_rows` data
    points. Categorical variables are returned as a list of strings.

    Numerical data is generated by sampling from a normal distribution. A
    fixed random seed is used, so that identical calls to demo_data() will
    produce identical results. Numerical data is returned in a numpy array.

    Example:

    .. ipython:

       In [1]: patsy.demo_data("a", "b", "x", "y")
       Out[1]:
       {'a': ['a1', 'a1', 'a2', 'a2', 'a1', 'a1', 'a2', 'a2'],
        'b': ['b1', 'b2', 'b1', 'b2', 'b1', 'b2', 'b1', 'b2'],
        'x': array([ 1.76405235,  0.40015721,  0.97873798,  2.2408932 ,
                     1.86755799, -0.97727788,  0.95008842, -0.15135721]),
        'y': array([-0.10321885,  0.4105985 ,  0.14404357,  1.45427351,
                     0.76103773,  0.12167502,  0.44386323,  0.33367433])}
    nlevelsr    min_rows   zunexpected keyword arguments %rr   ZabcdefghijklmnZpqrstuvwxyzzbad name %r)dtypeg      ?r	   )sizeNr   )r   	TypeErrorsetaddr   npZprodr   r   intZceilr   ZrandomZRandomStater   Znormal)r   r   r*   r+   Z	numericalZcategoricalr   Zbalanced_design_sizer	   Znum_rowsr   rr   r   r   r   C   s(   !
r   c                  C   sT  t ddd} t|  g dksJ | d g dksJ | d g dks&J | d jttks2J | d jdks;J t dd}t| ddgksLJ t|d t|d   kr_d	ksbJ  J tt dd
dd d
kspJ tt dddd
dd dksJ tt dddd
ddd dksJ dd l}|	t
t ddd |j	tt dddd d S )Nr"   r#   x)r"   r#   r5   )r$   r$   r%   r%   r$   r$   r%   r%   )r&   r'   r&   r'   r&   r'   r&   r'   )   yr,   
   )r+      r!   )r+   r*      r   Z__123{   )Zasdfasdf)r   r   keysr-   r2   floatshapelenpytestraisesr   r/   )Zd1Zd2r@   r   r   r   test_demo_dataz   s   
, "rB   c                   @   sj   e Zd Z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d Zdd ZeZdS )r   a8  A simple factor class that simply looks up a named entry in the given
    data.

    Useful for programatically constructing formulas, and as a simple example
    of the factor protocol.  For details see
    :ref:`expert-model-specification`.

    Example::

      dmatrix(ModelDesc([], [Term([LookupFactor("x")])]), {"x": [1, 2, 3]})

    :arg varname: The name of this variable; used as a lookup key in the
      passed in data dictionary/DataFrame/whatever.
    :arg force_categorical: If True, then treat this factor as
      categorical. (Equivalent to using :func:`C` in a regular formula, but
      of course you can't do that with a :class:`LookupFactor`.
    :arg contrast: If given, the contrast to use; see :func:`C`. (Requires
      ``force_categorical=True``.)
    :arg levels: If given, the categorical levels; see :func:`C`. (Requires
      ``force_categorical=True``.)
    :arg origin: Either ``None``, or the :class:`Origin` of this factor for use
      in error reporting.

    .. versionadded:: 0.2.0
       The ``force_categorical`` and related arguments.
    FNc                 C   sL   || _ || _|| _|| _|| _| js"|d urtd|d ur$tdd S d S )Nz)contrast= requires force_categorical=Truez'levels= requires force_categorical=True)_varname_force_categorical	_contrast_levelsorigin
ValueError)selfZvarnameforce_categoricalcontrastr   rG   r   r   r   __init__   s   zLookupFactor.__init__c                 C   s   | j S N)rC   rI   r   r   r   r      s   zLookupFactor.namec                 C   s   d| j j| jf S )Nz%s(%r))	__class____name__rC   rN   r   r   r   __repr__   s   zLookupFactor.__repr__c                 C   s:   t |to| j|jko| j|jko| j|jko| j|jkS rM   )
isinstancer   rC   rD   rE   rF   rI   otherr   r   r   __eq__   s   




zLookupFactor.__eq__c                 C   s
   | |k S rM   r   rS   r   r   r   __ne__   s   
zLookupFactor.__ne__c                 C   s   t t| j| j| j| jfS rM   )hashr   rC   rD   rE   rF   rN   r   r   r   __hash__   s   zLookupFactor.__hash__c                 C   s   dS )Nr   r   )rI   stateZeval_envr   r   r   memorize_passes_needed      z#LookupFactor.memorize_passes_neededc                 C      J rM   r   )rI   rY   
which_passr   r   r   r   memorize_chunk   r[   zLookupFactor.memorize_chunkc                 C   r\   rM   r   )rI   rY   r]   r   r   r   memorize_finish   r[   zLookupFactor.memorize_finishc                 C   s&   || j  }| jrt|| j| jd}|S )N)rK   r   )rC   rD   r   rE   rF   )rI   Zmemorize_stater   r   r   r   r   eval   s   
zLookupFactor.eval)FNNN)rP   
__module____qualname____doc__rL   r   rQ   rU   rV   rX   rZ   r^   r_   r`   r   __getstate__r   r   r   r   r      s    
r   c                  C   s^  t d} |  dksJ | t dksJ | t dksJ t| tt dks(J t| tt dks4J | i ddidks@J | i ddidksLJ t| dksTJ | jd u s[J t ddd}|jdkshJ t dd	d
dd}|i dg di}|jg dksJ |jd
ksJ |jdksJ dd l	}|j
tt dd
d |j
tt ddd tt d d S )Nr"   r#   r
   r    zLookupFactor('a')Zasdf)rG   cTZCONTRAST)r
   r    )rJ   rK   r   )r
   r
   r    r   Znc)rK   )r   )r   r   rW   r`   reprrG   r   rK   r   r@   rA   rH   r   )Zl_aZl_with_originZl_cZboxr@   r   r   r   test_LookupFactor   s.   rg   )__all__r   Znumpyr2   Zpatsyr   Zpatsy.categoricalr   Z
patsy.utilr   r   r   r)   r   rB   objectr   rg   r   r   r   r   <module>   s   (
7N