Coverage for src/hdmf/array.py: 50%
137 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-10-04 02:57 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-10-04 02:57 +0000
1from abc import abstractmethod, ABCMeta
3import numpy as np
6class Array:
8 def __init__(self, data):
9 self.__data = data
10 if hasattr(data, 'dtype'): 10 ↛ 13line 10 didn't jump to line 13, because the condition on line 10 was never false
11 self.dtype = data.dtype
12 else:
13 tmp = data
14 while isinstance(tmp, (list, tuple)):
15 tmp = tmp[0]
16 self.dtype = type(tmp)
18 @property
19 def data(self):
20 return self.__data
22 def __len__(self):
23 return len(self.__data)
25 def get_data(self):
26 return self.__data
28 def __getidx__(self, arg):
29 return self.__data[arg]
31 def __sliceiter(self, arg):
32 return (x for x in range(*arg.indices(len(self))))
34 def __getitem__(self, arg):
35 if isinstance(arg, list): 35 ↛ 36line 35 didn't jump to line 36, because the condition on line 35 was never true
36 idx = list()
37 for i in arg:
38 if isinstance(i, slice):
39 idx.extend(x for x in self.__sliceiter(i))
40 else:
41 idx.append(i)
42 return np.fromiter((self.__getidx__(x) for x in idx), dtype=self.dtype)
43 elif isinstance(arg, slice):
44 return np.fromiter((self.__getidx__(x) for x in self.__sliceiter(arg)), dtype=self.dtype)
45 elif isinstance(arg, tuple): 45 ↛ 46line 45 didn't jump to line 46, because the condition on line 45 was never true
46 return (self.__getidx__(arg[0]), self.__getidx__(arg[1]))
47 else:
48 return self.__getidx__(arg)
51class AbstractSortedArray(Array, metaclass=ABCMeta):
52 '''
53 An abstract class for representing sorted array
54 '''
56 @abstractmethod
57 def find_point(self, val):
58 pass
60 def get_data(self):
61 return self
63 def __lower(self, other):
64 ins = self.find_point(other)
65 return ins
67 def __upper(self, other):
68 ins = self.__lower(other)
69 while self[ins] == other:
70 ins += 1
71 return ins
73 def __lt__(self, other):
74 ins = self.__lower(other)
75 return slice(0, ins)
77 def __le__(self, other):
78 ins = self.__upper(other)
79 return slice(0, ins)
81 def __gt__(self, other):
82 ins = self.__upper(other)
83 return slice(ins, len(self))
85 def __ge__(self, other):
86 ins = self.__lower(other)
87 return slice(ins, len(self))
89 @staticmethod
90 def __sort(a):
91 if isinstance(a, tuple):
92 return a[0]
93 else:
94 return a
96 def __eq__(self, other):
97 if isinstance(other, list): 97 ↛ 98line 97 didn't jump to line 98, because the condition on line 97 was never true
98 ret = list()
99 for i in other:
100 eq = self == i
101 ret.append(eq)
102 ret = sorted(ret, key=self.__sort)
103 tmp = list()
104 for i in range(1, len(ret)):
105 a, b = ret[i - 1], ret[i]
106 if isinstance(a, tuple):
107 if isinstance(b, tuple):
108 if a[1] >= b[0]:
109 b[0] = a[0]
110 else:
111 tmp.append(slice(*a))
112 else:
113 if b > a[1]:
114 tmp.append(slice(*a))
115 elif b == a[1]:
116 a[1] == b + 1
117 else:
118 ret[i] = a
119 else:
120 if isinstance(b, tuple):
121 if a < b[0]:
122 tmp.append(a)
123 else:
124 if b - a == 1:
125 ret[i] = (a, b)
126 else:
127 tmp.append(a)
128 if isinstance(ret[-1], tuple):
129 tmp.append(slice(*ret[-1]))
130 else:
131 tmp.append(ret[-1])
132 ret = tmp
133 return ret
134 elif isinstance(other, tuple): 134 ↛ 135line 134 didn't jump to line 135, because the condition on line 134 was never true
135 ge = self >= other[0]
136 ge = ge.start
137 lt = self < other[1]
138 lt = lt.stop
139 if ge == lt:
140 return ge
141 else:
142 return slice(ge, lt)
143 else:
144 lower = self.__lower(other)
145 upper = self.__upper(other)
146 d = upper - lower
147 if d == 1: 147 ↛ 149line 147 didn't jump to line 149, because the condition on line 147 was never false
148 return lower
149 elif d == 0:
150 return None
151 else:
152 return slice(lower, upper)
154 def __ne__(self, other):
155 eq = self == other
156 if isinstance(eq, tuple): 156 ↛ 157line 156 didn't jump to line 157, because the condition on line 156 was never true
157 return [slice(0, eq[0]), slice(eq[1], len(self))]
158 else:
159 return [slice(0, eq), slice(eq + 1, len(self))]
162class SortedArray(AbstractSortedArray):
163 '''
164 A class for wrapping sorted arrays. This class overrides
165 <,>,<=,>=,==, and != to leverage the sorted content for
166 efficiency.
167 '''
169 def __init__(self, array):
170 super().__init__(array)
172 def find_point(self, val):
173 return np.searchsorted(self.data, val)
176class LinSpace(SortedArray):
178 def __init__(self, start, stop, step):
179 self.start = start
180 self.stop = stop
181 self.step = step
182 self.dtype = float if any(isinstance(s, float) for s in (start, stop, step)) else int
183 self.__len = int((stop - start) / step)
185 def __len__(self):
186 return self.__len
188 def find_point(self, val):
189 nsteps = (val - self.start) / self.step
190 fl = int(nsteps)
191 if fl == nsteps: 191 ↛ 194line 191 didn't jump to line 194, because the condition on line 191 was never false
192 return int(fl)
193 else:
194 return int(fl + 1)
196 def __getidx__(self, arg):
197 return self.start + self.step * arg