o
    ;Di<                     @   sB  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mZ d dlmZ d dlmZ 			d)ddZee_G dd deZdd Z	
	d*ddZee_	
	d)ddZee_d*ddZee_			
d+ddZee_G dd deZdd Zd,ddZee_G dd  d eZd!d" Zd#d$ Zee_G d%d& d&eZd'd( Zd	S )-    )absolute_importprint_functiondivision)Counter)next)
Comparable)headerTable)sort)cutFNTc              	   C   s   t | ||||||dS )a	  
    Return rows in `a` that are not in `b`. E.g.::

        >>> import petl as etl
        >>> a = [['foo', 'bar', 'baz'],
        ...      ['A', 1, True],
        ...      ['C', 7, False],
        ...      ['B', 2, False],
        ...      ['C', 9, True]]
        >>> b = [['x', 'y', 'z'],
        ...      ['B', 2, False],
        ...      ['A', 9, False],
        ...      ['B', 3, True],
        ...      ['C', 9, True]]
        >>> aminusb = etl.complement(a, b)
        >>> aminusb
        +-----+-----+-------+
        | foo | bar | baz   |
        +=====+=====+=======+
        | 'A' |   1 | True  |
        +-----+-----+-------+
        | 'C' |   7 | False |
        +-----+-----+-------+

        >>> bminusa = etl.complement(b, a)
        >>> bminusa
        +-----+---+-------+
        | x   | y | z     |
        +=====+===+=======+
        | 'A' | 9 | False |
        +-----+---+-------+
        | 'B' | 3 | True  |
        +-----+---+-------+

    Note that the field names of each table are ignored - rows are simply
    compared following a lexical sort. See also the
    :func:`petl.transform.setops.recordcomplement` function.

    If `presorted` is True, it is assumed that the data are already sorted by
    the given key, and the `buffersize`, `tempdir` and `cache` arguments are
    ignored. Otherwise, the data are sorted, see also the discussion of the
    `buffersize`, `tempdir` and `cache` arguments under the
    :func:`petl.transform.sorts.sort` function.

    Note that the default behaviour is not strictly set-like, because 
    duplicate rows are counted separately, e.g.::
    
        >>> a = [['foo', 'bar'],
        ...      ['A', 1],
        ...      ['B', 2],
        ...      ['B', 2],
        ...      ['C', 7]]
        >>> b = [['foo', 'bar'],
        ...      ['B', 2]]
        >>> aminusb = etl.complement(a, b)
        >>> aminusb
        +-----+-----+
        | foo | bar |
        +=====+=====+
        | 'A' |   1 |
        +-----+-----+
        | 'B' |   2 |
        +-----+-----+
        | 'C' |   7 |
        +-----+-----+

    This behaviour can be changed with the `strict` keyword argument, e.g.::

        >>> aminusb = etl.complement(a, b, strict=True)
        >>> aminusb
        +-----+-----+
        | foo | bar |
        +=====+=====+
        | 'A' |   1 |
        +-----+-----+
        | 'C' |   7 |
        +-----+-----+

    .. versionchanged:: 1.1.0
    
    If `strict` is `True` then strict set-like behaviour is used, i.e., 
    only rows in `a` not found in `b` are returned.

    	presorted
buffersizetempdircachestrict)ComplementView)abr   r   r   r   r    r   N/var/www/Datamplify/venv/lib/python3.10/site-packages/petl/transform/setops.py
complement   s   
Wr   c                   @   s"   e Zd Z		dddZdd ZdS )	r   FNTc                 C   s@   |r	|| _ || _nt||||d| _ t||||d| _|| _d S N)r   r   r   )r   r   r
   r   )selfr   r   r   r   r   r   r   r   r   r   __init__k   s   
zComplementView.__init__c                 C      t | j| j| jS N)itercomplementr   r   r   r   r   r   r   __iter__w      zComplementView.__iter__FNNTF__name__
__module____qualname__r   r   r   r   r   r   r   i   s
    
r   c           	      c   sV   dd t | D }dd t |D }tt|}t| |V  zt|}W n
 ty0   Y d S w zt|}W n tyL   |V  |D ]}|V  qCY d S w 	 |d u sZt|t|k rn|V  zt|}W nF tym   Y d S w ||krzt|}W n
 ty   Y d S w |szt|}W n ty   d }Y nw nzt|}W n ty   d }Y nw qN)Nc                 s       | ]}t |V  qd S r   tuple.0rowr   r   r   	<genexpr>}       z!itercomplement.<locals>.<genexpr>c                 s   r&   r   r'   r)   r   r   r   r,   ~   r-   )iterr(   r   StopIterationr   )	tatbr   itaitbahdrr   r   r+   r   r   r   r   {   s\   r   c           	      C   sL   t | }t |}t|t|ksJ dt|g|R  }t| |||||dS )a(  
    Find records in `a` that are not in `b`. E.g.::

        >>> import petl as etl
        >>> a = [['foo', 'bar', 'baz'],
        ...      ['A', 1, True],
        ...      ['C', 7, False],
        ...      ['B', 2, False],
        ...      ['C', 9, True]]
        >>> b = [['bar', 'foo', 'baz'],
        ...      [2, 'B', False],
        ...      [9, 'A', False],
        ...      [3, 'B', True],
        ...      [9, 'C', True]]
        >>> aminusb = etl.recordcomplement(a, b)
        >>> aminusb
        +-----+-----+-------+
        | foo | bar | baz   |
        +=====+=====+=======+
        | 'A' |   1 | True  |
        +-----+-----+-------+
        | 'C' |   7 | False |
        +-----+-----+-------+

        >>> bminusa = etl.recordcomplement(b, a)
        >>> bminusa
        +-----+-----+-------+
        | bar | foo | baz   |
        +=====+=====+=======+
        |   3 | 'B' | True  |
        +-----+-----+-------+
        |   9 | 'A' | False |
        +-----+-----+-------+

    Note that both tables must have the same set of fields, but that the order
    of the fields does not matter. See also the
    :func:`petl.transform.setops.complement` function.

    See also the discussion of the `buffersize`, `tempdir` and `cache` arguments
    under the :func:`petl.transform.sorts.sort` function.

    z,both tables must have the same set of fieldsr   r   r   r   )r   setr   r   )	r   r   r   r   r   r   hahbbvr   r   r   recordcomplement   s   /
r:   c           	   	   C   sH   |s
t | } t |}t|| d||||d}t| |d||||d}||fS )a;  
    Find the difference between rows in two tables. Returns a pair of tables.
    E.g.::

        >>> import petl as etl
        >>> a = [['foo', 'bar', 'baz'],
        ...      ['A', 1, True],
        ...      ['C', 7, False],
        ...      ['B', 2, False],
        ...      ['C', 9, True]]
        >>> b = [['x', 'y', 'z'],
        ...      ['B', 2, False],
        ...      ['A', 9, False],
        ...      ['B', 3, True],
        ...      ['C', 9, True]]
        >>> added, subtracted = etl.diff(a, b)
        >>> # rows in b not in a
        ... added
        +-----+---+-------+
        | x   | y | z     |
        +=====+===+=======+
        | 'A' | 9 | False |
        +-----+---+-------+
        | 'B' | 3 | True  |
        +-----+---+-------+

        >>> # rows in a not in b
        ... subtracted
        +-----+-----+-------+
        | foo | bar | baz   |
        +=====+=====+=======+
        | 'A' |   1 | True  |
        +-----+-----+-------+
        | 'C' |   7 | False |
        +-----+-----+-------+

    Convenient shorthand for ``(complement(b, a), complement(a, b))``. See also
    :func:`petl.transform.setops.complement`.

    If `presorted` is True, it is assumed that the data are already sorted by
    the given key, and the `buffersize`, `tempdir` and `cache` arguments are
    ignored. Otherwise, the data are sorted, see also the discussion of the
    `buffersize`, `tempdir` and `cache` arguments under the
    :func:`petl.transform.sorts.sort` function.

    .. versionchanged:: 1.1.0

    If `strict` is `True` then strict set-like behaviour is used.

    Tr   )r
   r   )	r   r   r   r   r   r   r   added
subtractedr   r   r   diff   s   5

r=   c                 C   s0   t || ||||d}t | |||||d}||fS )aF  
    Find the difference between records in two tables. E.g.::

        >>> import petl as etl
        >>> a = [['foo', 'bar', 'baz'],
        ...      ['A', 1, True],
        ...      ['C', 7, False],
        ...      ['B', 2, False],
        ...      ['C', 9, True]]
        >>> b = [['bar', 'foo', 'baz'],
        ...      [2, 'B', False],
        ...      [9, 'A', False],
        ...      [3, 'B', True],
        ...      [9, 'C', True]]
        >>> added, subtracted = etl.recorddiff(a, b)
        >>> added
        +-----+-----+-------+
        | bar | foo | baz   |
        +=====+=====+=======+
        |   3 | 'B' | True  |
        +-----+-----+-------+
        |   9 | 'A' | False |
        +-----+-----+-------+

        >>> subtracted
        +-----+-----+-------+
        | foo | bar | baz   |
        +=====+=====+=======+
        | 'A' |   1 | True  |
        +-----+-----+-------+
        | 'C' |   7 | False |
        +-----+-----+-------+

    Convenient shorthand for
    ``(recordcomplement(b, a), recordcomplement(a, b))``. See also
    :func:`petl.transform.setops.recordcomplement`.

    See also the discussion of the `buffersize`, `tempdir` and `cache`
    arguments under the :func:`petl.transform.sorts.sort` function.

    .. versionchanged:: 1.1.0

    If `strict` is `True` then strict set-like behaviour is used.

    r5   )r:   )r   r   r   r   r   r   r;   r<   r   r   r   
recorddiff%  s   
/
r>   c                 C   s   t | |||||dS )aQ  
    Return rows in `a` that are also in `b`. E.g.::

        >>> import petl as etl
        >>> table1 = [['foo', 'bar', 'baz'],
        ...           ['A', 1, True],
        ...           ['C', 7, False],
        ...           ['B', 2, False],
        ...           ['C', 9, True]]
        >>> table2 = [['x', 'y', 'z'],
        ...           ['B', 2, False],
        ...           ['A', 9, False],
        ...           ['B', 3, True],
        ...           ['C', 9, True]]
        >>> table3 = etl.intersection(table1, table2)
        >>> table3
        +-----+-----+-------+
        | foo | bar | baz   |
        +=====+=====+=======+
        | 'B' |   2 | False |
        +-----+-----+-------+
        | 'C' |   9 | True  |
        +-----+-----+-------+

    If `presorted` is True, it is assumed that the data are already sorted by
    the given key, and the `buffersize`, `tempdir` and `cache` arguments are
    ignored. Otherwise, the data are sorted, see also the discussion of the
    `buffersize`, `tempdir` and `cache` arguments under the
    :func:`petl.transform.sorts.sort` function.

    )r   r   r   r   )IntersectionView)r   r   r   r   r   r   r   r   r   intersection^  s   
"r@   c                   @   s"   e Zd Z		dddZdd ZdS )	r?   FNTc                 C   s<   |r
|| _ || _d S t||||d| _ t||||d| _d S r   )r   r   r
   )r   r   r   r   r   r   r   r   r   r   r     s   
zIntersectionView.__init__c                 C      t | j| jS r   )iterintersectionr   r   r   r   r   r   r        zIntersectionView.__iter__FNNTr"   r   r   r   r   r?     s
    
r?   c                 c   s    t | }t |}t|}t| t|V  z7tt|} tt|}	 t| t|k r3tt|} n| |krG| V  tt|} tt|}ntt|}q$ tyW   Y d S w r   )r.   r   r(   r   r/   )r   r   r2   r3   r4   r   r   r   rB     s*   
	rB   c                 C   s   t | ||dS )a  
    Alternative implementation of :func:`petl.transform.setops.complement`,
    where the complement is executed by constructing an in-memory set for all
    rows found in the right hand table, then iterating over rows from the
    left hand table.

    May be faster and/or more resource efficient where the right table is small
    and the left table is large.
    
    .. versionchanged:: 1.1.0
    
    If `strict` is `True` then strict set-like behaviour is used, i.e., 
    only rows in `a` not found in `b` are returned.

    )r   )HashComplementViewr   r   r   r   r   r   hashcomplement  s   rG   c                   @   s   e Zd ZdddZdd ZdS )rE   Fc                 C   s   || _ || _|| _d S r   rF   )r   r   r   r   r   r   r   r     s   
zHashComplementView.__init__c                 C   r   r   )iterhashcomplementr   r   r   r   r   r   r   r     r    zHashComplementView.__iter__NFr"   r   r   r   r   rE     s    
rE   c           	      c   s|    t | }t|}t|V  t |}t| tdd |D }|D ]}t|}|| dkr8|s7||  d8  < q!|V  q!d S )Nc                 s   r&   r   r'   r)   r   r   r   r,     r-   z%iterhashcomplement.<locals>.<genexpr>r      r.   r   r(   r   )	r   r   r   r2   r4   r3   bcntartr   r   r   rH     s   
rH   c                 C   s
   t | |S )au  
    Alternative implementation of
    :func:`petl.transform.setops.intersection`, where the intersection
    is executed by constructing an in-memory set for all rows found in the
    right hand table, then iterating over rows from the left hand table.

    May be faster and/or more resource efficient where the right table is small
    and the left table is large.

    )HashIntersectionViewr   r   r   r   r   hashintersection  s   
rQ   c                   @   s   e Zd Zdd Zdd ZdS )rO   c                 C   s   || _ || _d S r   rP   )r   r   r   r   r   r   r     s   
zHashIntersectionView.__init__c                 C   rA   r   )iterhashintersectionr   r   r   r   r   r   r     rC   zHashIntersectionView.__iter__Nr"   r   r   r   r   rO     s    rO   c                 c   sv    t | }t|}t|V  t |}t| tdd |D }|D ]}t|}|| dkr8|V  ||  d8  < q!d S )Nc                 s   r&   r   r'   r)   r   r   r   r,     r-   z'iterhashintersection.<locals>.<genexpr>r   rJ   rK   )r   r   r2   r4   r3   rL   rM   rN   r   r   r   rR     s   
rR   r!   )NNTFrD   rI   ) 
__future__r   r   r   collectionsr   petl.compatr   petl.comparisonr   petl.util.baser   r	   petl.transform.sortsr
   petl.transform.basicsr   r   r   r   r:   r=   r>   r@   r?   rB   rG   rE   rH   rQ   rO   rR   r   r   r   r   <module>   sJ    
[-
8
?
6
&

