Created
August 3, 2011 21:48
-
-
Save sumeet/1123871 to your computer and use it in GitHub Desktop.
A Python timer class.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
class Stopwatch(object): | |
"""A stopwatch utility for timing execution that can be used as a regular | |
object or as a context manager. | |
NOTE: This should not be used an accurate benchmark of Python code, but a | |
way to check how much time has elapsed between actions. And this does not | |
account for changes or blips in the system clock. | |
Instance attributes: | |
start_time -- timestamp when the timer started | |
stop_time -- timestamp when the timer stopped | |
As a regular object: | |
>>> stopwatch = Stopwatch() | |
>>> stopwatch.start() | |
>>> time.sleep(1) | |
>>> 1 <= stopwatch.time_elapsed <= 2 | |
True | |
>>> time.sleep(1) | |
>>> stopwatch.stop() | |
>>> 2 <= stopwatch.total_run_time | |
True | |
As a context manager: | |
>>> with Stopwatch() as stopwatch: | |
... time.sleep(1) | |
... print repr(1 <= stopwatch.time_elapsed <= 2) | |
... time.sleep(1) | |
True | |
>>> 2 <= stopwatch.total_run_time | |
True | |
""" | |
def __init__(self): | |
"""Initialize a new `Stopwatch`, but do not start timing.""" | |
self.start_time = None | |
self.stop_time = None | |
def start(self): | |
"""Start timing.""" | |
self.start_time = time.time() | |
def stop(self): | |
"""Stop timing.""" | |
self.stop_time = time.time() | |
@property | |
def time_elapsed(self): | |
"""Return the number of seconds that have elapsed since this | |
`Stopwatch` started timing. | |
This is used for checking how much time has elapsed while the timer is | |
still running. | |
""" | |
assert not self.stop_time, \ | |
"Can't check `time_elapsed` on an ended `Stopwatch`." | |
return time.time() - self.start_time | |
@property | |
def total_run_time(self): | |
"""Return the number of seconds that elapsed from when this `Stopwatch` | |
started to when it ended. | |
""" | |
return self.stop_time - self.start_time | |
def __enter__(self): | |
"""Start timing and return this `Stopwatch` instance.""" | |
self.start() | |
return self | |
def __exit__(self, type, value, traceback): | |
"""Stop timing. | |
If there was an exception inside the `with` block, re-raise it. | |
>>> with Stopwatch() as stopwatch: | |
... raise Exception | |
Traceback (most recent call last): | |
... | |
Exception | |
""" | |
self.stop() | |
if type: | |
raise type, value, traceback |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
import unittest | |
import stopwatch | |
class MockSystemClock(object): | |
"""Represents a system clock with time starting at `0` and incremented | |
whenever `sleep()` is called. | |
Meant to replace the `time()` and `sleep()` functions in the `time` module. | |
>>> clock = MockSystemClock() | |
>>> clock.time() | |
0 | |
>>> clock.sleep(1) | |
>>> clock.time() | |
1 | |
""" | |
def __init__(self): | |
"""Initialize the current system time to `0`.""" | |
self._system_time = 0 | |
def time(self): | |
"""Return the current system time.""" | |
return self._system_time | |
def sleep(self, seconds): | |
"""Increment the system time by `seconds`.""" | |
self._system_time += seconds | |
class StopwatchTestCase(unittest.TestCase): | |
def setUp(self): | |
"""Monkey patch `time.time()` and `time.sleep()` to point to the | |
corresponding methods on a new `MockSystemClock` instance. | |
""" | |
self._time_time = time.time | |
self._time_sleep = time.sleep | |
mock_system_clock = MockSystemClock() | |
time.time = mock_system_clock.time | |
time.sleep = mock_system_clock.sleep | |
def tearDown(self): | |
"""Restore the `time` module.""" | |
time.time = self._time_time | |
time.sleep = self._time_sleep | |
def test_stopwatch_as_object(self): | |
"""Test using a `Stopwatch` as a regular object.""" | |
sw = stopwatch.Stopwatch() | |
sw.start() | |
self.assertEqual(0, sw.time_elapsed) | |
time.sleep(1) | |
self.assertEqual(1, sw.time_elapsed) | |
sw.stop() | |
self.assertEqual(1, sw.total_run_time) | |
def test_stopwatch_as_context_manager(self): | |
"""Test using a `Stopwatch` as a context manager.""" | |
with stopwatch.Stopwatch() as sw: | |
sw.start() | |
self.assertEqual(0, sw.time_elapsed) | |
time.sleep(1) | |
self.assertEqual(1, sw.time_elapsed) | |
self.assertEqual(1, sw.total_run_time) | |
if __name__ == '__main__': | |
unittest.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment