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