o
    b9                     @   sp   d dl m Z  d dlmZ d dlmZmZ d dlmZ d dlmZm	Z	m
Z
mZ G dd deZG dd	 d	eZd
S )    )copy)Strict)MinMaxSequence)Serialisable)range_boundariesrange_to_tupleget_column_letterquote_sheetnamec                   @   st  e Zd ZdZeddedZeddedZeddedZeddedZ			dBddZ
ed	d
 Zedd Zedd Zedd Zedd Zdd Zdd Zdd Zdd ZdCddZdd Zd d! Zd"d# ZeZd$d% Zd&d' ZeZd(d) Zd*d+ Zd,d- Zd.d/ Z e Z!d0d1 Z"e"Z#d2d3 Z$dDd4d5Z%dDd6d7Z&ed8d9 Z'ed:d; Z(ed<d= Z)ed>d? Z*ed@dA Z+dS )E	CellRangea  
    Represents a range in a sheet: title and coordinates.

    This object is used to perform operations on ranges, like:

    - shift, expand or shrink
    - union/intersection with another sheet range,

    We can check whether a range is:

    - equal or not equal to another,
    - disjoint of another,
    - contained in another.

    We can get:

    - the size of a range.
    - the range bounds (vertices)
    - the coordinates,
    - the string representation,

       ifG  )minmaxexpected_typei   Nc                 C   s   |d urd|v rt |\}\}}}}nt|\}}}}|| _|| _|| _|| _|| _||kr9d}t|j||d||krHd}t|j||dd S )N!z({max_col} must be greater than {min_col})min_colmax_colz({max_row} must be greater than {min_row})min_rowmax_row)	r   r   r   r   r   r   title
ValueErrorformat)selfZrange_stringr   r   r   r   r   fmt r   \/var/www/secure340b-portal/env/lib/python3.10/site-packages/openpyxl/worksheet/cell_range.py__init__/   s    zCellRange.__init__c                 C   s   | j | j| j| jfS )z2
        Vertices of the range as a tuple
        r   r   r   r   r   r   r   r   boundsE   s   zCellRange.boundsc                 C   sB   d}| j | jkr| j| jkrd}|jt| j | jt| j| jdS )z9
        Excel-style representation of the range
        z%{min_col}{min_row}:{max_col}{max_row}z{min_col}{min_row}r   )r   r   r   r   r   r	   r   r   r   r   r   coordM   s   
zCellRange.coordc                 #   @    t | j| jd D ]  fddt | j| jd D V  q
dS )z1
        Return cell coordinates as rows
        r   c                    s   g | ]} |fqS r   r   .0colrowr   r   
<listcomp>d       z"CellRange.rows.<locals>.<listcomp>N)ranger   r   r   r   r   r   r&   r   rows^      $zCellRange.rowsc                 #   r"   )z4
        Return cell coordinates as columns
        r   c                    s   g | ]}| fqS r   r   r$   r'   r%   r   r   r(   m   r)   z"CellRange.cols.<locals>.<listcomp>N)r*   r   r   r   r   r   r   r.   r   colsg   r,   zCellRange.colsc                 C   s2   ddl m} |t| j| jd t| j| jd S )Nr   )productr   )	itertoolsr0   r*   r   r   r   r   )r   r0   r   r   r   cellsp   s   &zCellRange.cellsc                 C   s<   t |tsttt||jr| j|jkrtddS dS )z
        Check whether comparisons between ranges are possible.
        Cannot compare ranges from different worksheets
        Skip if the range passed in has no title.
        z1Cannot work with ranges from different worksheetsN)
isinstancer   	TypeErrorreprtyper   r   r   otherr   r   r   _check_titlev   s
   
zCellRange._check_titlec                 C   s&   d}| j rd}|j| jj| j | jdS )Nz<{cls} {coord}>z<{cls} {title!r}!{coord}>)clsr   r!   )r   r   	__class____name__r!   r    r   r   r   __repr__   s   zCellRange.__repr__c                 C   s*   d}| j }|rd}t|}|j|| jdS )Nz{coord}z{title}!{coord})r   r!   )r   r
   r   r!   )r   r   r   r   r   r   __str__   s   zCellRange.__str__c                 C   s   | j | j| j| j| j| jdS )Nr   r   r   r   r   )r;   r   r   r   r   r   r   r   r   r   __copy__   s   zCellRange.__copy__r   c                 C   sh   | j | dks| j| dkrtd|||  j |7  _ |  j|7  _|  j|7  _|  j|7  _dS )a{  
        Shift the focus of the range according to the shift values (*col_shift*, *row_shift*).

        :type col_shift: int
        :param col_shift: number of columns to be moved by, can be negative
        :type row_shift: int
        :param row_shift: number of rows to be moved by, can be negative
        :raise: :class:`ValueError` if any row or column index < 1
        r   z1Invalid shift value: col_shift={0}, row_shift={1}N)r   r   r   r   r   r   )r   Z	col_shiftZ	row_shiftr   r   r   shift   s   zCellRange.shiftc                 C   sT   z|  | W n
 ty   Y dS w |j| jkp)| j|jkp)|j| jkp)| j|jkS )z
        Test whether the ranges are not equal.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range
        :return: ``True`` if *range* != *other*.
        T)r9   r   r   r   r   r   r7   r   r   r   __ne__   s   


zCellRange.__ne__c                 C   s   |  | S )z
        Test whether the ranges are equal.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range
        :return: ``True`` if *range* == *other*.
        )rB   r7   r   r   r   __eq__   s   zCellRange.__eq__c                 C   s^   |  | |j| j  ko| j  ko|jkn  o.|j| j  ko,| j  ko,|jkS   S )z
        Test whether every cell in this range is also in *other*.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range
        :return: ``True`` if *range* <= *other*.
        r9   r   r   r   r   r7   r   r   r   issubset      
*"zCellRange.issubsetc                 C      |  |o	| |S )z
        Test whether *other* contains every cell of this range, and more.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range
        :return: ``True`` if *range* < *other*.
        )__le__rB   r7   r   r   r   __lt__      zCellRange.__lt__c                 C   s^   |  | | j|j  ko|j  ko| jkn  o.| j|j  ko,|j  ko,| jkS   S )z
        Test whether every cell in *other* is in this range.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range
        :return: ``True`` if *range* >= *other* (or *other* in *range*).
        rD   r7   r   r   r   
issuperset   rF   zCellRange.issupersetc                 C   s$   t |}|jdu r| j|_| |S )zO
        Check whether the range contains a particular cell coordinate
        N)r   r   rK   r   r!   crr   r   r   __contains__   s   

zCellRange.__contains__c                 C   rG   )z
        Test whether this range contains every cell in *other*, and more.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range
        :return: ``True`` if *range* > *other*.
        )__ge__rB   r7   r   r   r   __gt__  rJ   zCellRange.__gt__c                 C   sD   |  | | j|jkr|| } }| j|jk p!| j|jk p!|j| jk S )aV  
        Return ``True`` if this range has no cell in common with *other*.
        Ranges are disjoint if and only if their intersection is the empty range.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range.
        :return: ``True`` if the range has no cells in common with other.
        )r9   r   r   r   r   r   r7   r   r   r   
isdisjoint  s   
	


zCellRange.isdisjointc                 C   sb   |  |rtd| |t| j|j}t| j|j}t| j|j}t| j|j}t	||||dS )aN  
        Return a new range with cells common to this range and *other*

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range.
        :return: the intersecting sheet range.
        :raise: :class:`ValueError` if the *other* range doesn't intersect
            with this range.
        zRange {0} doesn't intersect {0}r   )
rQ   r   r   r   r   r   r   r   r   r   r   r8   r   r   r   r   r   r   r   intersection'  s   

zCellRange.intersectionc                 C   sV   |  | t| j|j}t| j|j}t| j|j}t| j|j}t||||| jdS )a  
        Return the minimal superset of this range and *other*. This new range
        will contain all cells from this range, *other*, and any additional
        cells required to form a rectangular ``CellRange``.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range.
        :return: a ``CellRange`` that is a superset of this and *other*.
        r?   )	r9   r   r   r   r   r   r   r   r   rR   r   r   r   union?  s   

zCellRange.unionc                 c   s0    | j D ]}|dkrqt| |}||fV  qdS )zC
        For use as a dictionary elsewhere in the library.
        r   N)	__attrs__getattr)r   xvr   r   r   __iter__U  s   

zCellRange.__iter__c                 C   s<   |  j |8  _ |  j|8  _|  j|7  _|  j|7  _dS )a  
        Expand the range by the dimensions provided.

        :type right: int
        :param right: expand range to the right by this number of cells
        :type down: int
        :param down: expand range down by this number of cells
        :type left: int
        :param left: expand range to the left by this number of cells
        :type up: int
        :param up: expand range up by this number of cells
        Nr   )r   rightZdownleftupr   r   r   expand`     zCellRange.expandc                 C   s<   |  j |7  _ |  j|7  _|  j|8  _|  j|8  _dS )a  
        Shrink the range by the dimensions provided.

        :type right: int
        :param right: shrink range from the right by this number of cells
        :type down: int
        :param down: shrink range from the top by this number of cells
        :type left: int
        :param left: shrink range from the left by this number of cells
        :type up: int
        :param up: shrink range from the bottown by this number of cells
        Nr   )r   rZ   bottomr[   topr   r   r   shrinks  r^   zCellRange.shrinkc                 C   s*   | j d | j }| jd | j }||dS )zC Return the size of the range as a dictionary of rows and columns. r   )columnsr+   )r   r   r   r   )r   r/   r+   r   r   r   size  s   
zCellRange.sizec                         fddt  j jd D S )z=A list of cell coordinates that comprise the top of the rangec                       g | ]} j |fqS r   )r   r#   r   r   r   r(         z!CellRange.top.<locals>.<listcomp>r   r*   r   r   r   r   r   r   r`         zCellRange.topc                    rd   )z@A list of cell coordinates that comprise the bottom of the rangec                    re   r   )r   r#   r   r   r   r(     rf   z$CellRange.bottom.<locals>.<listcomp>r   rg   r   r   r   r   r_     rh   zCellRange.bottomc                    rd   )zCA list of cell coordinates that comprise the left-side of the rangec                       g | ]}| j fqS r   )r   r-   r   r   r   r(     rf   z"CellRange.left.<locals>.<listcomp>r   r*   r   r   r   r   r   r   r[     rh   zCellRange.leftc                    rd   )zDA list of cell coordinates that comprise the right-side of the rangec                    ri   r   )r   r-   r   r   r   r(     rf   z#CellRange.right.<locals>.<listcomp>r   rj   r   r   r   r   rZ     rh   zCellRange.right)NNNNNN)r   r   )r   r   r   r   ),r<   
__module____qualname____doc__r   intr   r   r   r   r   propertyr   r!   r+   r/   r2   r9   r=   r>   r@   rA   rB   rC   rE   rH   rI   rK   rO   rN   rP   rQ   rS   __and__rT   __or__rY   r]   ra   rc   r`   r_   r[   rZ   r   r   r   r   r      sf    





	







r   c                   @   s|   e Zd ZeedZdddZdd Zdd Zd	d
 Z	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S )MultiCellRange)r   r   c                 C   s&   t |trdd | D }|| _d S )Nc                 S      g | ]}t |qS r   )r   r$   rr   r   r   r(     r)   z+MultiCellRange.__init__.<locals>.<listcomp>)r3   strsplitrangesr   rx   r   r   r   r     s   

zMultiCellRange.__init__c                 C   s0   t |tr	t|}| jD ]	}||kr dS qdS )NTF)r3   rv   r   rx   )r   r!   ru   r   r   r   rN     s   

zMultiCellRange.__contains__c                 C   s&   d dd | jD }d| jj|S )N c                 S   rs   r   rv   rt   r   r   r   r(     r)   z+MultiCellRange.__repr__.<locals>.<listcomp>z<{0} [{1}]>)joinrx   r   r;   r<   ry   r   r   r   r=     s   zMultiCellRange.__repr__c                 C   s   d dd | jD }|S )Nrz   c                 S   rs   r   r{   rt   r   r   r   r(     r)   z*MultiCellRange.__str__.<locals>.<listcomp>)r|   rx   ry   r   r   r   r>     s   zMultiCellRange.__str__c                 C   sF   |}t |trt|}n	t |tstd|| vr!| j| dS dS )z4
        Add a cell coordinate or CellRange
        zYou can only add CellRangesN)r3   rv   r   r   rx   appendrL   r   r   r   add  s   


zMultiCellRange.addc                 C   s   |  | | S N)r~   r   r!   r   r   r   __iadd__  s   
zMultiCellRange.__iadd__c                 C   s    t |tr
| |}| j|jkS r   )r3   rv   r;   rx   r7   r   r   r   rC     s   

zMultiCellRange.__eq__c                 C   s
   | |k S r   r   r7   r   r   r   rB        
zMultiCellRange.__ne__c                 C   s
   t | jS r   )boolrx   r   r   r   r   __bool__  r   zMultiCellRange.__bool__c                 C   s"   t |ts	t|}| j| d S r   )r3   r   rx   remover   r   r   r   r     s   
zMultiCellRange.removec                 c   s    | j D ]}|V  qd S r   )rx   )r   rM   r   r   r   rY     s   
zMultiCellRange.__iter__c                 C   s&   t  }| jD ]
}|jt| q|S r   )rr   rx   r}   r   )r   nru   r   r   r   r@     s   
zMultiCellRange.__copy__N)r   )r<   rk   rl   r   r   rx   r   rN   r=   r>   r~   r   rC   rB   r   r   rY   r@   r   r   r   r   rr     s    

	rr   N)r   Zopenpyxl.descriptorsr   r   r   Z!openpyxl.descriptors.serialisabler   Zopenpyxl.utilsr   r   r	   r
   r   rr   r   r   r   r   <module>   s      