o
    #eW                     @   s  d dl mZ d dlZd dlmZ d dlmZmZmZ d dl	m
Z
mZ d dlmZ d dlmZmZ d dlmZmZ g d	ZG d
d deZeg ZG dd deZdd ZG dd deZdd Zdd ZG dd de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,d- Z&d.d/ Z'd0d1 Z(d2d3 Z)d4d5 Z*d6d7 Z+G d8d9 d9eZ,i d:d;g fd<d;g fd=d;g fd>d;d>gfd?d;g fd@dAg fdBdAg fdCd;g fdDd;g fdEdAg fdFd;g fdGdAg fdHd;g fdIdAg fdJd;d>gfdKdAd>gfdLdAd>gfi dMd;d>gfdNd;g fdOd;d>dPgfdQd;d>dPgfdRd;d>dPgfdSd;d>dPgfdTd;d>dPgfdUd;d>gfdVd;d>dPgfdWd;d>dXgfdYd;d>gfdZd;g d[fd\d;d>d]gfd^d;d_gfd`d;d_gfdad;d_dbgfdcd;dbddgfi ded;d_gfdfd;g dgfdhd;dbgfdid;g djfdkd;g fdld;g fdmd;g fdnd;g fdod;g dpfdqd;g dpfdrd;g dsfdtd;g dufdvd;g dpfdwd;g dxfdyd;g dzfd{d;g d|fd}d;d>d_gfi d~d;g dfdd;g dfdd;g dfdd;d>gfdd;g dfdd;g dfdd;d>gfdd;d>dPgfdd;g dpfddAg dpfddAg fdd;d>dPgfdd;g d;d>dPgfddAdgd;d>dPgfddAdgd;d>dPgfddAg dd;d>dPgfddAg d;g fi dd;dgd;d>dPgfdd;g dfdd;g dfdd;dPd_gfdd;g dfdd;g dfdd;g dfdd;g dfdd;g fddAg fdd;g fddAg fdd;d>gfdd;d>gfdd;d>gfddAg fZ-g dZ.dd Z/dd Z0dd Z1dd Z2dd Z3dS )    )print_functionN
PatsyError)	ParseNodeTokenparse_formula)EvalEnvironment
EvalFactor)uniqueify_list)repr_pretty_delegaterepr_pretty_impl)no_picklingassert_no_pickling)Term	ModelDesc	INTERCEPTc                   @   sH   e Zd ZdZdd Zdd Zdd Zdd	 ZeZ	d
d Z
dd ZeZdS )r   a  The interaction between a collection of factor objects.

    This is one of the basic types used in representing formulas, and
    corresponds to an expression like ``"a:b:c"`` in a formula string.
    For details, see :ref:`formulas` and :ref:`expert-model-specification`.

    Terms are hashable and compare by value.

    Attributes:
    
    .. attribute:: factors

       A tuple of factor objects.
    c                 C   s   t t|| _d S N)tupler
   factors)selfr    r   *lib/python3.10/site-packages/patsy/desc.py__init__+      zTerm.__init__c                 C   s   t |tot|jt| jkS r   )
isinstancer   	frozensetr   r   otherr   r   r   __eq__.   s   
zTerm.__eq__c                 C   s
   | |k S r   r   r   r   r   r   __ne__2      
zTerm.__ne__c                 C   s   t tt| jfS r   )hashr   r   r   r   r   r   r   __hash__5   r   zTerm.__hash__c                 C   s    |rJ t || t| jg d S r   )r   listr   r   pcycler   r   r   _repr_pretty_9   s   zTerm._repr_pretty_c                 C   s    | j rddd | j D S dS )z+Return a human-readable name for this term.:c                 S   s   g | ]}|  qS r   )name).0fr   r   r   
<listcomp>@       zTerm.name.<locals>.<listcomp>	Intercept)r   joinr"   r   r   r   r*   =   s   z	Term.nameN)__name__
__module____qualname____doc__r   r   r   r#   r   __repr__r(   r*   r   __getstate__r   r   r   r   r      s    r   c                   @   s   e Zd Zdd Zdd ZdS )_MockFactorc                 C   s
   || _ d S r   _name)r   r*   r   r   r   r   I   r    z_MockFactor.__init__c                 C   s   | j S r   r8   r"   r   r   r   r*   L   s   z_MockFactor.nameN)r1   r2   r3   r   r*   r   r   r   r   r7   H   s    r7   c                  C   s   t g djdksJ t ddgt ddgksJ tt ddgtt ddgks+J td} td}t | |g dks?J t || g dksKJ t g  d	ksUJ tt g  d S )
N)      r:   )r:   r;   r:   r;   aba:bzb:ar/   )r   r   r!   r7   r*   r   )f1f2r   r   r   	test_TermO   s   $rA   c                   @   s<   e Zd ZdZdd ZeZdd Zdd Ze	dd	 Z
eZd
S )r   a  A simple container representing the termlists parsed from a formula.

    This is a simple container object which has exactly the same
    representational power as a formula string, but is a Python object
    instead. You can construct one by hand, and pass it to functions like
    :func:`dmatrix` or :func:`incr_dbuilder` that are expecting a formula
    string, but without having to do any messy string manipulation. For
    details see :ref:`expert-model-specification`.

    Attributes:

    .. attribute:: lhs_termlist
                   rhs_termlist

       Two termlists representing the left- and right-hand sides of a
       formula, suitable for passing to :func:`design_matrix_builders`.
    c                 C   s   t || _t || _d S r   )r
   lhs_termlistrhs_termlist)r   rB   rC   r   r   r   r   m   s   
zModelDesc.__init__c                 C   s&   |rJ t || g d| jfd| jfgS )NrB   rC   )r   rB   rC   r%   r   r   r   r(   r   s   zModelDesc._repr_pretty_c                    s   dd  d  fdd| jD }|r|d7 }n|d7 }| jtgkr*| t7 }|S g }t| jvr6|d | fd	d| jD 7 }|d |7 }|S )
a  Returns a human-readable representation of this :class:`ModelDesc`
        in pseudo-formula notation.

        .. warning:: There is no guarantee that the strings returned by this
           function can be parsed as formulas. They are best-effort
           descriptions intended for human users. However, if this ModelDesc
           was created by parsing a formula, then it should work in
           practice. If you *really* have to.
        c                 S   s   | t krdS |  S )N1)r   r*   )termr   r   r   	term_code   s   z%ModelDesc.describe.<locals>.term_codez + c                    s   g | ]} |qS r   r   r+   rE   rF   r   r   r-      r.   z&ModelDesc.describe.<locals>.<listcomp>z ~ z~ 0c                    s   g | ]
}|t kr |qS r   r   rG   rH   r   r   r-      s    )r0   rB   rC   r   append)r   resultZ
term_namesr   rH   r   describey   s   



zModelDesc.describec                 C   s:   t |tr|}nt|}t j|dd}t || sJ |S )a$  Construct a :class:`ModelDesc` from a formula string.

        :arg tree_or_string: A formula string. (Or an unevaluated formula
          parse tree, but the API for generating those isn't public yet. Shh,
          it can be our secret.)
        :returns: A new :class:`ModelDesc`.
        F)require_evalexpr)r   r   r   	Evaluatoreval)clsZtree_or_stringtreevaluer   r   r   from_formula   s   
	zModelDesc.from_formulaN)r1   r2   r3   r4   r   r   r5   r(   rM   classmethodrT   r   r6   r   r   r   r   r   [   s    
r   c                  C   s   t d} t d}ttt| ggt| gt| |gg}|jtt| ggks'J |jt| gt| |ggks7J t|  | dksEJ t| tg g  dksTJ ttgg  dks`J ttgtg dksmJ ttgtt|gg dks~J d S )Nr<   r=   z1 + a ~ 0 + a + a:bz~ 0z1 ~ 0z1 ~ 1z1 ~ b)	r7   r   r   r   rB   rC   printrM   r   )r?   r@   mr   r   r   test_ModelDesc   s   & rX   c                  C   sV   dt dfD ]"} t| }|jttdggksJ |jtttdggks(J qd S )Nzy ~ xyx)r   r   rT   rB   r   r	   rC   r   )inputZmdr   r   r   test_ModelDesc_from_formula   s
   
r\   c                   @   s(   e Zd ZdZdd ZeZdd ZeZ	dS )IntermediateExprzFThis class holds an intermediate result while we're evaluating a tree.c                 C   sH   || _ || _|| _tt|| _| j r| jsJ | j r | jr"J d S d S r   )	interceptintercept_originintercept_removedr   r
   terms)r   r^   r_   r`   ra   r   r   r   r      s   
zIntermediateExpr.__init__c                 C   s$   |rJ t || | j| j| j| jgS r   )r   r^   r_   r`   ra   r%   r   r   r   _pretty_repr_   s   zIntermediateExpr._pretty_repr_N)
r1   r2   r3   r4   r   r   r5   rb   r   r6   r   r   r   r   r]      s    	r]   c                 C   s   | rt f| S |S r   rJ   )Zdoitra   r   r   r   _maybe_add_intercept   s   
rc   c                    sv    fdd|j D }t|dkr|dtdd dg  t|dks#J tt|d j|d jt|d j |d jS )Nc                       g | ]}  |qS r   rP   r+   arg	evaluatorr   r   r-          z#_eval_any_tilde.<locals>.<listcomp>r:   r   FTr;   )	argsleninsertr]   r   rc   r^   ra   r`   ri   rR   Zexprsr   rh   r   _eval_any_tilde   s   ro   c                 C   sz   |  |jd }|jd jdkrtdd d|jS |  |jd }|jr/td|jd|j|j S t|j|j|j|j|j S )Nr   r:   ZEROFTrP   rk   typer]   ra   r^   r_   r`   )ri   rR   	left_expr
right_exprr   r   r   _eval_binary_plus   s   


ru   c                    s   |  |jd }|jd jdkrtd|jd d|jS |jd jdkr+tdd d|jS |  |jd   fdd|jD } jrGtdd d|S t|j|j|j|S )	Nr   r:   rp   TFONEc                    s   g | ]	}| j vr|qS r   )ra   rG   rt   r   r   r-     s    
z&_eval_binary_minus.<locals>.<listcomp>rq   )ri   rR   rs   ra   r   rw   r   _eval_binary_minus   s    rx   c                 C   s   | j r	td| jd S )Nz1intercept term cannot interact with anything else)r^   r   r_   )exprr   r   r   _check_interactable  s
   rz   c                 C   sV   | |fD ]}t | qg }| jD ]}|jD ]}|t|j|j  qqtdd d|S )NF)rz   ra   rK   r   r   r]   )rs   rt   ry   ra   Zl_termZr_termr   r   r   _interaction  s   


r{   c                    s<    fdd|j D }tdd d|d j|d j t| j S )Nc                    rd   r   re   rf   rh   r   r   r-     rj   z%_eval_binary_prod.<locals>.<listcomp>Fr   r:   )rk   r]   ra   r{   rn   r   rh   r   _eval_binary_prod  s   r|   c                 C   s   |  |jd }|  |jd }t|j}t| g }|jD ]	}|t|j7 }qtdd dt|g}|tt||j7 }tdd d|S )Nr   r:   F)	rP   rk   r$   ra   rz   r   r]   r   r{   )ri   rR   rs   rt   ra   Zleft_factorsrE   Zleft_combined_exprr   r   r   _eval_binary_div(  s   

r}   c                    s    fdd|j D }t| S )Nc                    rd   r   re   rf   rh   r   r   r-   8  rj   z)_eval_binary_interact.<locals>.<listcomp>)rk   r{   rn   r   rh   r   _eval_binary_interact7  s   r~   c                 C   s   |  |jd }t| d}|jd jdv r-|jd jj}zt|}W n	 ty,   Y nw |dk r9td|jd |j	}|}t
t|j	|}td|D ]}t||}||j	 }qKtdd d|S )Nr   r:   )rv   NUMBERz '**' requires a positive integerF)rP   rk   rz   rr   tokenextraint
ValueErrorr   ra   minrl   ranger{   r]   )ri   rR   rs   Zpowerry   Z	all_termsZbig_exprir   r   r   _eval_binary_power;  s&   
r   c                 C   s   |  |jd S )Nr   )rP   rk   ri   rR   r   r   r   _eval_unary_plusP     r   c                 C   sH   |j d jdkrtd|jdg S |j d jdkrtdd dg S td|)Nr   rp   TFrv   z)Unary minus can only be applied to 1 or 0)rk   rr   r]   originr   r   r   r   r   _eval_unary_minusS  s
   
r   c                 C   s   t dd dg S )NFT)r]   r   r   r   r   
_eval_zero[  s   r   c                 C   s   t d|jdg S )NTF)r]   r   r   r   r   r   	_eval_one^  r   r   c                 C   s
   t d|)Nz4numbers besides '0' and '1' are only allowed with **r   r   r   r   r   _eval_numbera  s   r   c                 C   s(   t |jj|jd}tdd dt|ggS )N)r   F)r	   r   r   r   r]   r   )ri   rR   Zfactorr   r   r   _eval_python_expre  s   r   c                   @   s&   e Zd Zdd Zdd Zd	ddZdS )
rO   c                 C   s   i | _ | ddt | ddt | ddt | ddt | ddt | ddt | ddt | d	dt | ddt	 | ddt
 | d
dt | ddt | ddt | ddt i | _d S )N~r;   r:   +-*/r)   z**rp   r   rv   r   ZPYTHON_EXPR)_evaluatorsadd_opro   ru   rx   r|   r}   r~   r   r   r   r   r   r   r   Zstashr"   r   r   r   r   j  s    
zEvaluator.__init__c                 C   s   || j ||f< d S r   )r   )r   opZarityri   r   r   r   r     r   zEvaluator.add_opTc                 C   s   d }t |ts	J |jt|jf}|| jvr td|jf |j| j| | |}|r>t |ts>t |t	r9td|td||S )Nz/I don't know how to evaluate this '%s' operatorz2~ can only be used once, and only at the top levelzBcustom operator returned an object that I don't know how to handle)
r   r   rr   rl   rk   r   r   r   r]   r   )r   rR   rN   rL   keyr   r   r   rP     s&   

zEvaluator.evalN)T)r1   r2   r3   r   r   rP   r   r   r   r   rO   i  s    rO    T z 
 r<   rD   rI   Fz- 1z- 0z+ 1z+ 0z0 + 1z1 + 0z1 - 0z0 - 1z1 + az0 + aza - 1za - 0z1 - aa + br=   z(a + b)za + ((((b))))za + ((((+b))))za + ((((b - a))))z	a + a + aza + (b - a)za + np.log(a, base=10)znp.log(a, base=10)z0a + np.log(a, base=10) - np . log(a , base = 10)za + (I(b) + c))r<   zI(b)cza + I(b + c)zI(b + c)r>   r<   r=   za:b:az	a:(b + c)r<   r   z	(a + b):cr=   r   z	a:(b - c)zc + a:c + a:(b - c))r   r   r   z	(a - b):czb + b:c + (a - b):c)r=   r   r   z	a:b - a:bz	a:b - b:az1 - (a + b)za + b - (a + b)za * b)r<   r=   r   z	a * b * aza * (b + c))r<   r=   r   r   r   z(a + b) * c)r<   r=   r   r   r   za * (b - c)zc + a:c + a * (b - c))r   r   r<   r=   r   z(a - b) * c)r<   r   r   zb + b:c + (a - b) * c)r=   r   r<   r   r   za/bz	(a + b)/c)r<   r=   r<   r=   r   zb + b:c + (a - b)/c)r=   r   r<   r   z	a/(b + c))r<   r   r   za ** 2z(a + b + c + d) ** 2)
r<   r=   r   dr   r   r<   r   r   r=   r   r   r   z(a + b + c + d) ** 3)r<   r=   r   r   r   r   r   r   r   r   r   )r<   r=   r   )r<   r   r   )r=   r   r   za + +az~ a + bz~ a*bz	~ a*b + 0z~ -1z	0 ~ a + bz	1 ~ a + bz	y ~ a + brY   z0 + y ~ a + bz0 + y * z ~ a + b)rY   z)rY   r   z-1 ~ 1z1 + y ~ a + bz	a + b * c)r<   r=   r   r   z	a * b + c)r<   r=   r   r   z	a * b - az	a + b / c)r<   r=   r   z	a / b + c)r<   r   r   za*b:c)r<   r   r   za:b*c)r   r   r   z~ 1 + 1 + 0 + 1z~ 0 + 1 + 0z~ 0 - 1 - 1 + 0 + 1z~ 1 - 1z~ 0 + a + 1z~ 1 + (a + 0)z~ 0 + (a + 1)z~ 1 - (a + 1))#za <+>za + <(>z
b + <(-a)>za:<1>z(a + <1>)*bza + <2>z	a + <1.0>za ** <b>za ** <(1 + 1)>z
a ** <1.5>za + b <# asdf>z<)>za + <)>z<*> aza + <*>za + <foo[bar>za + <foo{bar>za + <foo(bar>z
a + <[bar>z
a + <{bar>za + <{bar[]>za + foo<]>barza + foo[]<]>barza + foo{}<}>barza + foo<)>barza + b<)>z(a) <.>z<(>a + bz<y ~ a> ~ bzy ~ <(a ~ b)>z	<~ a> ~ bz~ <(a ~ b)>z1 + <-(a + b)>z<- a>za + <-a**2>c                 C   s~   |rdg| }t | t |ksJ t| |D ]&\}}t|tr6t|tr'|f}|jtdd |D ks5J q||ks<J qd S )Nr   c                 S   s   g | ]}t |qS r   )r	   )r+   sr   r   r   r-   Q  r.   z'_assert_terms_match.<locals>.<listcomp>)rl   zipr   r   strr   r   )ra   Zexpected_interceptZ	expectedsrE   Zexpectedr   r   r   _assert_terms_matchI  s   


r   c                 C   s~   t | D ]7\}}t|dkrdg f| }t|}tt| t| t| |\}}}}t|j|| t|j	|| qd S )Nr;   F)
sixZ	iteritemsrl   r   rT   rV   reprr   rB   rC   )ZtestscoderL   Z
model_descZlhs_interceptrB   Zrhs_interceptrC   r   r   r   _do_eval_formula_testsU  s   
r   c                   C   s   t t d S r   )r   _eval_testsr   r   r   r   test_eval_formulac  s   r   c                  C   s"   ddl m}  dd }| |t d S )Nr   )_parsing_error_testc                 S   s
   t | S r   )r   rT   )Zformular   r   r   <lambda>h  s   
 z3test_eval_formula_error_reporting.<locals>.<lambda>)patsy.parse_formular   _eval_error_tests)r   Zparse_fnr   r   r   !test_eval_formula_error_reportingf  s   r   c                  C   s^   ddl m}  td}|jd jd j| dddksJ |jd jd j| dddks-J d S )Nr   )Originr   r:   r;         )Zpatsy.originr   r   rT   rC   r   r   )r   Zdescr   r   r   test_formula_factor_origink  s   


r   )4Z
__future__r   r   Zpatsyr   r   r   r   r   Z
patsy.evalr   r	   Z
patsy.utilr
   r   r   r   r   __all__objectr   r   r7   rA   r   rX   r\   r]   rc   ro   ru   rx   rz   r{   r|   r}   r~   r   r   r   r   r   r   r   rO   r   r   r   r   r   r   r   r   r   r   r   <module>   s  *P	5
	





!
#%&
(
)*+
,-
./1245789:;<=>@ABC
EFI
OQRSTVWXYZ[\_`abcdehijk
l
m
nos8