Waht do you think about my repeated_timer class
Cecil Westerhof
Cecil at decebal.nl
Thu Feb 3 00:00:18 EST 2022
Cecil Westerhof <Cecil at decebal.nl> writes:
> I need (sometimes) to repeatedly execute a function. For this I wrote
> the below class. What do you think about it?
I wrote some unit test for the class. Is this the correct way to do
this?
For example in test_correct_params_no_start I check four things. Some
people say you should not check more as one.
By the way it was good that I defined __enter__ and __exit__. :-D
#!/usr/bin/env python3
import unittest
from threading import Timer
from repeated_timer import repeated_timer
class test_repeated_timer(unittest.TestCase):
def test_interval_zero(self):
with self.assertRaises(ValueError):
rt = repeated_timer(dummy_fn, 0)
def test_interval_negative(self):
with self.assertRaises(ValueError):
rt = repeated_timer(dummy_fn, -1)
def test_interval_string(self):
with self.assertRaises(TypeError):
rt = repeated_timer(dummy_fn, '.4')
def test_non_function(self):
with self.assertRaises(TypeError):
rt = repeated_timer('dummy_fn', .5)
def test_correct_params_no_start(self):
rt = repeated_timer(dummy_fn, .5)
self.assertEqual(rt._fn, dummy_fn)
self.assertEqual(rt._interval, .5)
self.assertEqual(rt._timer, None)
self.assertFalse(rt._is_running)
def test_correct_params_do_start(self):
with repeated_timer(dummy_fn, .375, True) as rt:
self.assertEqual(rt._fn, dummy_fn)
self.assertEqual(rt._interval, .375)
self.assertTrue (isinstance(rt._timer, Timer), 'There should be a timer')
self.assertTrue (rt._is_running, 'Should be running')
def test__start_later(self):
with repeated_timer(dummy_fn, .5) as rt:
self.assertEqual(rt._fn, dummy_fn)
self.assertEqual(rt._interval, .5)
self.assertEqual(rt._timer, None)
self.assertFalse(rt._is_running)
rt.start()
self.assertEqual(rt._fn, dummy_fn)
self.assertEqual(rt._interval, .5)
self.assertTrue (isinstance(rt._timer, Timer), 'There should be a timer')
self.assertTrue (rt._is_running, 'Should be running')
def dummy_fn():
pass
if __name__ == '__main__':
unittest.main()
> from threading import Timer
>
>
>
> class repeated_timer(object):
> def __init__(self, fn, interval, start = False):
> if not callable(fn):
> raise TypeError('{} is not a function'.format(fn))
> self._fn = fn
> self._check_interval(interval)
> self._interval = interval
> self._timer = None
> self._is_running = False
> if start:
> self.start()
>
> def _check_interval(self, interval):
> if not type(interval) in [int, float]:
> raise TypeError('{} is not numeric'.format(interval))
> if interval <= 0:
> raise ValueError('{} is not greater as 0'.format(interval))
>
> def _next(self):
> self._timer = Timer(self._interval, self._run)
> self._timer.start()
>
> def _run(self):
> self._next()
> self._fn()
>
> def set_interval(self, interval):
> self._check_interval(interval)
> self._interval = interval
>
> def start(self):
> if not self._is_running:
> self._next()
> self._is_running = True
>
> def stop(self):
> if self._is_running:
> self._timer.cancel()
> self._timer = None
> self._is_running = False
--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
More information about the Python-list
mailing list