Completed
Push — develop ( 6efd8f...bea917 )
by Kale
01:18
created

frozendict   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 10
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 10
c 0
b 0
f 0
wmc 4

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __hash__() 0 2 1
A __key() 0 2 2
A __eq__() 0 2 1
1
# -*- coding: utf-8 -*-
2
"""Common collection classes."""
3
from __future__ import print_function, division, absolute_import
4
from functools import reduce
5
6
from .compat import text_type
7
8
9
# http://stackoverflow.com/a/14620633/2127762
10
class AttrDict(dict):
11
    """Sub-classes dict, and further allows attribute-like access to dictionary items.
12
13
    Examples:
14
        >>> d = AttrDict({'a': 1})
15
        >>> d.a, d['a'], d.get('a')
16
        (1, 1, 1)
17
        >>> d.b = 2
18
        >>> d.b, d['b']
19
        (2, 2)
20
    """
21
    def __init__(self, *args, **kwargs):
22
        super(AttrDict, self).__init__(*args, **kwargs)
23
        self.__dict__ = self
24
25
26
class frozendict(dict):
27
28
  def __key(self):
29
    return tuple((k,self[k]) for k in sorted(self))
30
31
  def __hash__(self):
32
    return hash(self.__key())
33
34
  def __eq__(self, other):
35
    return self.__key() == other.__key()
36
37
def first(seq, key=lambda x: bool(x), default=None, apply=lambda x: x):
38
    """Give the first value that satisfies the key test.
39
40
    Args:
41
        seq (iterable):
42
        key (callable): test for each element of iterable
43
        default: returned when all elements fail test
44
        apply (callable): applied to element before return
45
46
    Returns: first element in seq that passes key, mutated with optional apply
47
48
    Examples:
49
        >>> first([0, False, None, [], (), 42])
50
        42
51
        >>> first([0, False, None, [], ()]) is None
52
        True
53
        >>> first([0, False, None, [], ()], default='ohai')
54
        'ohai'
55
        >>> import re
56
        >>> m = first(re.match(regex, 'abc') for regex in ['b.*', 'a(.*)'])
57
        >>> m.group(1)
58
        'bc'
59
60
        The optional `key` argument specifies a one-argument predicate function
61
        like that used for `filter()`.  The `key` argument, if supplied, must be
62
        in keyword form.  For example:
63
        >>> first([1, 1, 3, 4, 5], key=lambda x: x % 2 == 0)
64
        4
65
66
    """
67
    return next((apply(x) for x in seq if key(x)), default)
68
69
70
def firstitem(map, key=lambda k, v: bool(k), default=None, apply=lambda k, v: (k, v)):
71
    return next((apply(k, v) for k, v in map if key(k, v)), default)
72
73
74
def last(seq, key=lambda x: bool(x), default=None, apply=lambda x: x):
75
    return next((apply(x) for x in reversed(seq) if key(x)), default)
76
77
78
def call_each(seq):
79
    """Calls each element of sequence to invoke the side effect.
80
81
    Args:
82
        seq:
83
84
    Returns: None
85
86
    """
87
    try:
88
        reduce(lambda _, y: y(), seq)
89
    except TypeError as e:
90
        if text_type(e) != "reduce() of empty sequence with no initial value":
91
            raise
92