Module noifTimer.noifTimer

Expand source code
from datetime import datetime


class Timer:
    """Simple timer class that tracks total elapsed time
    and average time between calls to 'start' and 'stop'."""

    def __init__(self, averagingWindowLength: int = 10, subsecondFormat: bool = False):
        """:param averagingWindowLength: Number of start/stop cycles
        to calculate the average elapsed time with.\n
        :param subsecondFormat: If True, formatTime() will
        include milliseconds and microseconds with its return string."""
        self.startTime = datetime.now()
        self.stopTime = datetime.now()
        self.averageElapsedTime = 0
        self.history = []
        self.elapsedTime = 0
        self.averagingWindowLength = averagingWindowLength
        self.subsecondFormat = subsecondFormat
        self.started = False

    def start(self):
        """Start timer."""
        self.startTime = datetime.now()
        self.started = True

    def stop(self):
        """Stop timer.

        Calculates elapsed time and average elapsed time."""
        self.stopTime = datetime.now()
        self.started = False
        self.elapsedTime = (self.stopTime - self.startTime).total_seconds()
        self._saveElapsedTime()
        self.averageElapsedTime = sum(self.history) / (len(self.history))

    def _saveElapsedTime(self):
        """Saves current elapsed time to the history buffer
        in a FIFO manner."""
        if len(self.history) >= self.averagingWindowLength:
            self.history.pop(0)
        self.history.append(self.elapsedTime)

    def checkTime(self, format: bool = True) -> float | str:
        """Returns current elapsed without stopping the timer.

        :param format: If True, elapsed time is returned as a string.
        If False, elapsed time is returned as a float."""
        self.elapsedTime = (datetime.now() - self.startTime).total_seconds()
        return self.formatTime(self.elapsedTime) if format else self.elapsedTime

    def _getTimeUnit(
        self, numSeconds: float, secondsPerUnit: float, unitSuffix: str
    ) -> tuple[float, str]:
        """Determines the number of units in a given number of seconds
        by integer division.

        Returns a tuple containing the remaining number of seconds after division
        as well as the number of units as a string with 'unitSuffix' appended to the string.

        e.g. _getTimeUnit(124, 60, 'm') will return (4, '2m')"""
        numUnits = int(numSeconds / secondsPerUnit)
        if numUnits > 0:
            remainder = numSeconds - (numUnits * secondsPerUnit)
            return (remainder, f"{numUnits}{unitSuffix}")
        else:
            return (numSeconds, "")

    def formatTime(self, numSeconds: float) -> str:
        """Returns numSeconds as a string with units."""
        microsecond = 0.000001
        millisecond = 0.001
        second = 1
        secondsPerMinute = 60
        secondsPerHour = secondsPerMinute * 60
        secondsPerDay = secondsPerHour * 24
        secondsPerWeek = secondsPerDay * 7
        secondsPerMonth = secondsPerWeek * 4
        secondsPerYear = secondsPerMonth * 12
        timeUnits = [
            (secondsPerYear, "y"),
            (secondsPerMonth, "mn"),
            (secondsPerWeek, "w"),
            (secondsPerDay, "d"),
            (secondsPerHour, "h"),
            (secondsPerMinute, "m"),
            (second, "s"),
            (millisecond, "ms"),
            (microsecond, "us"),
        ]
        if not self.subsecondFormat:
            timeUnits = timeUnits[:-2]
        timeString = ""
        for timeUnit in timeUnits:
            numSeconds, unitString = self._getTimeUnit(
                numSeconds, timeUnit[0], timeUnit[1]
            )
            if unitString != "":
                timeString += f"{unitString} "
        return timeString

    def getStats(self, format: bool = True) -> str:
        """Returns string for elapsed time and average elapsed time."""
        if format:
            return f"elapsed time: {self.formatTime(self.elapsedTime)}\naverage elapsed time: {self.formatTime(self.averageElapsedTime)}"
        else:
            return f"elapsed time: {self.elapsedTime}s\naverage elapsed time: {self.averageElapsedTime}s"

Classes

class Timer (averagingWindowLength: int = 10, subsecondFormat: bool = False)

Simple timer class that tracks total elapsed time and average time between calls to 'start' and 'stop'.

:param averagingWindowLength: Number of start/stop cycles to calculate the average elapsed time with.

:param subsecondFormat: If True, formatTime() will include milliseconds and microseconds with its return string.

Expand source code
class Timer:
    """Simple timer class that tracks total elapsed time
    and average time between calls to 'start' and 'stop'."""

    def __init__(self, averagingWindowLength: int = 10, subsecondFormat: bool = False):
        """:param averagingWindowLength: Number of start/stop cycles
        to calculate the average elapsed time with.\n
        :param subsecondFormat: If True, formatTime() will
        include milliseconds and microseconds with its return string."""
        self.startTime = datetime.now()
        self.stopTime = datetime.now()
        self.averageElapsedTime = 0
        self.history = []
        self.elapsedTime = 0
        self.averagingWindowLength = averagingWindowLength
        self.subsecondFormat = subsecondFormat
        self.started = False

    def start(self):
        """Start timer."""
        self.startTime = datetime.now()
        self.started = True

    def stop(self):
        """Stop timer.

        Calculates elapsed time and average elapsed time."""
        self.stopTime = datetime.now()
        self.started = False
        self.elapsedTime = (self.stopTime - self.startTime).total_seconds()
        self._saveElapsedTime()
        self.averageElapsedTime = sum(self.history) / (len(self.history))

    def _saveElapsedTime(self):
        """Saves current elapsed time to the history buffer
        in a FIFO manner."""
        if len(self.history) >= self.averagingWindowLength:
            self.history.pop(0)
        self.history.append(self.elapsedTime)

    def checkTime(self, format: bool = True) -> float | str:
        """Returns current elapsed without stopping the timer.

        :param format: If True, elapsed time is returned as a string.
        If False, elapsed time is returned as a float."""
        self.elapsedTime = (datetime.now() - self.startTime).total_seconds()
        return self.formatTime(self.elapsedTime) if format else self.elapsedTime

    def _getTimeUnit(
        self, numSeconds: float, secondsPerUnit: float, unitSuffix: str
    ) -> tuple[float, str]:
        """Determines the number of units in a given number of seconds
        by integer division.

        Returns a tuple containing the remaining number of seconds after division
        as well as the number of units as a string with 'unitSuffix' appended to the string.

        e.g. _getTimeUnit(124, 60, 'm') will return (4, '2m')"""
        numUnits = int(numSeconds / secondsPerUnit)
        if numUnits > 0:
            remainder = numSeconds - (numUnits * secondsPerUnit)
            return (remainder, f"{numUnits}{unitSuffix}")
        else:
            return (numSeconds, "")

    def formatTime(self, numSeconds: float) -> str:
        """Returns numSeconds as a string with units."""
        microsecond = 0.000001
        millisecond = 0.001
        second = 1
        secondsPerMinute = 60
        secondsPerHour = secondsPerMinute * 60
        secondsPerDay = secondsPerHour * 24
        secondsPerWeek = secondsPerDay * 7
        secondsPerMonth = secondsPerWeek * 4
        secondsPerYear = secondsPerMonth * 12
        timeUnits = [
            (secondsPerYear, "y"),
            (secondsPerMonth, "mn"),
            (secondsPerWeek, "w"),
            (secondsPerDay, "d"),
            (secondsPerHour, "h"),
            (secondsPerMinute, "m"),
            (second, "s"),
            (millisecond, "ms"),
            (microsecond, "us"),
        ]
        if not self.subsecondFormat:
            timeUnits = timeUnits[:-2]
        timeString = ""
        for timeUnit in timeUnits:
            numSeconds, unitString = self._getTimeUnit(
                numSeconds, timeUnit[0], timeUnit[1]
            )
            if unitString != "":
                timeString += f"{unitString} "
        return timeString

    def getStats(self, format: bool = True) -> str:
        """Returns string for elapsed time and average elapsed time."""
        if format:
            return f"elapsed time: {self.formatTime(self.elapsedTime)}\naverage elapsed time: {self.formatTime(self.averageElapsedTime)}"
        else:
            return f"elapsed time: {self.elapsedTime}s\naverage elapsed time: {self.averageElapsedTime}s"

Methods

def checkTime(self, format: bool = True) ‑> float | str

Returns current elapsed without stopping the timer.

:param format: If True, elapsed time is returned as a string. If False, elapsed time is returned as a float.

Expand source code
def checkTime(self, format: bool = True) -> float | str:
    """Returns current elapsed without stopping the timer.

    :param format: If True, elapsed time is returned as a string.
    If False, elapsed time is returned as a float."""
    self.elapsedTime = (datetime.now() - self.startTime).total_seconds()
    return self.formatTime(self.elapsedTime) if format else self.elapsedTime
def formatTime(self, numSeconds: float) ‑> str

Returns numSeconds as a string with units.

Expand source code
def formatTime(self, numSeconds: float) -> str:
    """Returns numSeconds as a string with units."""
    microsecond = 0.000001
    millisecond = 0.001
    second = 1
    secondsPerMinute = 60
    secondsPerHour = secondsPerMinute * 60
    secondsPerDay = secondsPerHour * 24
    secondsPerWeek = secondsPerDay * 7
    secondsPerMonth = secondsPerWeek * 4
    secondsPerYear = secondsPerMonth * 12
    timeUnits = [
        (secondsPerYear, "y"),
        (secondsPerMonth, "mn"),
        (secondsPerWeek, "w"),
        (secondsPerDay, "d"),
        (secondsPerHour, "h"),
        (secondsPerMinute, "m"),
        (second, "s"),
        (millisecond, "ms"),
        (microsecond, "us"),
    ]
    if not self.subsecondFormat:
        timeUnits = timeUnits[:-2]
    timeString = ""
    for timeUnit in timeUnits:
        numSeconds, unitString = self._getTimeUnit(
            numSeconds, timeUnit[0], timeUnit[1]
        )
        if unitString != "":
            timeString += f"{unitString} "
    return timeString
def getStats(self, format: bool = True) ‑> str

Returns string for elapsed time and average elapsed time.

Expand source code
def getStats(self, format: bool = True) -> str:
    """Returns string for elapsed time and average elapsed time."""
    if format:
        return f"elapsed time: {self.formatTime(self.elapsedTime)}\naverage elapsed time: {self.formatTime(self.averageElapsedTime)}"
    else:
        return f"elapsed time: {self.elapsedTime}s\naverage elapsed time: {self.averageElapsedTime}s"
def start(self)

Start timer.

Expand source code
def start(self):
    """Start timer."""
    self.startTime = datetime.now()
    self.started = True
def stop(self)

Stop timer.

Calculates elapsed time and average elapsed time.

Expand source code
def stop(self):
    """Stop timer.

    Calculates elapsed time and average elapsed time."""
    self.stopTime = datetime.now()
    self.started = False
    self.elapsedTime = (self.stopTime - self.startTime).total_seconds()
    self._saveElapsedTime()
    self.averageElapsedTime = sum(self.history) / (len(self.history))