o
    ZhG)                     @   s   d dl Z d dlZd dlmZ d dlmZ g dZdd Zdd Zd	d
 Z	e
fddZe
fddZe
fddZe
fddZe
fddZe
fddZe
fddZdd Ze
fddZde
fddZd(d d!Zd"d# Zd$d% Zd&d' ZdS ))    N)Mapping)reduce)merge
merge_withvalmapkeymapitemmap	valfilter	keyfilter
itemfilterassocdissocassoc_in	update_inget_inc                 C   s2   | dt}|rt| j d| d  d|S )Nfactoryz'() got an unexpected keyword argument 'r   ')popdict	TypeError__name__popitem)fkwargsr    r   b/var/www/auris/lib/python3.10/site-packages/torch/fx/experimental/unification/unification_tools.py_get_factory   s   r   c                  O   sJ   t | dkrt| d ts| d } tt|}| }| D ]}|| q|S )zMerge a collection of dictionaries

    >>> merge({1: "one"}, {2: "two"})
    {1: 'one', 2: 'two'}

    Later dictionaries have precedence

    >>> merge({1: 2, 3: 4}, {3: 3, 4: 4})
    {1: 2, 3: 3, 4: 4}

    See Also:
        merge_with
       r   )len
isinstancer   r   r   update)dictsr   r   rvdr   r   r   r   "   s   
r   c                 O   s|   t |dkrt|d ts|d }tt|}| }|D ]}| D ]\}}||vr/|g||< q!|| | q!qt| ||S )a  Merge dictionaries and apply function to combined values

    A key may occur in more than one dict, and all values mapped from the key
    will be passed to the function as a list, such as func([val1, val2, ...]).

    >>> merge_with(sum, {1: 1, 2: 2}, {1: 10, 2: 20})
    {1: 11, 2: 22}

    >>> merge_with(first, {1: 1, 2: 2}, {2: 20, 3: 30})  # doctest: +SKIP
    {1: 1, 2: 2, 3: 30}

    See Also:
        merge
    r   r   )r   r   r   r   r   itemsappendr   )funcr!   r   r   resultr#   kvr   r   r   r   :   s   
r   c                 C   s(   | }| t| t| |  |S )zApply function to values of dictionary

    >>> bills = {"Alice": [20, 15, 30], "Bob": [10, 35]}
    >>> valmap(sum, bills)  # doctest: +SKIP
    {'Alice': 65, 'Bob': 45}

    See Also:
        keymap
        itemmap
    )r    zipkeysmapvaluesr&   r#   r   r"   r   r   r   r   W      r   c                 C   s(   | }| tt| | |  |S )zApply function to keys of dictionary

    >>> bills = {"Alice": [20, 15, 30], "Bob": [10, 35]}
    >>> keymap(str.lower, bills)  # doctest: +SKIP
    {'alice': [20, 15, 30], 'bob': [10, 35]}

    See Also:
        valmap
        itemmap
    )r    r*   r,   r+   r-   r.   r   r   r   r   g   r/   r   c                 C   s   | }| t| |  |S )zApply function to items of dictionary

    >>> accountids = {"Alice": 10, "Bob": 20}
    >>> itemmap(reversed, accountids)  # doctest: +SKIP
    {10: "Alice", 20: "Bob"}

    See Also:
        keymap
        valmap
    )r    r,   r$   r.   r   r   r   r   w   s   r   c                 C   s,   | }|  D ]\}}| |r|||< q|S )zFilter items in dictionary by value

    >>> iseven = lambda x: x % 2 == 0
    >>> d = {1: 2, 2: 3, 3: 4, 4: 5}
    >>> valfilter(iseven, d)
    {1: 2, 3: 4}

    See Also:
        keyfilter
        itemfilter
        valmap
    r$   	predicater#   r   r"   r(   r)   r   r   r   r	         r	   c                 C   s,   | }|  D ]\}}| |r|||< q|S )zFilter items in dictionary by key

    >>> iseven = lambda x: x % 2 == 0
    >>> d = {1: 2, 2: 3, 3: 4, 4: 5}
    >>> keyfilter(iseven, d)
    {2: 3, 4: 5}

    See Also:
        valfilter
        itemfilter
        keymap
    r0   r1   r   r   r   r
      r3   r
   c                 C   s0   | }|  D ]}| |r|\}}|||< q|S )a  Filter items in dictionary by item

    >>> def isvalid(item):
    ...     k, v = item
    ...     return k % 2 == 0 and v < 4

    >>> d = {1: 2, 2: 3, 3: 4, 4: 5}
    >>> itemfilter(isvalid, d)
    {2: 3}

    See Also:
        keyfilter
        valfilter
        itemmap
    r0   )r2   r#   r   r"   itemr(   r)   r   r   r   r      s   r   c                 C   s   | }| |  |||< |S )zReturn a new dict with new key value pair

    New dict has d[key] set to value. Does not modify the initial dictionary.

    >>> assoc({"x": 1}, "x", 2)
    {'x': 2}
    >>> assoc({"x": 1}, "y", 3)  # doctest: +SKIP
    {'x': 1, 'y': 3}
    )r    )r#   keyvaluer   d2r   r   r   r      s   

r   c                 O   sv   t t|}| }t|t| d k r%||  |D ]	}||v r"||= q|S t| }|| |D ]}| | ||< q0|S )aB  Return a new dict with the given key(s) removed.

    New dict has d[key] deleted for each supplied key.
    Does not modify the initial dictionary.

    >>> dissoc({"x": 1, "y": 2}, "y")
    {'x': 1}
    >>> dissoc({"x": 1, "y": 2}, "y", "x")
    {}
    >>> dissoc({"x": 1}, "y")  # Ignores missing keys
    {'x': 1}
    g333333?)r   r   r   r    setdifference_update)r#   r+   r   r   r7   r5   	remainingr(   r   r   r   r      s   


r   c                    s   t | | fdd |S )a  Return a new dict with new, potentially nested, key value pair

    >>> purchase = {
    ...     "name": "Alice",
    ...     "order": {"items": ["Apple", "Orange"], "costs": [0.50, 1.25]},
    ...     "credit card": "5555-1234-1234-1234",
    ... }
    >>> assoc_in(purchase, ["order", "costs"], [0.25, 1.00])  # doctest: +SKIP
    {'credit card': '5555-1234-1234-1234',
     'name': 'Alice',
     'order': {'costs': [0.25, 1.00], 'items': ['Apple', 'Orange']}}
    c                    s    S Nr   xr6   r   r   <lambda>      zassoc_in.<locals>.<lambda>)r   )r#   r+   r6   r   r   r>   r   r      s   r   c                 C   s   t |}t|}|  }}||  |D ] }	|| v r'| | } | }
|
|  n|  } }
|
 ||< }|	}q|| v rC|| | ||< |S ||||< |S )a  Update value in a (potentially) nested dictionary

    inputs:
    d - dictionary on which to operate
    keys - list or tuple giving the location of the value to be changed in d
    func - function to operate on that value

    If keys == [k0,..,kX] and d[k0]..[kX] == v, update_in returns a copy of the
    original dictionary with v replaced by func(v), but does not mutate the
    original dictionary.

    If k0 is not a key in d, update_in creates nested dictionaries to the depth
    specified by the keys, with the innermost value set to func(default).

    >>> inc = lambda x: x + 1
    >>> update_in({"a": 0}, ["a"], inc)
    {'a': 1}

    >>> transaction = {
    ...     "name": "Alice",
    ...     "purchase": {"items": ["Apple", "Orange"], "costs": [0.50, 1.25]},
    ...     "credit card": "5555-1234-1234-1234",
    ... }
    >>> update_in(transaction, ["purchase", "costs"], sum)  # doctest: +SKIP
    {'credit card': '5555-1234-1234-1234',
     'name': 'Alice',
     'purchase': {'costs': 1.75, 'items': ['Apple', 'Orange']}}

    >>> # updating a value when k0 is not in d
    >>> update_in({}, [1, 2, 3], str, default="bar")
    {1: {2: {3: 'bar'}}}
    >>> update_in({1: "foo"}, [2, 3, 4], inc, 0)
    {1: 'foo', 2: {3: {4: 1}}}
    )iternextr    )r#   r+   r&   defaultr   ksr(   r"   innerr5   Zdtempr   r   r   r     s"   #


r   Fc              
   C   s4   zt tj| |W S  tttfy   |r | Y S w )a  Returns coll[i0][i1]...[iX] where [i0, i1, ..., iX]==keys.

    If coll[i0][i1]...[iX] cannot be found, returns ``default``, unless
    ``no_default`` is specified, then it raises KeyError or IndexError.

    ``get_in`` is a generalization of ``operator.getitem`` for nested data
    structures such as dictionaries and lists.

    >>> transaction = {
    ...     "name": "Alice",
    ...     "purchase": {"items": ["Apple", "Orange"], "costs": [0.50, 1.25]},
    ...     "credit card": "5555-1234-1234-1234",
    ... }
    >>> get_in(["purchase", "items", 0], transaction)
    'Apple'
    >>> get_in(["name"], transaction)
    'Alice'
    >>> get_in(["purchase", "total"], transaction)
    >>> get_in(["purchase", "items", "apple"], transaction)
    >>> get_in(["purchase", "items", 10], transaction)
    >>> get_in(["purchase", "total"], transaction, 0)
    0
    >>> get_in(["y"], {}, no_default=True)
    Traceback (most recent call last):
        ...
    KeyError: 'y'

    See Also:
        itertoolz.get
        operator.getitem
    )r   operatorgetitemKeyError
IndexErrorr   )r+   ZcollrC   Z
no_defaultr   r   r   r   ?  s    r   c                    sJ   t  tr t dkr d   fddS  rtj  S dd S t S )Nr   r   c                    s
   |   fS r;   r   r<   indexr   r   r?   k  s   
 zgetter.<locals>.<lambda>c                 S   s   dS )Nr   r   r<   r   r   r   r?   o  r@   )r   listr   rF   
itemgetterrJ   r   rJ   r   getterg  s   


rN   c                 C   s\   t | st| } tdd }|D ]
}|| | | qi }| D ]	\}}|j||< q"|S )a  Group a collection by a key function

    >>> names = ["Alice", "Bob", "Charlie", "Dan", "Edith", "Frank"]
    >>> groupby(len, names)  # doctest: +SKIP
    {3: ['Bob', 'Dan'], 5: ['Alice', 'Edith', 'Frank'], 7: ['Charlie']}

    >>> iseven = lambda x: x % 2 == 0
    >>> groupby(iseven, [1, 2, 3, 4, 5, 6, 7, 8])  # doctest: +SKIP
    {False: [1, 3, 5, 7], True: [2, 4, 6, 8]}

    Non-callable keys imply grouping on a member.

    >>> groupby(
    ...     "gender",
    ...     [
    ...         {"name": "Alice", "gender": "F"},
    ...         {"name": "Bob", "gender": "M"},
    ...         {"name": "Charlie", "gender": "M"},
    ...     ],
    ... )  # doctest:+SKIP
    {'F': [{'gender': 'F', 'name': 'Alice'}],
     'M': [{'gender': 'M', 'name': 'Bob'},
           {'gender': 'M', 'name': 'Charlie'}]}

    Not to be confused with ``itertools.groupby``

    See Also:
        countby
    c                   S   s   g j S r;   )r%   r   r   r   r   r?     s    zgroupby.<locals>.<lambda>)callablerN   collectionsdefaultdictr$   __self__)r5   seqr#   r4   r"   r(   r)   r   r   r   groupbyt  s   rT   c                 C   s   t t| S )zBThe first element in a sequence

    >>> first("ABC")
    'A'
    )rB   rA   )rS   r   r   r   first  s   rU   )NF)rP   rF   collections.abcr   	functoolsr   __all__r   r   r   r   r   r   r   r	   r
   r   r   r   r   r   r   rN   rT   rU   r   r   r   r   <module>   s,   	
;()