potluck.mast_utils

Utils from codder which are necessary for the mast module.

mast_utils.py

 1"""
 2Utils from codder which are necessary for the mast module.
 3
 4mast_utils.py
 5"""
 6
 7# Attempts at 2/3 dual compatibility:
 8from __future__ import print_function
 9
10try: # Python 3
11    from collections.abc import Iterable
12except Exception: # Python 2
13    from collections import Iterable
14
15
16class Some(object):
17    """
18    An ML-inspired option for Python.  Pair with None.
19    """
20    def __init__(self, value):
21        self.value = value
22
23    def get(self):
24        return self.value
25
26    def dump(self, dumper):
27        return 'Some({})'.format(dumper(self.value))
28
29    def __repr__(self):
30        return 'Some({})'.format(self.value)
31
32
33# pure dictionary ops
34
35def dict_bind(d, binding):
36    """Return a copy of d with binding added."""
37    di = d.copy()
38    key, val = binding
39    di[key] = val
40    return di
41
42
43def dict_unbind(d, remove_key):
44    """Return a copy of d with remove_key unbound."""
45    di = d.copy()
46    del di[remove_key]
47    return di
48    # return {k: v for k, v in d.items() if k != remove_key}
49
50
51# generator/iterator convenience functions
52
53def takeone(it):
54    """Return Some(first value yielded by gen) or None if no values yielded."""
55    for x in it:
56        assert x is not None
57        return Some(x)
58    return None
59
60
61def iterone(elem):
62    """Produce an iterator over a single element with printable contents"""
63    # return iter([elem])
64    return FiniteIterator([elem])
65
66
67def iterempty():
68    """Produce an empty iterator with printable contents"""
69    # return iter([])
70    return FiniteIterator([])
71
72
73class FiniteIterator(Iterable):
74    '''An iterator with a finite number of elements left to iterate.'''
75
76    def __init__(self, elts):
77        self.elts = elts
78        self.nextIndex = 0
79
80    def __iter__(self):
81        return self
82
83    def __next__(self):
84        if self.nextIndex >= len(self.elts):
85            raise StopIteration
86        else:
87            self.nextIndex += 1
88            return self.elts[self.nextIndex - 1]
89
90    def __len__(self):
91        return len(self.elts - (self.nextIndex + 1))
92
93    def dump(self, dumper):
94        return '<FiniteIterator({})>'.format(
95            ','.join(dumper(elt) for elt in self.elts))
96
97    def __repr__(self):
98        return '<FiniteIterator({})>'.format(
99            ','.join(str(elt) for elt in self.elts))
class Some:
17class Some(object):
18    """
19    An ML-inspired option for Python.  Pair with None.
20    """
21    def __init__(self, value):
22        self.value = value
23
24    def get(self):
25        return self.value
26
27    def dump(self, dumper):
28        return 'Some({})'.format(dumper(self.value))
29
30    def __repr__(self):
31        return 'Some({})'.format(self.value)

An ML-inspired option for Python. Pair with None.

Some(value)
21    def __init__(self, value):
22        self.value = value
def get(self):
24    def get(self):
25        return self.value
def dump(self, dumper):
27    def dump(self, dumper):
28        return 'Some({})'.format(dumper(self.value))
def dict_bind(d, binding):
36def dict_bind(d, binding):
37    """Return a copy of d with binding added."""
38    di = d.copy()
39    key, val = binding
40    di[key] = val
41    return di

Return a copy of d with binding added.

def dict_unbind(d, remove_key):
44def dict_unbind(d, remove_key):
45    """Return a copy of d with remove_key unbound."""
46    di = d.copy()
47    del di[remove_key]
48    return di
49    # return {k: v for k, v in d.items() if k != remove_key}

Return a copy of d with remove_key unbound.

def takeone(it):
54def takeone(it):
55    """Return Some(first value yielded by gen) or None if no values yielded."""
56    for x in it:
57        assert x is not None
58        return Some(x)
59    return None

Return Some(first value yielded by gen) or None if no values yielded.

def iterone(elem):
62def iterone(elem):
63    """Produce an iterator over a single element with printable contents"""
64    # return iter([elem])
65    return FiniteIterator([elem])

Produce an iterator over a single element with printable contents

def iterempty():
68def iterempty():
69    """Produce an empty iterator with printable contents"""
70    # return iter([])
71    return FiniteIterator([])

Produce an empty iterator with printable contents

class FiniteIterator(collections.abc.Iterable):
 74class FiniteIterator(Iterable):
 75    '''An iterator with a finite number of elements left to iterate.'''
 76
 77    def __init__(self, elts):
 78        self.elts = elts
 79        self.nextIndex = 0
 80
 81    def __iter__(self):
 82        return self
 83
 84    def __next__(self):
 85        if self.nextIndex >= len(self.elts):
 86            raise StopIteration
 87        else:
 88            self.nextIndex += 1
 89            return self.elts[self.nextIndex - 1]
 90
 91    def __len__(self):
 92        return len(self.elts - (self.nextIndex + 1))
 93
 94    def dump(self, dumper):
 95        return '<FiniteIterator({})>'.format(
 96            ','.join(dumper(elt) for elt in self.elts))
 97
 98    def __repr__(self):
 99        return '<FiniteIterator({})>'.format(
100            ','.join(str(elt) for elt in self.elts))

An iterator with a finite number of elements left to iterate.

FiniteIterator(elts)
77    def __init__(self, elts):
78        self.elts = elts
79        self.nextIndex = 0
def dump(self, dumper):
94    def dump(self, dumper):
95        return '<FiniteIterator({})>'.format(
96            ','.join(dumper(elt) for elt in self.elts))