o
    3g0                     @  s  d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	m
Z
 ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZmZmZmZ d
dlmZ eeef ZG dd deZdaedd ZddddOddZdPddZdddQd$d%ZdRd(d)Z dPd*d+Z!dSd-d.Z"dTd1d2Z#dPd3d4Z$dUd8d9Z%dPd:d;Z&dVd<d=Z'dPd>d?Z(d@dA Z)ddBdWdEdFZ*dPdGdHZ+dXdKdLZ,dPdMdNZ-dS )Yz-
Helpers for hpi doctor/stats functionality.
    )annotationsN)IterableIteratorSequence)contextmanager)datetime)Path)
ModuleType)AnyCallableProtocolcast   )asdictc                   @  s   e Zd Zddd
ddZd	S )StatsFunFquickr   boolreturnStatsc                C  s   d S N )selfr   r   r   '/home/garg/my-data/HPI/my/core/stats.py__call__   s    zStatsFun.__call__Nr   r   r   r   )__name__
__module____qualname__r   r   r   r   r   r      s    r   Fc                  c  s"    t } z
da d V  W | a d S | a w )NT)QUICK_STATS)prevr   r   r   quick_stats*   s   r!   r   namefunc+Callable[[], Iterable[Any]] | Iterable[Any]r   r   r#   
str | Noner   r   c                C  s   t | r|  }t|drt|dri S | j}n	| }dt| }t|j}i }|dkrCtt|}| }|jdd}|j	 }||d< t
||d}	|	| |d	urT|n|}
|
|	iS )
z
    Extracts various statistics from a passed iterable/callable, e.g.:
    - number of items
    - first/last item
    - timestamps associated with first/last item

    If quick is set, then only first 100 items of the iterable will be processed
    	__enter____exit__unnamed_	DataFramerecords)orientdtypesr   N)callablehasattrr   idtyper   r
   reset_indexto_dictr-   _stat_iterableupdate)r$   r   r#   frfname	type_nameextrasdfr-   res	stat_namer   r   r   stat5   s(   



r=   Nonec                    s   t g d} |  \\}}|ddiksJ dd }t |dddiiks%J tdd }t |i ks3J d	d l}d	d l d fdd}t |dd|d|dd d ddiks`J d S )Nr         countrA   c                   S     g dS )N)         r   r   r   r   r   funp      ztest_stat.<locals>.funrG   c                   s  s    dV  dV  d S )Nr   rA   r   r   r   r   r   cmz   s   
ztest_stat.<locals>.cmr   r   pd.DataFramec                    s0    j dddd}  jdd t| D | dgdS )	N2024-02-10 08:00z2024-02-11 16:005h)startendfreqc                 S  s   g | ]	\}}d | qS )valuer   ).0i_r   r   r   
<listcomp>   s    z)test_stat.<locals>.df.<locals>.<listcomp>rP   )indexcolumns)
date_ranger*   	enumerate)datespdr   r   r:      s    ztest_stat.<locals>.dfr:      z<M8[ns]O)rU   rP   rK   z2024-02-11 14:00)rB   r-   firstlast)r   rJ   )r=   itemsr   numpypandasdtype	Timestamp)r;   r#   vrG   rI   npr:   r   rZ   r   	test_state   s*   
rg   )guessmodule_namestrrh   StatsFun | Nonec                C  sH   d }zt | }W n
 ty   Y d S w t|dd }|d u r"t|}|S )Nstats)	importlibimport_module	Exceptiongetattrguess_stats)ri   rh   rl   moduler   r   r   	get_stats   s   rs   rr   r	   c                   s0   t |  t dkrdS ddd fd	d
}|S )z
    If the module doesn't have explicitly defined 'stat' function,
     this is used to try to guess what could be included in stats automatically
    r   NFr   r   r   r   r   c                   s.   i }   D ]\}}|t|| |d q|S )Nr"   )r`   r5   r=   )r   r;   kre   	providersr   r   
auto_stats   s   zguess_stats.<locals>.auto_statsr   )_guess_data_providerslen)rr   rw   r   ru   r   rq      s
   rq   c                  C  sx   dd l m  m  m}  t| }|d usJ |dd}|dddddtd	d
d
d
d
d
td	d
dd
d
d
ddks:J d S )Nr   Fr   rA   z
file1.jsonz
file3.json)rB   r^   r_   	   i  r   )inputs	iter_data)my.core.tests.auto_statscoretestsrw   rq   r   )Mrw   r;   r   r   r   test_guess_stats   s   
r   dict[str, Callable]c                 C  s   t | t j}dd |D S )Nc                 S  s   i | ]\}}t |r||qS r   )is_data_provider)rQ   rt   re   r   r   r   
<dictcomp>   s    z)_guess_data_providers.<locals>.<dictcomp>)inspect
getmembers
isfunction)rr   
mfunctionsr   r   r   rx      s   rx   rG   r
   c              	   C  s   | du rdS zt | }W n ttfy   Y dS w ttt|dkr&dS t| dr3| j	dr3dS t
| }|d}|du rCdS t|S )z
    Criteria for being a "data provider":
    1. returns iterable or something like that
    2. takes no arguments? (otherwise not callable by stats anyway?)
    3. doesn't start with an underscore (those are probably helper functions?)
    NFr   r   rS   r   )r   	signature
ValueError	TypeErrorry   list_sig_required_paramsr/   r   
startswithtypingget_type_hintsget_type_is_iterable)rG   sig
type_hintsreturn_typer   r   r   r      s"   	


r   c                  C  s   t } | d rJ | trJ | drJ dd }| |rJ dd }| |r(J ddd	}| |r3J ddd}| |s>J ddd}| |rIJ ddd}| |sTJ ddd}| |s_J d S )Nxc                   S  rC   )Nr?   r   r   r   r   r   no_return_type   rH   z-test_is_data_provider.<locals>.no_return_typec                   S  s   ddgS )Nr   r@   r   r   r   r   r   <lambda>  s    z'test_is_data_provider.<locals>.<lambda>r   	list[int]c                 S  s   t t| S r   )r   range)rB   r   r   r   has_extra_args  s   z-test_is_data_provider.<locals>.has_extra_argsSequence[str]c                   S  rC   )N)abcr   r   r   r   r   has_return_type  rH   z.test_is_data_provider.<locals>.has_return_typeIterator[Any]c                   s      dV  d S Nr   r   r   r   r   r   _helper_func     
z+test_is_data_provider.<locals>._helper_funcc                   s  r   r   r   r   r   r   r   r{     r   z%test_is_data_provider.<locals>.inputsc                   s  r   r   r   r   r   r   r   producer_inputs  r   z.test_is_data_provider.<locals>.producer_inputs)r   r   )r   r   )r   r   )r   int)idpr   lamr   r   r   r{   r   r   r   r   test_is_data_provider   s$   




r   r   inspect.SignatureIterator[inspect.Parameter]c                 c  s*    | j  D ]}|jtjjkr|V  qdS )zg
    Returns parameters the user is required to provide - e.g. ones that don't have default values
    N)
parametersvaluesdefaultr   	Parameterempty)r   paramr   r   r   r      s   r   c                  C  s~   ddd} t ttt| dksJ ddd}t ttt|d	ks(J dddd}t ttt|dks=J d S )Nr   r   c                   S  s   dS )NrE   r   r   r   r   r   r   +     z#test_sig_required_params.<locals>.xr   argc                 S     | S r   r   r   r   r   r   y0  r   z#test_sig_required_params.<locals>.yr   rE   c                 S  r   r   r   r   r   r   r   z8  r   z#test_sig_required_params.<locals>.z)r   r   )r   r   r   r   )rE   )ry   r   r   r   r   )r   r   r   r   r   r   test_sig_required_params)  s   

"r   c                 C  s>   t | }|d u rdS t|tjjrdS t|tjjrdS dS )NFT)r   
get_origin
issubclasscollectionsabcMappingr   )	type_specoriginr   r   r   r   >  s   
r   c                  C  sx   t } | d rJ | trJ | trJ | tttf rJ | tt s&J | ttttf  s2J | tt s:J d S r   )r   r   r
   dictr   r   rj   r   )rG   r   r   r   test_type_is_iterableN  s   r   c                 C  s&   | d u rd S t | trt| S t| S r   )
isinstancer   rj   _guess_datetime)itemr   r   r   
_stat_itemZ  s
   
r   r   itIterable[Any]c                  s   ddl m}m}m} dd d d  fdd}| }|s#tr9|d|}t|}||d d ur8| d}n||}d|i}	dkrId|	d	<  dkrQ |	d
< t }
d ur]|
|	d< t }d uri||	d< |	S )Nr   )r^   ilentakec                  3  sB    D ]} d7 t | tr d7  n| d u r| | V  qd S r   )r   ro   r   errors
first_itemr   	last_itemtotalr   r   funcitk  s   

z_stat_iterable.<locals>.funcitd   +rB   zTHE ITERABLE RETURNED NO DATAwarningr   r^   r_   )more_itertoolsr^   r   r   r   ry   r   )r   r   r^   r   r   r   eitinitialrB   r;   
stat_first	stat_lastr   r   r   r4   b  s2   

r4   c                    s   ddl m } m}m} ddlm} | jd|jd|ddG dd	 d	|  fd
d}t| }|d dks:J |d dksBJ |d d  ksNJ d S )Nr   )r   	timedeltatimezone
NamedTuple{   )tzrA   )daysc                   @     e Zd ZU ded< ded< dS )ztest_stat_iterable.<locals>.Xr   r   r   dNr   r   r   __annotations__r   r   r   r   X     
 r   c                  3  s    t dV  tdD ]}  | |   dV  q
t dV  tdD ]}  | d | d   dV  q! dd  dV  d S )	Nzoops!r@   )r   r   zbad!rA   
   r   2   )RuntimeErrorr   )rR   r   dayddr   r   r     s   

 ztest_stat_iterable.<locals>.itrB      r   r@   r_   r   )r   r   r   r   r   fromtimestamputcr4   )r   r   r   r   r   r;   r   r   r   test_stat_iterable  s   

	r   r   datetime | Nonec                 C  s>   zt | }W n   Y d S | D ]}t|tr|  S qd S r   )r   r   r   r   )r   r   re   r   r   r   r     s   
r   c                  C  s   ddl m}  ddlm} ddlm} |d}G dd d|}G d	d
 d
|}t|ddd u s1J t|d|d|ks=J | G dd d}t||dd|ksRJ d S )Nr   )	dataclassr   r   )fromisoformatz2021-02-01T12:34:56Zc                   @  s   e Zd ZU ded< dS )ztest_guess_datetime.<locals>.Ar   r   Nr   r   r   r   r   A  s   
 r   c                   @  r   )ztest_guess_datetime.<locals>.Br   r   r   createdNr   r   r   r   r   B  r   r   rD   r   )r   r   c                   @  r   )ztest_guess_datetime.<locals>.Cr   r   r   r   Nr   r   r   r   r   C  s   
 r   i  )r   r   )dataclassesr   r   r   compatr   r   )r   r   r   r   r   r   r   r   r   r   test_guess_datetime  s   r   )r$   r%   r   r   r#   r&   r   r   )r   r>   )ri   rj   rh   r   r   rk   )rr   r	   r   rk   )rr   r	   r   r   )rG   r
   r   r   )r   r   r   r   )r   r   )r   r   r   r   r   r   )r   r
   r   r   ).__doc__
__future__r   collections.abcr   rm   r   r   r   r   r   
contextlibr   r   pathlibr   typesr	   r
   r   r   r   r   r   rj   r   r   r   r!   r=   rg   rs   rq   r   rx   r   r   r   r   r   r   r   r4   r   r   r   r   r   r   r   <module>   sJ    

03




%
(
	


4
