Mercurial > templog
comparison py/utils.py @ 569:d7575050e4be
StepIntegrator
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Wed, 11 Nov 2015 00:07:21 +0800 |
parents | 59cb8449ef97 |
children | 11cebd6f0bfb |
comparison
equal
deleted
inserted
replaced
568:8eb16d97ed2b | 569:d7575050e4be |
---|---|
169 """ | 169 """ |
170 if self(): | 170 if self(): |
171 L(msg + " (log interval %s)" % str(self.limit)) | 171 L(msg + " (log interval %s)" % str(self.limit)) |
172 else: | 172 else: |
173 D(msg) | 173 D(msg) |
174 | |
175 class StepIntegrator(object): | |
176 """ | |
177 >>> s = StepIntegrator(lambda: t, 40) | |
178 >>> t = 1 | |
179 >>> s.turn(1) | |
180 >>> t = 10 | |
181 >>> s.turn(0) | |
182 >>> t = 20 | |
183 >>> s.turn(1) | |
184 >>> t = 30 | |
185 >>> print(s.integrate()) | |
186 19 | |
187 >>> s.turn(0) | |
188 >>> print(s.integrate()) | |
189 19 | |
190 >>> t = 35 | |
191 >>> print(s.integrate()) | |
192 19 | |
193 >>> t = 42 | |
194 >>> print(s.integrate()) | |
195 18 | |
196 >>> t = 52 | |
197 >>> print(s.integrate()) | |
198 10 | |
199 >>> t = 69 | |
200 >>> print(s.integrate()) | |
201 1 | |
202 >>> t = 70 | |
203 >>> print(s.integrate()) | |
204 0 | |
205 >>> t = 170 | |
206 >>> print(s.integrate()) | |
207 0 | |
208 """ | |
209 def __init__(self, timefn, limittime): | |
210 # _on_periods is a list of [[start, end]]. End is None if still on | |
211 self._on_periods = [] | |
212 self._timefn = timefn | |
213 self._limittime = limittime | |
214 | |
215 def turn(self, value): | |
216 if not self._on_periods: | |
217 if value: | |
218 self._on_periods.append([self._timefn(), None]) | |
219 return | |
220 | |
221 # state hasn't changed | |
222 on_now = (self._on_periods[-1][1] is None) | |
223 if value == on_now: | |
224 return | |
225 | |
226 if value: | |
227 self._on_periods.append([self._timefn(), None]) | |
228 else: | |
229 self._on_periods[-1][1] = self._timefn() | |
230 | |
231 def _trim(self): | |
232 begin = self._timefn() - self._limittime | |
233 # shortcut, first start is after begin | |
234 if not self._on_periods or self._on_periods[0][0] >= begin: | |
235 return | |
236 | |
237 new_periods = [] | |
238 for s, e in self._on_periods: | |
239 if s == e: | |
240 continue | |
241 elif s >= begin: | |
242 new_periods.append([s,e]) | |
243 elif e is not None and e < begin: | |
244 continue | |
245 else: | |
246 new_periods.append([begin, e]) | |
247 self._on_periods = new_periods | |
248 | |
249 def integrate(self): | |
250 self._trim() | |
251 tot = 0 | |
252 for s, e in self._on_periods: | |
253 if e is None: | |
254 e = self._timefn() | |
255 tot += (e-s) | |
256 return tot | |
257 | |
258 | |
259 | |
260 | |
261 | |
262 | |
263 |