-
Notifications
You must be signed in to change notification settings - Fork 1
/
utils.py
132 lines (107 loc) · 2.88 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
from collections.abc import Iterable, Iterator, Sequence
import itertools as it
import operator
from typing import Any, TypeVar, overload
_T = TypeVar("_T")
@overload
def ceildiv(a: int, b: int) -> int: ...
@overload
def ceildiv(a: float, b: float) -> float: ...
def ceildiv(a, b):
"""
Return the ceiling of `a / b`.
Parameters
----------
a : int or float
Dividend.
b : int or float
Divisor.
Returns
-------
int or float
The ceiling of the quotient of `a` and `b`.
"""
return -(a // -b)
def distribute(
sequence: Sequence[_T],
start: float = 0,
stop: float = 1,
) -> Iterator[tuple[float, _T]]:
"""
Enumerate the sequence evenly over the interval (`start`, `stop`).
Based on https://stackoverflow.com/a/59594546 .
Parameters
----------
sequence : array-like
Sequence to enumerate.
start : float, default 0
Start of interval (exclusive).
stop : float, default 1
End of interval (exclusive).
Yields
------
position : float
Position of sequence item in interval.
item
Sequence item.
Examples
--------
>>> list(distribute("abc"))
[(0.25, 'a'), (0.5, 'b'), (0.75, 'c')]
>>> list(distribute("abc", 1, 4))
[(1.75, 'a'), (2.5, 'b'), (3.25, 'c')]
"""
m = len(sequence) + 1
for i, v in enumerate(sequence, 1):
yield start + (stop - start) * i / m, v
def intersperse(*sequences: Sequence[_T]) -> Iterator[_T]:
"""
Evenly intersperse the sequences.
Based on https://stackoverflow.com/a/59594546 .
Parameters
----------
*sequences
Sequences to intersperse.
Yields
------
item
Sequence item.
Examples
--------
>>> list(intersperse(range(10), "abc"))
[0, 1, 'a', 2, 3, 4, 'b', 5, 6, 7, 'c', 8, 9]
>>> list(intersperse("XY", range(10), "abc"))
[0, 1, 'a', 2, 'X', 3, 4, 'b', 5, 6, 'Y', 7, 'c', 8, 9]
>>> "".join(intersperse("hlwl", "eood", "l r!"))
'hello world!'
"""
distributions = map(distribute, sequences)
for _, v in sorted(it.chain(*distributions), key=operator.itemgetter(0)):
yield v
def pad(
iterable: Iterable[_T],
size: int,
padvalue: Any = None,
) -> Iterable[_T]:
"""
Pad an iterable to a specified size.
If the iterable is longer than the specified size, it is truncated.
If it is shorter, `padvalue` is appended until the specified size is
reached.
Parameters
----------
iterable : iterable
Iterable to pad.
size : int
Size to pad iterable to.
padvalue : any, default None
Value to pad iterable with.
Returns
-------
iterable
Padded iterable.
"""
return it.islice(it.chain(iterable, it.repeat(padvalue)), size)
__all__ = [
"ceildiv", "distribute", "intersperse", "pad",
]