B
    |U#                 @   s~   d ddg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| }x6|D ]. |   }| fddtd|d D  qW ttj|  }i }x&t||D ]\ }t|| | < qnW |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.7/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    
&c              C   s   t ddd} | d ddddddgks(t| d dd	d
dd	d
gksDtt dddd} | d ddddddddddddgkszt| d dd	d
dd	d
dd	d
dd	d
gkstd S )N      )abr!   a1a2r"   b1b2Zb3)r!   r"   r	   )r   AssertionError)r   r   r   r   test_balanced9   s    r(   c              O   s   | dd}| dd}|r*td|f t }i }xH| D ]@}|d dkrT|||< q:|d dkrl|| q:td	|f q:W tjt| t	d
}t	t
|d | }|| }	tf d|i|}
tjd}x t|D ]}|j|	d|
|< qW |
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	   )size)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(    !

c           	   C   sp  t ddd} t|  dddgks&t| d ddddddddgksFt| d ddddddddgksft| d jttks~t| d jdkstt dd	}t| dd	gkstt|d t|d	   krd
ksn ttt dddd dksttt dddddd dksttt ddddddd dks>tddl	m
} |tt ddd |tt dddd d S )Nr!   r"   xr#   r$   r%   r&   )   yr+   
   )r*      r    )r*   r)      r   )assert_raisesZ__123{   )Zasdfasdf)r   r   keysr'   r,   r1   floatshapelen
nose.toolsr:   r   r.   )Zd1Zd2r:   r   r   r   test_demo_dataz   s      
*"$rA   c               @   sf   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   sH   || _ || _|| _|| _|| _| jsD|d k	r4td|d k	rDtd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   rF   r   r   r   __init__   s    zLookupFactor.__init__c             C   s   | j S )N)rB   )rH   r   r   r   r      s    zLookupFactor.namec             C   s   d| j j| jf S )Nz%s(%r))	__class____name__rB   )rH   r   r   r   __repr__   s    zLookupFactor.__repr__c             C   s:   t |to8| j|jko8| j|jko8| j|jko8| j|jkS )N)
isinstancer   rB   rC   rD   rE   )rH   otherr   r   r   __eq__   s
    
zLookupFactor.__eq__c             C   s
   | |k S )Nr   )rH   rP   r   r   r   __ne__   s    zLookupFactor.__ne__c             C   s   t t| j| j| j| jfS )N)hashr   rB   rC   rD   rE   )rH   r   r   r   __hash__   s    zLookupFactor.__hash__c             C   s   dS )Nr   r   )rH   stateZeval_envr   r   r   memorize_passes_needed   s    z#LookupFactor.memorize_passes_neededc             C   s   dst d S )NF)r'   )rH   rU   
which_passr   r   r   r   memorize_chunk   s    zLookupFactor.memorize_chunkc             C   s   dst d S )NF)r'   )rH   rU   rW   r   r   r   memorize_finish   s    zLookupFactor.memorize_finishc             C   s&   || j  }| jr"t|| j| jd}|S )N)rJ   r   )rB   rC   r   rD   rE   )rH   Zmemorize_stater   r   r   r   r   eval   s    
zLookupFactor.eval)FNNN)rM   
__module____qualname____doc__rK   r   rN   rQ   rR   rT   rV   rX   rY   rZ   r   __getstate__r   r   r   r   r      s    
c              C   sh  t d} |  dkst| t dks(t| t dks8tt| tt dksPtt| tt dksht| i ddidkst| i ddidkstt| dkst| jd kstt ddd}|jdkstt dd	d
dd}|i ddddgi}|jdddgkst|jd
kst|j	dks,tddl
m} |tt dd
d |tt ddd tt d d S )Nr!   r"   r
   r   zLookupFactor('a')Zasdf)rF   cTZCONTRAST)r
   r   )rI   rJ   r   r   )r:   Znc)rJ   )r   )r   r   r'   rS   rZ   reprrF   r   rJ   r   r@   r:   rG   r   )Zl_aZl_with_originZl_cZboxr:   r   r   r   test_LookupFactor   s,    
ra   )__all__r   Znumpyr1   Zpatsyr   Zpatsy.categoricalr   Z
patsy.utilr   r   r   r(   r   rA   objectr   ra   r   r   r   r   <module>	   s   
(
7N