-
Notifications
You must be signed in to change notification settings - Fork 0
/
measure.py
112 lines (79 loc) · 2.93 KB
/
measure.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
from __future__ import absolute_import
__author__ = "John Kirkham <kirkhamj@janelia.hhmi.org>"
__date__ = "$Dec 08, 2016 14:49:29 GMT-0500$"
import numbers
import math
import kenjutsu.format
class UnknownSliceLengthException(Exception):
"""
Raised if a slice does not have a known length.
"""
pass
def len_slice(a_slice, a_length=None):
"""
Determines how many elements a slice will contain.
Raises:
UnknownSliceLengthException: Will raise an exception if
a_slice.stop and a_length is None.
Args:
a_slice(slice): a slice to reformat.
a_length(int): a length to fill for stopping if not
provided.
Returns:
(slice): a new slice with as many values filled in as
possible.
Examples:
>>> len_slice(slice(2, None), 10)
8
>>> len_slice(slice(2, 6))
4
"""
if isinstance(a_slice, numbers.Integral):
raise TypeError(
"An integral index does not provide an object with a length."
)
new_slice = kenjutsu.format.reformat_slice(a_slice, a_length)
new_slice_size = 0
if isinstance(new_slice, slice):
if new_slice.stop is None:
if new_slice.step > 0:
raise UnknownSliceLengthException(
"Cannot determine slice length without a defined end"
" point. The reformatted slice was %s." % repr(new_slice)
)
else:
new_slice = slice(new_slice.start, -1, new_slice.step)
new_slice_diff = float(new_slice.stop - new_slice.start)
new_slice_size = int(math.ceil(new_slice_diff / new_slice.step))
else:
new_slice_size = len(new_slice)
return(new_slice_size)
def len_slices(slices, lengths=None):
"""
Takes a tuple of slices and reformats them to fill in as many undefined
values as possible.
Args:
slices(tuple(slice)): a tuple of slices to reformat.
lengths(tuple(int)): a tuple of lengths to fill.
Returns:
(slice): a tuple of slices with all default
values filled if possible.
Examples:
>>> len_slices(
... (
... slice(None),
... slice(3, None),
... slice(None, 5),
... slice(None, None, 2)
... ),
... (10, 13, 15, 20)
... )
(10, 10, 5, 10)
"""
new_slices = kenjutsu.format.reformat_slices(slices, lengths)
lens = []
for each_slice in new_slices:
if not isinstance(each_slice, numbers.Integral):
lens.append(len_slice(each_slice))
lens = tuple(lens)
return(lens)