Source code for timeutils.stopwatch

# Author: Michal Ciesielczyk
# Licence: MIT
import time

from .timespan import TimeSpan


[docs]class Stopwatch: """Provides a set of methods and properties that you can use to accurately measure elapsed time. :param start: if set to `True`, immediately starts measuring the time (by calling :py:meth:`~.stopwatch.Stopwatch.start`). By default set to `False`. :type start: bool .. rubric:: Examples Simple time measurement:: sw = Stopwatch(start=True) # code to be measured sw.stop() Getting the elapsed time:: print(sw.elapsed) # hh:mm:ss.ms print(sw.elapsed.human_str()) # human-readable time Restarting the stopwatch instance:: sw.restart() Pausing and resuming the stopwatch:: sw.pause() # code block not included in the measurement sw.resume() .. note:: :py:class:`~.stopwatch.Stopwatch` methods are protected against inappropriate calls. It is an error to start or stop a :py:class:`~.stopwatch.Stopwatch` object that is already in the desired state. .. seealso:: Documentation of the :py:class:`~.timespan.TimeSpan` class. """ def __init__(self, start=False): self.__elapsed = 0 self.__stop_time = None self.__start_time = time.time() if start else None self.__last_resume = self.__start_time @property def is_running(self): """Indicates whether the :py:class:`~.stopwatch.Stopwatch` instance is running. """ return self.__start_time is not None and self.__stop_time is None
[docs] def start(self): """Starts measuring elapsed time for an interval.""" assert not self.is_running, "Stopwatch is already running." assert self.__elapsed == 0, "Stopwatch has already been executed." self.__start_time = time.time() self.__last_resume = self.__start_time
[docs] def reset(self): """Stops time interval measurement and resets the :py:class:`~.stopwatch.Stopwatch` instance. The time elapsed before reset is set to zero. """ self.__elapsed = 0 self.__start_time = None self.__stop_time = None self.__last_resume = None
@property def is_paused(self): """Indicates whether the :py:class:`~.stopwatch.Stopwatch` instance is paused. """ return self.__last_resume is None
[docs] def pause(self): """Pauses the time measurement until the :py:class:`~.stopwatch.Stopwatch` instance is resumed or stopped. Returns the total elapsed time measured by the current instance. Call :py:meth:`~.stopwatch.Stopwatch.resume` to resume measuring elapsed time. """ assert self.is_running, "Stopwatch is already stopped." assert not self.is_paused, "Stopwatch is already paused." self.__elapsed += time.time() - self.__last_resume self.__last_resume = None return self.elapsed
[docs] def resume(self): """Resumes measuring elapsed time after calling :py:meth:`~timeutils.stopwatch.Stopwatch.pause`. """ assert self.is_running, "Stopwatch is already stopped." assert self.is_paused, "Stopwatch is not paused." self.__last_resume = time.time()
[docs] def stop(self): """Stops the time measurement. Returns the total elapsed time measured by the current instance. """ assert self.is_running, "Stopwatch is already stopped." self.__stop_time = time.time() if not self.is_paused: self.__elapsed += self.__stop_time - self.__last_resume self.__last_resume = None return self.elapsed
[docs] def restart(self): """Stops time interval measurement, resets the :py:class:`~.stopwatch.Stopwatch` instance, and starts measuring elapsed time. The time elapsed before restart is set to zero. """ self.reset() self.start()
@property def elapsed_seconds(self): """Gets the total elapsed time in fractions of a second measured by the current instance. """ if self.is_running and not self.is_paused: return self.__elapsed + time.time() - self.__last_resume else: return self.__elapsed @property def elapsed(self): """Gets the total elapsed time measured by the current instance.""" return TimeSpan(self.elapsed_seconds) def __float__(self): return self.elapsed_seconds @property def start_time(self): """Returns the time at which the time measurement has been started.""" assert self.__start_time is not None, \ "The Stopwatch hasn't been started." return self.__start_time @property def stop_time(self): """Returns the time at which the time measurement has been stopped.""" assert self.__stop_time is not None, \ "Stopwatch hasn't been stopped yet." return self.__stop_time def __str__(self): return str(self.elapsed) def __enter__(self): self.start() def __exit__(self, exception_type, exception_value, traceback): self.stop()