o
    ‹¨Êh[r  ã                   @   sÀ   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	 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 d
dlmZ G dd„ deƒZdd„ Zdd„ Zdd„ Zdd„ ZdS )a  
    pyexcel.internal.sheets.matrix
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Matrix, a data model that accepts any types, spread sheet style
    of lookup.

    :copyright: (c) 2014-2017 by Onni Software Ltd.
    :license: New BSD License, see LICENSE for more details
é    N)Úpartial)Úchain)Ú	SheetMeta)ÚRow)ÚColumn)Ú	to_format)ÚPyexcelListé   )Ú_sharedc                   @   sj  e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dXdd„Z
dd„ Zdd„ ZdYdd„Zdd„ Zdd„ Zdd„ Zdd„ ZdYd d!„Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ ZdZd,d-„Zd.d/„ Zd0d1„ Zd2d3„ Zd4d5„ Zd6d7„ Zd8d9„ Zd:d;„ Zd<d=„ Z d>d?„ Z!d@dA„ Z"dBdC„ Z#dDdE„ Z$dFdG„ Z%dHdI„ Z&dJdK„ Z'dLdM„ Z(dNdO„ Z)dZdPdQ„Z*dRdS„ Z+dTdU„ Z,dVdW„ Z-dS )[ÚMatrixz]The internal representation of a sheet data. Each element
    can be of any python types
    c                 C   sl   t |tjƒrtt|ƒƒ\| _| _nz
t|ƒ\| _| _W n ty&   tdƒ‚w t| ƒ| _	t
| ƒ| _d| _dS )zæConstructor

        The reason a deep copy was not made here is because
        the data sheet could be huge. It could be costly to
        copy every cell to a new memory area
        :param list array: a list of arrays
        zInvalid two dimensional arrayÚmatrixN)Ú
isinstanceÚtypesÚGeneratorTypeÚuniformÚlistÚ_Matrix__widthÚ_Matrix__arrayÚ	TypeErrorr   Úrowr   ÚcolumnÚname)ÚselfÚarray© r   úP/var/www/html/env/lib/python3.10/site-packages/pyexcel/internal/sheets/matrix.pyÚ__init__   s   ÿ


zMatrix.__init__c                 C   ó   | j S )zpresent internal array©r   ©r   r   r   r   Úget_internal_array2   s   zMatrix.get_internal_arrayc                 C   s
   t | jƒS )zThe number of rows)Úlenr   r   r   r   r   Únumber_of_rows6   s   
zMatrix.number_of_rowsc                 C   s   |   ¡ dkr	| jS dS )zThe number of columnsr   )r"   r   r   r   r   r   Únumber_of_columns:   s   zMatrix.number_of_columnsc                 C   ó   t  |  ¡ ¡S )z3
        Utility function to get row range
        )ÚcompactÚiranger"   r   r   r   r   Ú	row_rangeA   ó   zMatrix.row_rangec                 C   r$   )z6
        Utility function to get column range
        )r%   r&   r#   r   r   r   r   Úcolumn_rangeG   r(   zMatrix.column_rangeNc                 C   sh   ||   ¡ k r ||  ¡ k r |du r| j| | S || j| |< dS |du r(tdƒ‚|  ||f|gg¡ dS )zÜRandom access to table cells

        :param int row: row index which starts from 0
        :param int column: column index which starts from 0
        :param any new_value: new value if this is to set the value
        NzIndex out of range)r"   r#   r   Ú
IndexErrorÚpaste)r   r   r   Ú	new_valuer   r   r   Ú
cell_valueM   s   zMatrix.cell_valuec                 C   s`   ||   ¡ v rtt | j| ¡ƒS |dk r+t |¡|   ¡ v r+tt | j||  ¡   ¡ƒS tt	j
ƒ‚)z4
        Gets the data at the specified row
        r   )r'   r   ÚcopyÚdeepcopyr   ÚutilsÚabsr"   r*   Ú	constantsÚMESSAGE_INDEX_OUT_OF_RANGE)r   Úindexr   r   r   Úrow_ata   s   ÿ
zMatrix.row_atc                 C   sN   |   ¡ }||k r"|| j|< t|ƒ|  ¡ kr t| jƒ\| _| _dS dS ttjƒ‚)z Update a row data range
        N)	r"   r   r!   r#   r   r   r*   r2   r3   )r   Ú	row_indexÚ
data_arrayÚnrowsr   r   r   Ú
set_row_atp   s   
ÿ
zMatrix.set_row_atr   c           
      C   s¨   |   ¡ }|  ¡ }||k rO||k rOt|ƒ| }t||ƒ}t||ƒD ]}|  |||||  ¡ q ||krD|| }	| j| ||	d…  | j|< t| jƒ\| _| _dS t	t
jƒ‚)aH  Update a row data range

        It works like this if the call is: set_row_at(2, ['N', 'N', 'N'], 1)::

            A B C
            1 3 5
            2 N N <- row_index = 2
              ^starting = 1

        This function will not set element outside the current table range

        :param int row_index: which row to be modified
        :param list data_array: one dimensional array
        :param int starting: from which index, the update happens
        :raises IndexError: if row_index exceeds row range or starting
                            exceeds column range
        N)r"   r#   r!   ÚminÚranger-   r   r   r   r*   r2   r3   )
r   r6   r7   Ústartingr8   ÚncolumnsÚreal_lenÚendÚiÚleftr   r   r   Ú_set_row_at{   s   
ÿ
zMatrix._set_row_atc                 C   s8   t  |¡}t |t¡r|  j|7  _d S | j |¡ d S ©N)r.   r/   r%   Úis_array_typer   r   Úappend)r   r   r   r   r   r   Ú_extend_row�   s   
zMatrix._extend_rowc                 C   s:   t |tƒr|  |¡ t| jƒ\| _| _dS tdt|ƒ ƒ‚)z1Inserts two dimensional data after the bottom rowzCannot use %sN)r   r   rF   r   r   r   r   Útype©r   Úrowsr   r   r   Úextend_rows¤   s   

zMatrix.extend_rowsc                 C   s`   t |tƒdu r	t‚t|ƒdkr,t|ƒ}t|dd�}|D ]}||  ¡ k r+|dkr+| j|= qdS dS )zDeletes specified row indicesFr   T©ÚreverseN)r   r   r*   r!   Ú_uniqueÚsortedr"   r   )r   Úrow_indicesÚunique_listÚsorted_listr@   r   r   r   Údelete_rows¬   s   €ûzMatrix.delete_rowsc                 C   sŠ   t ƒ }||  ¡ v r|  ¡ D ]}| |  ||¡¡ q|S |dk r@t |¡|  ¡ v r@|  ¡ | }|  ¡ D ]}| |  ||¡¡ q2|S tt	j
ƒ‚)z7
        Gets the data at the specified column
        r   )r   r)   r'   rE   r-   r0   r1   r#   r*   r2   r3   )r   r4   Ú
cell_arrayr@   Úreverse_indexr   r   r   Ú	column_at·   s   
zMatrix.column_atc           
      C   s¸   |   ¡ }|  ¡ }||k rW||k rWt|ƒ| }t||ƒ}t||ƒD ]}|  |||||  ¡ q ||krLt||ƒD ]}dg| |||  g }	| j |	¡ q7t| jƒ\| _	| _dS t
tjƒ‚)ay  Updates a column data range

        It works like this if the call is:
        set_column_at(2, ['N','N', 'N'], 1)::

                +--> column_index = 2
                |
            A B C
            1 3 N <- starting = 1
            2 4 N

        This function will not set element outside the current table range

        :param int column_index: which column to be modified
        :param list data_array: one dimensional array
        :param int staring: from which index, the update happens
        :raises IndexError: if column_index exceeds column range
                            or starting exceeds row range
        Ú N)r"   r#   r!   r:   r;   r-   r   rE   r   r   r*   r2   r3   )
r   Úcolumn_indexr7   r<   r8   r=   r>   r?   r@   Únew_rowr   r   r   Úset_column_atÊ   s   

zMatrix.set_column_atc                 C   s@   t |tƒs
ttjƒ‚|}t |t¡s|g}t|ƒ}|  |¡ dS )zµInserts two dimensional data after the rightmost column

        This is how it works:

        Given::

            s s s     t t

        Get::

            s s s  +  t t
        N)	r   r   r   r2   Ú%MESSAGE_DATA_ERROR_DATA_TYPE_MISMATCHr%   rD   Ú	transposeÚ_extend_columns_with_rows)r   ÚcolumnsÚincoming_datar   r   r   Úextend_columnsí   s   

zMatrix.extend_columnsc                 C   s´   |   ¡ }|  ¡ }t|ƒ}t||ƒ}td|ƒD ]}t || ¡}| j|  |7  < q||k rO|| }|}	td|ƒD ]}tj	g| }
|
||	|  7 }
| j 
|
¡ q8t| jƒ\| _| _d S )Nr   )r"   r#   r!   r:   r;   r.   r/   r   r2   Ú
DEFAULT_NArE   r   r   )r   rI   Úcurrent_nrowsÚcurrent_ncolsÚinsert_column_nrowsÚarray_lengthr@   r   ÚdeltaÚbaseÚ	new_arrayr   r   r   r\     s   
z Matrix._extend_columns_with_rowsc                 C   s   |   |¡ dS )aK  Rows were appended to the rightmost side

        example::

            >>> import pyexcel as pe
            >>> data = [
            ...     [1],
            ...     [2],
            ...     [3]
            ... ]
            >>> matrix = pe.Sheet(data)
            >>> matrix
            pyexcel sheet:
            +---+
            | 1 |
            +---+
            | 2 |
            +---+
            | 3 |
            +---+
            >>> rows = [
            ...      [11, 11],
            ...      [22, 22]
            ... ]
            >>> matrix.extend_columns_with_rows(rows)
            >>> matrix
            pyexcel sheet:
            +---+----+----+
            | 1 | 11 | 11 |
            +---+----+----+
            | 2 | 22 | 22 |
            +---+----+----+
            | 3 |    |    |
            +---+----+----+
        N)r\   rH   r   r   r   Úextend_columns_with_rows  s   $zMatrix.extend_columns_with_rowsc           	      C   st   g }t |d |  ¡ ƒ}t |d |  ¡ ƒ}t|d |ƒD ]}g }t|d |ƒD ]}| |  ||¡¡ q&| |¡ q|S )zîGet a rectangle shaped data out

        :param slice topleft_corner: the top left corner of the rectangle
        :param slice bottomright_corner: the bottom right
                                         corner of the rectangle
        r   r	   )r:   r"   r#   r;   rE   r-   )	r   Útopleft_cornerÚbottomright_cornerÚregionÚmax_rowÚmax_colr   Útmp_rowr   r   r   r   rk   9  s   zMatrix.regionc                 C   sP   |   ||¡}t|d |d ƒD ]}t|d |d ƒD ]
}|  ||tj¡ qq|S )a	  Get a rectangle shaped data out and clear them in position

        :param slice topleft_corner: the top left corner of the rectangle
        :param slice bottomright_corner: the bottom right
                                         corner of the rectangle
        r   r	   )rk   r;   r-   r2   r`   )r   ri   rj   rk   r   r   r   r   r   ÚcutJ  s   ÿz
Matrix.cutc                 C   s2   |r
|   ||¡ dS |r|  ||¡ dS ttjƒ‚)a  Paste a rectangle shaped data after a position

        :param slice topleft_corner: the top left corner of the rectangle

        example::

            >>> import pyexcel as pe
            >>> data = [
            ...     # 0 1  2  3  4 5   6
            ...     [1, 2, 3, 4, 5, 6, 7], #  0
            ...     [21, 22, 23, 24, 25, 26, 27],
            ...     [31, 32, 33, 34, 35, 36, 37],
            ...     [41, 42, 43, 44, 45, 46, 47],
            ...     [51, 52, 53, 54, 55, 56, 57]  # 4
            ... ]
            >>> s = pe.Sheet(data)
            >>> # cut  1<= row < 4, 1<= column < 5
            >>> data = s.cut([1, 1], [4, 5])
            >>> s.paste([4,6], rows=data)
            >>> s
            pyexcel sheet:
            +----+----+----+----+----+----+----+----+----+----+
            | 1  | 2  | 3  | 4  | 5  | 6  | 7  |    |    |    |
            +----+----+----+----+----+----+----+----+----+----+
            | 21 |    |    |    |    | 26 | 27 |    |    |    |
            +----+----+----+----+----+----+----+----+----+----+
            | 31 |    |    |    |    | 36 | 37 |    |    |    |
            +----+----+----+----+----+----+----+----+----+----+
            | 41 |    |    |    |    | 46 | 47 |    |    |    |
            +----+----+----+----+----+----+----+----+----+----+
            | 51 | 52 | 53 | 54 | 55 | 56 | 22 | 23 | 24 | 25 |
            +----+----+----+----+----+----+----+----+----+----+
            |    |    |    |    |    |    | 32 | 33 | 34 | 35 |
            +----+----+----+----+----+----+----+----+----+----+
            |    |    |    |    |    |    | 42 | 43 | 44 | 45 |
            +----+----+----+----+----+----+----+----+----+----+
            >>> s.paste([6,9], columns=data)
            >>> s
            pyexcel sheet:
            +----+----+----+----+----+----+----+----+----+----+----+----+
            | 1  | 2  | 3  | 4  | 5  | 6  | 7  |    |    |    |    |    |
            +----+----+----+----+----+----+----+----+----+----+----+----+
            | 21 |    |    |    |    | 26 | 27 |    |    |    |    |    |
            +----+----+----+----+----+----+----+----+----+----+----+----+
            | 31 |    |    |    |    | 36 | 37 |    |    |    |    |    |
            +----+----+----+----+----+----+----+----+----+----+----+----+
            | 41 |    |    |    |    | 46 | 47 |    |    |    |    |    |
            +----+----+----+----+----+----+----+----+----+----+----+----+
            | 51 | 52 | 53 | 54 | 55 | 56 | 22 | 23 | 24 | 25 |    |    |
            +----+----+----+----+----+----+----+----+----+----+----+----+
            |    |    |    |    |    |    | 32 | 33 | 34 | 35 |    |    |
            +----+----+----+----+----+----+----+----+----+----+----+----+
            |    |    |    |    |    |    | 42 | 43 | 44 | 22 | 32 | 42 |
            +----+----+----+----+----+----+----+----+----+----+----+----+
            |    |    |    |    |    |    |    |    |    | 23 | 33 | 43 |
            +----+----+----+----+----+----+----+----+----+----+----+----+
            |    |    |    |    |    |    |    |    |    | 24 | 34 | 44 |
            +----+----+----+----+----+----+----+----+----+----+----+----+
            |    |    |    |    |    |    |    |    |    | 25 | 35 | 45 |
            +----+----+----+----+----+----+----+----+----+----+----+----+

        N)Ú_paste_rowsÚ_paste_columnsÚ
ValueErrorr2   Ú MESSAGE_DATA_ERROR_EMPTY_CONTENT)r   ri   rI   r]   r   r   r   r+   W  s
   ?
zMatrix.pastec                    sÈ   |\}}|   ¡ }|  ¡ }|| }|dkr*t||ƒ‰ ‡ fdd„t |¡D ƒ}|  |¡ |   ¡ }t|ƒD ]&\}	}
||	 }||k rI| j||
|d d� q2tj	g|d  |
 }|  |¡ q2t
| jƒ\| _| _d S )Nr   c                    s    g | ]}d d„ t  ˆ ¡D ƒ‘qS )c                 S   s   g | ]}t j‘qS r   )r2   r`   )Ú.0Ú_r   r   r   Ú
<listcomp>¥  s    z1Matrix._paste_rows.<locals>.<listcomp>.<listcomp>)r%   r&   )rt   Ú__©Úmax_columnsr   r   rv   ¤  s    ÿÿz&Matrix._paste_rows.<locals>.<listcomp>r	   ©r<   )r"   r#   Úmaxr%   r&   rF   Ú	enumeraterB   r2   r`   r   r   r   )r   ri   rI   Ústarting_rowÚstarting_columnr"   r#   re   Ú	empty_rowr4   r   Ú	set_indexÚreal_rowr   rx   r   rp   �  s$   

þ
zMatrix._paste_rowsc           	      C   s‚   |d }|   ¡ }t|ƒD ])\}}|| }||k r#| j|||d d� qtjg|d  }||7 }|  |g¡ qt| jƒ\| _| _d S )Nr	   r   rz   )	r#   r|   rY   r2   r`   r_   r   r   r   )	r   ri   r]   r~   r#   r4   r   r€   Úreal_columnr   r   r   rq   ³  s   
ÿzMatrix._paste_columnsc                 C   s„   t |tƒdu rttjƒ‚t|ƒdkr@t|ƒ}t|dd�}|  ¡ D ]}|D ]}||  	¡ k r6|dkr6| j
| |= q$q t| j
ƒ| _dS dS )z4Delete columns by specified list of indices
        Fr   TrK   N)r   r   r   r2   rZ   r!   rM   rN   r'   r#   r   Úlongest_row_numberr   )r   Úcolumn_indicesrP   rQ   r@   Újr   r   r   Údelete_columnsÂ  s   
€þùzMatrix.delete_columnsc                 C   sJ   t |tƒr|  |d |d |¡S t |tƒr#t |¡\}}|  |||¡S t‚)z"Override the operator to set itemsr   r	   )r   Útupler-   Ústrr0   Úexcel_cell_positionr*   )r   Úasetr-   r   r   r   r   r   Ú__setitem__Ð  s   

zMatrix.__setitem__c                 C   sd   t |tƒr|  |d |d ¡S t |tƒr!t |¡\}}|  ||¡S t |tƒr0ttj	ƒ |  
|¡S t‚)zNBy default, this class recognize from top to bottom
        from left to rightr   r	   )r   r‡   r-   rˆ   r0   r‰   ÚintÚprintr2   ÚMESSAGE_DEPRECATED_ROW_COLUMNr5   r*   )r   rŠ   r   r   r   r   r   Ú__getitem__Ú  s   




zMatrix.__getitem__c                 C   s    |   ¡ D ]	}||ƒr dS qdS )zHas something in the tableTF©rI   )r   Ú	predicater   r   r   r   Úcontainsè  s
   ÿzMatrix.containsc                 C   s"   t | jƒ| _t| jƒ\| _| _dS )zQRotate the data table by 90 degrees

        Reference :func:`transpose`
        N)r[   r   r   r   r   r   r   r   r[   ï  s   zMatrix.transposec                 C   r   )zGet an array out
        r   r   r   r   r   Úto_array÷  s   zMatrix.to_arrayc                 C   s   |   ¡ S )z
        Default iterator to go through each cell one by one from top row to
        bottom row and from left to right
        r�   r   r   r   r   Ú__iter__ü  s   zMatrix.__iter__c                 C   s
   t | jŽ S )aä  
        Iterate cell by cell from top to bottom and from left to right

        .. testcode::

            >>> import pyexcel as pe
            >>> data = [
            ...     [1, 2, 3, 4],
            ...     [5, 6, 7, 8],
            ...     [9, 10, 11, 12]
            ... ]
            >>> m = pe.internal.sheets.Matrix(data)
            >>> print(list(m.enumerate()))
            [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

        More details see :class:`HTLBRIterator`
        )r   r   r   r   r   r   r|     s   
zMatrix.enumeratec                 c   s*   � t | jƒD ]}t |ƒD ]}|V  qqdS )a  Opposite to enumerate

        each cell one by one from
        bottom row to top row and from right to left
        example::

            >>> import pyexcel as pe
            >>> data = [
            ...     [1, 2, 3, 4],
            ...     [5, 6, 7, 8],
            ...     [9, 10, 11, 12]
            ... ]
            >>> m = pe.internal.sheets.Matrix(data)
            >>> print(list(m.reverse()))
            [12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

        More details see :class:`HBRTLIterator`
        N©Úreversedr   )r   r   Úcellr   r   r   rL     s   €ÿÿzMatrix.reversec                 C   s   t tj| jŽ Ž S )a  
        Default iterator to go through each cell one by one from
        leftmost column to rightmost row and from top to bottom
        example::

            import pyexcel as pe
            data = [
                [1, 2, 3, 4],
                [5, 6, 7, 8],
                [9, 10, 11, 12]
            ]
            m = pe.internal.sheets.Matrix(data)
            print(list(m.vertical()))

        output::

            [1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]

        More details see :class:`VTLBRIterator`
        )r   r%   Úczipr   r   r   r   r   Úvertical.  s   zMatrix.verticalc                 c   s6   � t jdd„ | jD ƒŽ D ]}t|ƒD ]}|V  qqdS )a  
        Default iterator to go through each cell one by one from rightmost
        column to leftmost row and from bottom to top
        example::

            import pyexcel as pe
            data = [
                [1, 2, 3, 4],
                [5, 6, 7, 8],
                [9, 10, 11, 12]
            ]
            m = pe.internal.sheets.Matrix(data)
            print(pe.utils.to_array(m.rvertical())

        output::

            [12, 8, 4, 11, 7, 3, 10, 6, 2, 9, 5, 1]

        More details see :class:`VBRTLIterator`
        c                 s   ó   � | ]}t |ƒV  qd S rC   ©r–   ©rt   r   r   r   r   Ú	<genexpr>Z  ó   € z#Matrix.rvertical.<locals>.<genexpr>N)r%   r˜   r   r–   )r   r   r—   r   r   r   Ú	rverticalE  s   €ÿÿzMatrix.rverticalc                 c   s   � | j D ]}|V  qdS )aÅ  
        Returns a top to bottom row iterator

        example::

            import pyexcel as pe
            data = [
                [1, 2, 3, 4],
                [5, 6, 7, 8],
                [9, 10, 11, 12]
            ]
            m = pe.internal.sheets.Matrix(data)
            print(pe.utils.to_array(m.rows()))

        output::

            [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]

        More details see :class:`RowIterator`
        Nr   ©r   r   r   r   r   rI   ^  s   €
ÿzMatrix.rowsc                 c   s   � t | jƒD ]}|V  qdS )aØ  
        Returns a bottom to top row iterator

        .. testcode::

            import pyexcel as pe
            data = [
                [1, 2, 3, 4],
                [5, 6, 7, 8],
                [9, 10, 11, 12]
            ]
            m = pe.internal.sheets.Matrix(data)
            print(pe.utils.to_array(m.rrows()))

        .. testoutput::

            [[9, 10, 11, 12], [5, 6, 7, 8], [1, 2, 3, 4]]

        More details see :class:`RowReverseIterator`
        Nr•   r    r   r   r   Úrrowsv  s   €ÿzMatrix.rrowsc                 c   s"   � t j| jŽ D ]}t|ƒV  qdS )aÎ  
        Returns a left to right column iterator

        .. testcode::

            import pyexcel as pe
            data = [
                [1, 2, 3, 4],
                [5, 6, 7, 8],
                [9, 10, 11, 12]
            ]
            m = pe.internal.sheets.Matrix(data)
            print(list(m.columns()))

        .. testoutput::

            [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

        More details see :class:`ColumnIterator`
        N©r%   r˜   r   r   r    r   r   r   r]   Ž  s   €ÿzMatrix.columnsc                 c   s,   � t jdd„ | jD ƒŽ D ]}t|ƒV  qdS )aØ  
        Returns a right to left column iterator

        example::

            import pyexcel as pe
            data = [
                [1, 2, 3, 4],
                [5, 6, 7, 8],
                [9, 10, 11, 12]
            ]
            m = pe.internal.sheets.Matrix(data)
            print(pe.utils.to_array(m.rcolumns()))

        output::

            [[4, 8, 12], [3, 7, 11], [2, 6, 10], [1, 5, 9]]

        More details see :class:`ColumnReverseIterator`
        c                 s   rš   rC   r›   rœ   r   r   r   r�   »  rž   z"Matrix.rcolumns.<locals>.<genexpr>Nr¢   )r   r   r   r   r   Úrcolumns¦  s   €ÿzMatrix.rcolumnsc                 C   s,   |dur	|   |¡ |dur|  |¡ dS dS )z&Apply the filter with immediate effectN)rR   r†   )r   r„   rO   r   r   r   Úfilter¾  s
   
ÿzMatrix.filterc                 C   s   t t|ƒ}|  |¡ dS )aÆ  Apply a formatting action for the whole sheet

        Example::

            >>> import pyexcel as pe
            >>> # Given a dictinoary as the following
            >>> data = {
            ...     "1": [1, 2, 3, 4, 5, 6, 7, 8],
            ...     "3": [1.25, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8],
            ...     "5": [2, 3, 4, 5, 6, 7, 8, 9],
            ...     "7": [1, '',]
            ...     }
            >>> sheet = pe.get_sheet(adict=data)
            >>> sheet.row[1]
            [1, 1.25, 2, 1]
            >>> sheet.format(str)
            >>> sheet.row[1]
            ['1', '1.25', '2', '1']
            >>> sheet.format(int)
            >>> sheet.row[1]
            [1, 1, 2, 1]

        N)r   r   Úmap)r   Ú	formatterÚcustom_functionr   r   r   ÚformatÅ  s   
zMatrix.formatc                 C   sB   |   ¡ D ]}|  ¡ D ]}|  ||¡}||ƒ}|  |||¡ q
qdS )a·  Execute a function across all cells of the sheet

        Example::

            >>> import pyexcel as pe
            >>> # Given a dictinoary as the following
            >>> data = {
            ...     "1": [1, 2, 3, 4, 5, 6, 7, 8],
            ...     "3": [1.25, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8],
            ...     "5": [2, 3, 4, 5, 6, 7, 8, 9],
            ...     "7": [1, '',]
            ...     }
            >>> sheet = pe.get_sheet(adict=data)
            >>> sheet.row[1]
            [1, 1.25, 2, 1]
            >>> inc = lambda value: (float(value) if value != '' else 0)+1
            >>> sheet.map(inc)
            >>> sheet.row[1]
            [2.0, 2.25, 3.0, 2.0]

        N)r'   r)   r-   )r   r§   r   r   Úvaluer   r   r   r¥   à  s   ýÿz
Matrix.mapc           
      C   sÔ   ddl m}m} i }| j|| j< t||ƒrA| ¡ }| ¡ D ]"}|}t| ¡ ƒdkr,|j	}||v r9|ƒ }d||f }|| ||< qnt|t
ƒr^|j}||v rW|ƒ }d|j|f }| ¡ ||< nt‚|ƒ }	|	 |¡ |	S )z:Overload the + sign

        :returns: a new book
        r   )ÚBookÚ
local_uuidr	   z%s_%s)Úpyexcel.bookrª   r«   r   r   r   Úto_dictÚkeysr!   Úfilenamer   r    r   Úload_from_sheets)
r   Úotherrª   r«   ÚcontentÚother_in_dictÚkeyÚnew_keyÚuidÚnew_bookr   r   r   Ú__add__ü  s0   
ù

zMatrix.__add__rC   )r   )NN).Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r    r"   r#   r'   r)   r-   r5   r9   rB   rF   rJ   rR   rU   rY   r_   r\   rh   rk   ro   r+   rp   rq   r†   r‹   r�   r’   r[   r“   r”   r|   rL   r™   rŸ   rI   r¡   r]   r£   r¤   r¨   r¥   r¸   r   r   r   r   r      sX    

"
#&
F

r   c                    s    t ƒ ‰ ˆ j‰‡ ‡fdd„| D ƒS )z¼Return a unique list of the incoming list

    Reference:
    http://stackoverflow.com/questions/480214/
    how-do-you-remove-duplicates-from-a-list-in-python-whilst-preserving-order
    c                    s    g | ]}|ˆ v sˆ|ƒs|‘qS r   r   )rt   Úx©ÚseenÚseen_addr   r   rv   %  s     z_unique.<locals>.<listcomp>)ÚsetÚadd)Úseqr   r¾   r   rM     s   rM   c                 C   s   t | ƒdkrttt | ƒƒS dS )z`Find the length of the longest row in the array

    :param list in_array: a list of arrays
    r   )r!   r{   r¥   )r   r   r   r   rƒ   (  s   rƒ   c                 C   st   t | ƒ}|dkrd| fS | D ]'}t|ƒ}td|ƒD ]}|| du r&tj||< q||k r5|tjg||  7 }q|| fS )zdFill-in empty strings to empty cells to make it MxN

    :param list in_array: a list of arrays
    r   N)rƒ   r!   r;   r2   r`   )r   Úwidthr   Ú
row_lengthr4   r   r   r   r   4  s   
€€r   c                 C   s`   t | ƒ}g }td|ƒD ]"}g }| D ]}|t|ƒk r!| || ¡ q| tj¡ q| |¡ q|S )a
  Rotate clockwise by 90 degrees and flip horizontally

    First column become first row.
    :param list in_array: a list of arrays

    The transformation is::

        1 2 3       1  4
        4 5 6 7 ->  2  5
                    3  6
                    '' 7
    r   )rƒ   r;   r!   rE   r2   r`   )Úin_arrayÚ
max_lengthrg   r@   Úrow_datar   r   r   r   r[   G  s   r[   )r¼   r.   r   Ú	functoolsr   Ú	itertoolsr   Úpyexcel._compactÚ_compactr%   Úpyexcel.constantsr2   Úpyexcel.internal.metar   Úpyexcel.internal.sheets.rowr   Úpyexcel.internal.sheets.columnr   Ú"pyexcel.internal.sheets.formattersr   Ú%pyexcel.internal.sheets.extended_listr   rV   r
   r0   r   rM   rƒ   r   r[   r   r   r   r   Ú<module>   s0    
      