Skip to main content

la-stopwatch

Measure the amount of time that elapses between lap times.

install

pip install la-stopwatch

usage

There are two versions of stopwatch:

  • StopwatchNS
  • Stopwatch

While both measure using nanoseconds, the second option convert nanoseconds to timedelta before returning any time measurement. All examples will be using Stopwatch because timedelta it's easy to read, but it doesn't matter each you use because both have the same methods.

basic

The first thing you should know is that time start when Stopwatch is created.

from time import sleep

from la_stopwatch import Stopwatch

stopwatch = Stopwatch()

time.sleep(1)
print(stopwatch.duration())  # 0:00:01.001374

Retrive the current time with duration().

record

You can record each lap time for future analysis using record().

stopwatch = Stopwatch()

time.sleep(1)
stopwatch.record()

time.sleep(1)
stopwatch.record()

print(stopwatch.get_record(0))  # 0:00:01.001317
print(stopwatch.get_record(1))  # 0:00:02.002678

Use get_record(n) to get the nº record.

named record

Is possible to give a name for each record.

stopwatch = Stopwatch()

time.sleep(1)
stopwatch.record("first")

time.sleep(1)
stopwatch.record("second")

time.sleep(1)
stopwatch.record("third")

print(stopwatch.get_record("first"))  # 0:00:01.001374
print(stopwatch.get_record("second"))  # 0:00:02.002231
print(stopwatch.get_record("third"))  # 0:00:03.003551

all records

All records (nameless or not) are available with get_records().

stopwatch = Stopwatch()

time.sleep(1)
stopwatch.record()

time.sleep(1)
stopwatch.record("second")

time.sleep(1)
stopwatch.record()

# {
#   0: datetime.timedelta(seconds=1, microseconds=392),
#   'second': datetime.timedelta(seconds=2, microseconds=1447),
#   1: datetime.timedelta(seconds=3, microseconds=2614)
# }
print(stopwatch.get_records())

chain calls

Some methods return the Stopwatch so you can chain method calls. For example, you can record how much time take to do each action if you reset every time after recording.

stopwatch = Stopwatch()

time.sleep(1)
stopwatch.record().reset()

time.sleep(1)
stopwatch.record()

print(stopwatch.get_record(0))  # 0:00:01.001267
print(stopwatch.get_record(1))  # 0:00:01.000460

context manager

Stopwatch accepts a callback as argument which will be called on exit of context managers receving the duration.

# 0:00:01.001578
with Stopwatch(print):
    time.sleep(1)

The advantage of context manager is that you can interact with Stopwatch during the scope.

# 0:00:00.000082
with Stopwatch(print) as stopwatch:
    time.sleep(1)
    stopwatch.reset()

The callback receive any extra arguments during Stopwatch initialization and the duration. Duration will be passed inside kwargs with the name duration or as last argument (in case kwargs is empty).

def on_finish(msg, duration):
    print(msg, duration)

# Success 0:00:01.001218
with Stopwatch(on_finish, "Success"):
    time.sleep(1)

It's okay to use inside a class with self keyword.

class Test():
    def on_finish(self, msg, grade, duration):
        print(msg, grade, duration)
    
    def start(self):
        with Stopwatch(self.on_finish, "Success", grade="A+"):
            time.sleep(1)

# Success A+ 0:00:01.001470
Test().start()

decorator

Stopwatch accepts a callback as argument which will be called on exiting decoratored functions.

@Stopwatch(print)
def main():
    time.sleep(1)


# 0:00:01.001281
main()

The callback needs to be identical to the decorated function but with the last argument being duration. Duration will be passed inside kwargs with the name duration or as last argument (in case kwargs is empty).

def on_finish(student, msg, duration, grade):
    print(student, msg, duration, grade)


@Stopwatch(on_finish)
def main(student, msg="Success", grade="A+"):
    time.sleep(1)


# Bob Success 0:00:01.000698 A+
main("Bob")

It's okay to use inside a class with self keyword.

class Test():
    def on_finish(self, student, msg, duration, grade):
        print(student, msg, duration, grade)
    
    @Stopwatch(on_finish)
    def start(self, student, msg="Success", grade="A+"):
        time.sleep(1)

# Bob Success 0:00:01.000500 A+
Test().start("Bob")

async

While Stopwatch alone doesn't have reason to use asynchronous code, it can fit your asynchronous code easly. You may need this when:

  • Decorating an async function
  • The Callback is an async function

async - context manager

Whenever you are inside an asynchronous function use async with.

import asyncio

from la_stopwatch import Stopwatch


async def on_finish_1(duration):
    print(duration)


def on_finish_2(duration):
    print(duration)


async def main():
    async with Stopwatch(on_finish_1):
        await asyncio.sleep(1)
    
    async with Stopwatch(on_finish_2):
        await asyncio.sleep(1)


# 0:00:01.001196
# 0:00:01.001875
asyncio.run(main())

It will check whenever you callback is asynchronous or not before calling, so you can change the callback as you feel like without breaking your code.

async - decorator

Same as context managers, it will check whenever your callback is asynchronous or not before calling.

async def on_finish(duration):
    print(duration)


@Stopwatch(on_finish)
async def main():
    await asyncio.sleep(1)


# 0:00:01.002338
asyncio.run(main())
import asyncio

from la_stopwatch import Stopwatch


def on_finish(duration):
    print(duration)


@Stopwatch(on_finish)
async def main():
    await asyncio.sleep(1)


# 0:00:01.002063
asyncio.run(main())

Release files for la-stopwatch 0.0.9

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for la-stopwatch 0.0.9
File Size Uploaded
la-stopwatch-0.0.9.tar.gz 8.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for la-stopwatch 0.0.9
File Interpreter ABI Platform
la_stopwatch-0.0.9-py3-none-any.whl Python 3 none any Details

Total release size: 14.8 kB

Release files / la-stopwatch-0.0.9.tar.gz

Download URL la-stopwatch-0.0.9.tar.gz
Size 8.4 kB
Tags Source
SHA-256 checksum
How to use checksums
f8b3f0e40bb97c0376561af40366bcf98d1090efe48338654b5729a671a25aa0
BLAKE2b-256 checksum
How to use checksums
059b523b5d9b1015e32f9bbc0a9cf1576de66a3e9ce57a6fe7e67f79d7faff95
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via pdm/2.1.3 CPython/3.10.6

Release files / la_stopwatch-0.0.9-py3-none-any.whl

Download URL la_stopwatch-0.0.9-py3-none-any.whl
Size 6.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
90d1e901556d8c4d0fd8dd48225f88e5cdd504b86a093ab6ab538d25db2d9ea1
BLAKE2b-256 checksum
How to use checksums
5e18efdc736262b05204d73d3e4fb4a7eb8909ddf7f200389e7830d102ea8567
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via pdm/2.1.3 CPython/3.10.6

Release history Release notifications | RSS feed

This release

0.0.9 This release

2 release files

0.0.8

1 release file

0.0.7

1 release file

0.0.6

1 release file

0.0.5

1 release file

0.0.4

1 release file

0.0.3

1 release file

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page