11"""Defines a set of convenient utilities to use in scripts."""
22import time
33from typing import Callable
4+ from collections import Counter
45
56
67class DebugLoop :
@@ -17,41 +18,63 @@ def __init__(
1718
1819 Arguments:
1920 callback: called for each iteration of the loop. This callable
20- takes no arguments and should return True if successful else,
21- False .
21+ takes no arguments and should return 0 if successful and an
22+ error code otherwise (this will be used to report statistics) .
2223 num_iters: number of iterations to run before exiting.
2324 iters_per_print: number of iterations between prints.
2425 """
2526 self ._callback = callback
2627 self ._num_iters = num_iters
2728 self ._iters_per_print = iters_per_print
2829
29- self ._errors = 0
30+ self ._errors = {}
31+ self ._cummulative_errors = Counter ({})
3032 self ._iters = 0
3133 self ._iter_start_time = None
3234
3335 def _loop_func (self ):
34- self ._errors += 0 if self ._callback () else 1
36+ err = self ._callback ()
37+ assert type (err ) is int
38+
39+ if err != 0 :
40+ if err not in self ._errors :
41+ self ._errors [err ] = 1
42+ else :
43+ self ._errors [err ] += 1
3544 self ._iters += 1
3645
3746 if self ._iters % self ._iters_per_print == 0 :
3847 self ._print_func ()
3948 self ._iter_start_time = time .time ()
4049
50+ def _print_error_codes (self , errors ):
51+ total_errors = sum (errors .values ())
52+ for error_code , count in sorted (errors .items ()):
53+ code_errors = count / total_errors * 100
54+ print (
55+ f"Error code: { error_code } was { round (code_errors , 2 )} % of "
56+ f"errors."
57+ )
58+
4159 def _print_func (self ):
4260 now = time .time ()
4361 diff = now - self ._iter_start_time
4462
4563 freq = self ._iters_per_print / diff
46- error_rate = self ._errors / self ._iters_per_print * 100
64+ total_errors = sum (self ._errors .values ())
65+ error_rate = total_errors / self ._iters_per_print * 100
4766 print (
4867 f"Loop frequency is { round (freq , 2 )} hz at "
68+ f"({ total_errors } /{ self ._iters_per_print } )"
4969 f"{ round (error_rate , 2 )} % error rate."
5070 )
5171
72+ self ._print_error_codes (self ._errors )
73+
5274 # Reset statistics variables.
5375 self ._start_time = now
54- self ._errors = 0
76+ self ._cummulative_errors += Counter (self ._errors )
77+ self ._errors = {}
5578
5679 def loop (self ):
5780 """Loops the callback. Can be escaped with ctrl^c."""
@@ -67,4 +90,6 @@ def loop(self):
6790 f"Interrupted. Loop exiting. Completed { self ._iters } "
6891 f"iterations."
6992 )
93+ print (f"Cummultive errors:" )
94+ self ._print_error_codes (self ._cummulative_errors )
7095 pass
0 commit comments