o
    5ti8                     @   s   d Z ddlZddlZddlmZmZ ddlmZmZ ddl	m
Z
mZmZmZ ddlZddl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 d	dlmZ e
rXddlZG dd dZdS )zA
.. codeauthor:: Tsuyoshi Hombashi <tsuyoshi.hombashi@gmail.com>
    N)OrderedDict
namedtuple)IteratorSequence)TYPE_CHECKINGAnyOptionalUnion)DataPropertyMatrix)TypeHint)Nan   )PatternMatch)to_value_matrix)loggerc                   @   s0  e Zd ZdZ				d^dee dee dedeej deee	ee
f   dee d	ee d
dfddZd
efddZded
efddZded
efddZed
ee fddZejdee d
dfddZed
ee fddZed
efddZed
efddZed
efddZed
efd d!Zejdee d
dfd"d!Zed
ee fd#d$Zed
ee fd%d&Zed
efd'd(Zed
eej fd)d*Z ed
eej! fd+d,Z"ed
ejfd-d.Z#d
efd/d0Z$d
efd1d2Z%d
efd3d4Z&d_dd d6ed
efd7d8Z'dd d
efd9d:Z(dd d
efd;d<Z)dd d
efd=d>Z*d_ded  d6ed
efd?d@Z+d`dAdBZ,dadDed
e-eedE f fdFdGZ.d
e/e0 fdHdIZ1dbdKdLZ2dcdMdNZ3ddOdOe4j5fdPee dQedRedSe4d
d f
dTdUZ6e7	V		dddWdJdedeee
  dee d
d f
dXdYZ8e7dZed[edRed
efd\d]Z9dS )e	TableDataz
    Class to represent a table data structure.

    :param table_name: Name of the table.
    :param  headers: Table header names.
    :param rows: Data of the table.
    N
table_nameheadersrowsdp_extractor
type_hintsmax_workersmax_precisionreturnc                 C   s   || _ g | _d | _|r|| _ng | _|rt|| _ntj|d| _|r(|| j_	d| j_
|r2|| j_|s:g | j_d S || j_d S )N)r   ")_TableData__table_name_TableData__value_matrix_TableData__value_dp_matrix_TableData__rowscopydeepcopy_TableData__dp_extractordpDataPropertyExtractorcolumn_type_hintsstrip_str_headerr   r   )selfr   r   r   r   r   r   r    r'   C/home/ubuntu/.local/lib/python3.10/site-packages/tabledata/_core.py__init__#   s"   
zTableData.__init__c                 C   sp   d| j  g}z|dd| j W n ty#   |d Y nw |d| j d| j g d|S )Nztable_name=zheaders=[{}]z, zheaders=Nonezcols=zrows=)	r   appendformatjoinr   	TypeErrorextendnum_columnsnum_rows)r&   element_listr'   r'   r(   __repr__H   s   
zTableData.__repr__otherc                 C   s   t |tsdS | j|ddS )NF	cmp_by_dp
isinstancer   equalsr&   r3   r'   r'   r(   __eq__T   s   
zTableData.__eq__c                 C   s   t |tsdS | j|dd S )NTFr4   r6   r9   r'   r'   r(   __ne__Z   s   
zTableData.__ne__c                 C      | j S )zstr: Name of the table.r   r&   r'   r'   r(   r   `      zTableData.table_namevaluec                 C   s
   || _ d S Nr=   r&   r@   r'   r'   r(   r   f      
c                 C      | j jS )z"Sequence[str]: Table header names.)r!   r   r>   r'   r'   r(   r   j   s   zTableData.headersc                 C   r<   )z(Sequence: Original rows of tabular data.)r   r>   r'   r'   r(   r   p   r?   zTableData.rowsc                 C   s$   | j r| j S dd | jD | _ | j S )z3DataPropertyMatrix: Converted rows of tabular data.c                 S   s   g | ]	}d d |D qS )c                 S   s   g | ]}|j qS r'   data.0value_dpr'   r'   r(   
<listcomp>~   s    z5TableData.value_matrix.<locals>.<listcomp>.<listcomp>r'   )rH   value_dp_listr'   r'   r(   rJ   }   s    z*TableData.value_matrix.<locals>.<listcomp>)r   value_dp_matrixr>   r'   r'   r(   value_matrixv   s   zTableData.value_matrixc                 C   s
   | j d uS rA   )r   r>   r'   r'   r(   has_value_dp_matrix   rC   zTableData.has_value_dp_matrixc                 C   rD   rA   r!   r   r>   r'   r'   r(   r      s   zTableData.max_workersc                 C   s   || j _d S rA   rO   rB   r'   r'   r(   r      s   c                 C   s"   zt | jW S  ty   Y dS w )z}Optional[int]:
        Number of rows in the tabular data.
        |None| if the ``rows`` is neither list nor tuple.
        N)lenr   r-   r>   r'   r'   r(   r0      s
   zTableData.num_rowsc                 C   sN   t | jrt| jS zt| jd W S  ty   Y d S  ty&   Y dS w )Nr   )typepyis_not_empty_sequencer   rP   r   r-   
IndexErrorr>   r'   r'   r(   r/      s   
zTableData.num_columnsc                 C   s(   | j du r| jt| j| j| _ | j S )z0DataPropertyMatrix: DataProperty for table data.N)r   r!   to_dp_matrixr   r   r   r>   r'   r'   r(   rL      s
   
zTableData.value_dp_matrixc                 C   s
   | j  S rA   )r!   to_header_dp_listr>   r'   r'   r(   header_dp_list   rC   zTableData.header_dp_listc                 C   s   | j | jS rA   )r!   to_column_dp_listrL   r>   r'   r'   r(   column_dp_list   s   zTableData.column_dp_listc                 C   r<   rA   )r!   r>   r'   r'   r(   r      s   zTableData.dp_extractorc                 C   s   t | jS )z6bool: |True| if the data :py:attr:`.headers` is empty.)rQ   is_empty_sequencer   r>   r'   r'   r(   is_empty_header   s   zTableData.is_empty_headerc                 C   s
   | j dkS )zW
        :return: |True| if the tabular data has no rows.
        :rtype: bool
        r   )r0   r>   r'   r'   r(   is_empty_rows   s   
zTableData.is_empty_rowsc                 C   s   t |  |  gS )z
        :return:
            |True| if the data :py:attr:`.headers` or
            :py:attr:`.value_matrix` is empty.
        :rtype: bool
        )anyrZ   r[   r>   r'   r'   r(   is_empty   s   zTableData.is_emptyTr5   c                 C   s   |r|  |S | |S rA   )_TableData__equals_dp_TableData__equals_raw)r&   r3   r5   r'   r'   r(   r8      s   

zTableData.equalsc                 C   s2   | j |j kg}| jd ur|| j|jk t|S rA   )r   r0   r*   all)r&   r3   compare_item_listr'   r'   r(   __equals_base   s   
zTableData.__equals_basec                 C   sn   |  |sdS | j|jkrdS t| j|jD ]\}}t|t|kr% dS tdd t||D s4 dS qdS )NFc                 S   s0   g | ]\}}t | st | s||kqS r'   )r   is_typerH   lhsrhsr'   r'   r(   rJ      s    

z*TableData.__equals_raw.<locals>.<listcomp>T)_TableData__equals_baser   zipr   rP   r`   )r&   r3   lhs_rowrhs_rowr'   r'   r(   __equals_raw   s   
	zTableData.__equals_rawc                 C   s   |  |sdS | j|jkrdS | jd u s|jd u rdS t| j|jD ]\}}t|t|kr1 dS tdd t||D r@ dS q"dS )NFc                 S   s   g | ]\}}||kqS r'   r'   rd   r'   r'   r(   rJ     s    z)TableData.__equals_dp.<locals>.<listcomp>T)rg   rV   rL   rh   rP   r\   )r&   r3   lhs_listrhs_listr'   r'   r(   __equals_dp   s   
zTableData.__equals_dpc                 C   s"   |D ]}| j ||dr dS qdS )Nr4   TF)r8   )r&   r3   r5   
table_datar'   r'   r(   in_tabledata_list  s
   zTableData.in_tabledata_listc                    s   g }t | jD ]/\} t ttfr t| jt kr || t tr6t	 fdd| jD s6|| q|s;dS |D ]}t
d| d| j|   q=tddt| j d| j d d	t|| j )
z%
        :raises ValueError:
        c                    s   g | ]}| v qS r'   r'   )rH   headerrowr'   r(   rJ     s    z+TableData.validate_rows.<locals>.<listcomp>Nzinvalid row (line=z): z1table header length and row length are mismatch:
z  header(len=
z%  # of miss match rows: {} ouf of {}
)	enumerater   r7   listtuplerP   r   r*   dictr`   r   debug
ValueErrorr+   r0   )r&   invalid_row_idx_listrow_idxinvalid_row_idxr'   rr   r(   validate_rows  s*    



zTableData.validate_rowstabledefault_keyzOrderedDict[str, Any]c                 C   sV   g }| j D ]}|s
qdd t| j|D }|sq|t| q| j}|s'|}||iS )a\  
        Args:
            default_key:
                Key of a returning dictionary when the ``table_name`` is empty.

        Returns:
            dict: Table data as a |dict| instance.

        Sample Code:
            .. code:: python

                from tabledata import TableData

                TableData(
                    "sample",
                    ["a", "b"],
                    [[1, 2], [3.3, 4.4]]
                ).as_dict()

        Output:
            .. code:: json

                {'sample': [OrderedDict([('a', 1), ('b', 2)]), OrderedDict([('a', 3.3), ('b', 4.4)])]}
        c                 S   s    g | ]\}}|d ur||fqS rA   r'   )rH   rq   r@   r'   r'   r(   rJ   O  s    z%TableData.as_dict.<locals>.<listcomp>)rM   rh   r   r*   r   r   )r&   r   	dict_bodyrs   valuesr   r'   r'   r(   as_dict0  s   

zTableData.as_dictc                 c   sB    t d| j}| jD ]}t|rq
|dd |D  }|V  q
dS )a4  
        :return: Rows of the tuple.
        :rtype: list of |namedtuple|

        :Sample Code:
            .. code:: python

                from tabledata import TableData

                records = TableData(
                    "sample",
                    ["a", "b"],
                    [[1, 2], [3.3, 4.4]]
                ).as_tuple()
                for record in records:
                    print(record)

        :Output:
            .. code-block:: none

                Row(a=1, b=2)
                Row(a=Decimal('3.3'), b=Decimal('4.4'))
        Rowc                 s   s    | ]}|j V  qd S rA   rE   rG   r'   r'   r(   	<genexpr>}  s    z%TableData.as_tuple.<locals>.<genexpr>N)r   r   rL   rQ   rY   )r&   r   rK   rs   r'   r'   r(   as_tuple^  s   

zTableData.as_tuplepandas.DataFramec                 C   sF   zddl m} W n ty   tdw || j}|  s!| j|_|S )aV  
        :return: Table data as a ``pandas.DataFrame`` instance.
        :rtype: pandas.DataFrame

        :Sample Code:
            .. code-block:: python

                from tabledata import TableData

                TableData(
                    "sample",
                    ["a", "b"],
                    [[1, 2], [3.3, 4.4]]
                ).as_dataframe()

        :Output:
            .. code-block:: none

                     a    b
                0    1    2
                1  3.3  4.4

        :Dependency Packages:
            - `pandas <https://pandas.pydata.org/>`__
        r   )	DataFramez8required 'pandas' package to execute as_dataframe method)pandasr   ImportErrorRuntimeErrorrM   rZ   r   columns)r&   r   	dataframer'   r'   r(   as_dataframe  s   
zTableData.as_dataframec                 C   s&   t | j| jdd t| j D | jdS )Nc                 S   s   g | ]}|qS r'   r'   )rH   rs   r'   r'   r(   rJ     s    z'TableData.transpose.<locals>.<listcomp>r   )r   r   r   rh   r   r   r>   r'   r'   r(   	transpose  s   zTableData.transposeFpatternsis_invert_matchis_re_matchpattern_matchc                 C   s   t d|||| |s| S g }g }|tjkrt}n|tjkr#t}ntd| t	| j
t	| j D ]/\}}	g }
|D ]}| |||}|
t|oK| | oO|g q;||
rb|| ||	 q3t d| j| t| j|tt	| | jdS )NzPfilter_column: patterns={}, is_invert_match={}, is_re_match={}, pattern_match={}zunknown matching: z-filter_column: table={}, match_header_list={}r   )r   ry   r+   r   ORr\   ANDr`   rz   rh   r   r   _TableData__is_matchr*   r   r   rv   r   )r&   r   r   r   r   match_header_listmatch_column_matrixmatch_methodrq   columnis_match_listpatternis_matchr'   r'   r(   filter_column  sJ   




zTableData.filter_column r   c                 C   s    t |t| jj| j ||dS )z
        Initialize TableData instance from a pandas.DataFrame instance.

        :param pandas.DataFrame dataframe:
        :param str table_name: Table name to create.
        )r   r   )r   rv   r   r   tolist)r   r   r   r   r'   r'   r(   from_dataframe  s   
zTableData.from_dataframerq   r   c                 C   s   |r
t || d uS | |kS rA   )research)rq   r   r   r'   r'   r(   
__is_match  s   zTableData.__is_match)NNNN)T)r   N)r   )r   r   )r   r   )r   NN):__name__
__module____qualname____doc__r   strr   r"   r#   r	   r   intr)   r2   r   boolr:   r;   propertyr   setterr   r   r
   rM   rN   r   r0   r/   rL   rv   DataPropertyrV   ColumnDataPropertyrX   r   rZ   r[   r]   r8   rg   r_   r^   rp   r~   rx   r   r   rw   r   r   r   r   r   r   staticmethodr   r   r'   r'   r'   r(   r      s    	
%


 .
#
&

5
 r   )r   r   r   collectionsr   r   collections.abcr   r   typingr   r   r   r	   datapropertyr"   rQ   r
   dataproperty.typingr   r   	_constantr   
_converterr   _loggerr   r   r   r'   r'   r'   r(   <module>   s"    