Completed
Push — develop ( 06a9d5...28049f )
by Kale
01:02
created

call_each()   A

Complexity

Conditions 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
c 1
b 0
f 0
dl 0
loc 10
rs 9.4285
1
# -*- coding: utf-8 -*-
2
"""Common collection classes."""
3
from __future__ import print_function, division, absolute_import
4
from functools import reduce
5
6
7
# http://stackoverflow.com/a/14620633/2127762
8
class AttrDict(dict):
9
    """Sub-classes dict, and further allows attribute-like access to dictionary items.
10
11
    Examples:
12
        >>> d = AttrDict({'a': 1})
13
        >>> d.a, d['a'], d.get('a')
14
        (1, 1, 1)
15
        >>> d.b = 2
16
        >>> d.b, d['b']
17
        (2, 2)
18
    """
19
    def __init__(self, *args, **kwargs):
20
        super(AttrDict, self).__init__(*args, **kwargs)
21
        self.__dict__ = self
22
23
24
def first(seq, key=lambda x: bool(x), default=None, apply=lambda x: x):
25
    """Give the first value that satisfies the key test.
26
27
    Args:
28
        seq (iterable):
29
        key (callable): test for each element of iterable
30
        default: returned when all elements fail test
31
        apply (callable): applied to element before return
32
33
    Returns: first element in seq that passes key, mutated with optional apply
34
35
    Examples:
36
        >>> first([0, False, None, [], (), 42])
37
        42
38
        >>> first([0, False, None, [], ()]) is None
39
        True
40
        >>> first([0, False, None, [], ()], default='ohai')
41
        'ohai'
42
        >>> import re
43
        >>> m = first(re.match(regex, 'abc') for regex in ['b.*', 'a(.*)'])
44
        >>> m.group(1)
45
        'bc'
46
47
        The optional `key` argument specifies a one-argument predicate function
48
        like that used for `filter()`.  The `key` argument, if supplied, must be
49
        in keyword form.  For example:
50
        >>> first([1, 1, 3, 4, 5], key=lambda x: x % 2 == 0)
51
        4
52
53
    """
54
    return next((apply(x) for x in seq if key(x)), default)
55
56
57
def last(seq, key=lambda x: bool(x), default=None, apply=lambda x: x):
58
    return next((apply(x) for x in reversed(seq) if key(x)), default)
59
60
61
def call_each(seq):
62
    """Calls each element of sequence to invoke the side effect.
63
64
    Args:
65
        seq:
66
67
    Returns: None
68
69
    """
70
    reduce(lambda _, y: y(), seq)
71