Beginner Project: Running Lap Timer?


Not sure if this question is appropriate for this forum or not, so please say if I should be asking elsewhere.

I’m a running coach and I’m looking for an app that would allow me to record the lap times of runners. I can’t find an existing app that will do the job, so I wondered if this is something I could learn to write myself in Python, with the help of the community?

The Functionality I Need

  1. Add the names of each runner.
  2. Start a timer (to mimic a stopwatch)
  3. As each runner completes a lap, tap their name on screen.
  4. This would automatically store each of their lap times in a table column.
  5. When the runners complete a second lap, their times go into a second column. This repeats for however many laps are required.
  6. The app/site would also ideally keep a running total of the average lap time for each runner, so they can see their overall pace across the whole distance.

If this feasible for a beginner to write in Python? I’m happy to take my time over it. There’s no rush.


It doesn’t sound too difficult to me. Personally, I do it in tkinter because that comes as standard in the Python library, assuming you’re talking about running it on an actual computer. The tricky bit, I think, is tapping the screen at the right time as the runner completes a lap, especially if there are multiple runners completing laps in quick succession…

Thanks for replying. Tapping the screen on time hopefully shouldn’t be a big issue, as this will mainly be used for longer runs, tapping every lap rather than 100m for instance.

I’m new to Python, and hope to use this as a project to learn as I go.

Is there any advice you can give about how to approach this using Tkinter? E.g. Where to start and what the steps to complete this may look like?

I appreciate there’s probably many different ways to approach this, but I’d just appreciate some suggested guidance if at all possible.

Thanks again.

My advice (for what it’s worth) is that you should get your app working first with a CLI, then migrate it to a GUI: a GUI is, for the most part, no more than a front end for the ‘nuts and bolts’ of the CLI code and if you keep in mind that a GUI is the goal, then you’ll be more inclined to use functions within your code, which can be simply(!?) migrated to a GUI app.

I’m going to, unashamedly, give a shout out to PAGE for the migration process, as it seems to me that it was designed for that very purpose: I’ve been deep in the weeds of PAGE for a couple of days now, and the more I learn about it, the more impressed I become.

1 Like

General tip regarding timing: Python comes with a monotonic clock which is perfect for this sort of thing.

>>> print(time.monotonic()); time.sleep(1); print(time.monotonic())

It doesn’t mean anything in particular, just that when one second passes, the monotonic clock will increase by one. So when you start the timer, you record the current time on the monotonic clock, and all future calculations are the difference between that initial time and some future time. Extremely convenient.


Wait, what’s the use of this over time.time exactly? Can time.time go backwards to account for DST or something?

Edit: time — Time access and conversions — Python 3.11.3 documentation

While this function normally returns non-decreasing values, it can return a lower value than a previous call if the system clock has been set back between the two calls.

Huh. I have definitely unintentionally relied on time.time being monotonic a lot of times. Better go look over some of my code…

Yeah, that’s a trap that only gets you very VERY occasionally, but when it does, it’s so confusing. For example, you start running your script on a computer whose clock is a few seconds off, and then NTP kicks in and fixes the clock; your time calculations inexplicably do the wrong thing, but only briefly and only that once. But if you use time.monotonic(), you’ll be safe.

You could also get caught out by a leap second, although those are deprecated anyway.

I’ve not given this too much consideration; it’s more of a subconscious process for me, but for the actual build, I think that I’d have one process for each runner (that is to say, have a simple app that can be started many times; once for each runner) rather than try to have a more complicated app running once and trying to keep track of many runners. Then process the data that is collected by each instance of the (let’s call it a) ‘timer app’. You could then have a GUI based ‘control panel’ to start/stop said app: just spitballing thoughts here.

That said, maybe @Rosuav is on to something with time.monotonic() function.