Last active
August 29, 2015 13:57
-
-
Save alexprengere/9526152 to your computer and use it in GitHub Desktop.
Simple converter from pace to reference times for runners.
This file contains 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
#!/usr/bin/env python | |
""" | |
Simple converter from pace to reference times | |
for runners. | |
$ ./run_times_from_pace.py 4:15 -d 1.0 | |
1.00km in 0:04:15 gives you: | |
1km: 0:04:15 ( 1.00km) | |
5km: 0:21:15 ( 5.00km) | |
10km: 0:42:30 (10.00km) | |
10miles: 1:08:22.950000 (16.09km) | |
Half-marathon: 1:29:40.500000 (21.10km) | |
30km: 2:07:30 (30.00km) | |
Marathon: 2:59:21 (42.20km) | |
Speed: 14.12 km/h | |
""" | |
from datetime import timedelta | |
from operator import itemgetter | |
DISTANCES = [ | |
(0.05, '50m'), | |
(0.1, '100m'), | |
(1, '1km'), | |
(5, '5km'), | |
(10, '10km'), | |
(16.09, '10miles'), | |
(20, '20km'), | |
(21.1, 'Half-marathon'), | |
(30, '30km'), | |
(42.2, 'Marathon'), | |
(50, '50km'), | |
(100, '100km'), | |
] | |
def fmt_minutes(minutes): | |
"""Nicely format a duration in minutes. | |
>>> fmt_minutes(30) | |
'0:30:00' | |
>>> fmt_minutes(120) | |
'2:00:00' | |
>>> fmt_minutes(60 * 48) | |
'2 days, 0:00:00' | |
""" | |
seconds = 60 * minutes | |
return str(timedelta(seconds=seconds)) | |
def duration_to_minutes(dur): | |
"""Parse HH:MM:SS date input. | |
>>> duration_to_minutes('01:00:00') | |
60.0 | |
>>> duration_to_minutes('00:30:30') | |
30.5 | |
>>> duration_to_minutes('15:00') | |
15.0 | |
>>> duration_to_minutes('5') | |
5.0 | |
""" | |
dur = dur.split(':') | |
if len(dur) == 3: | |
return float(dur[0]) * 60 + float(dur[1]) + float(dur[2]) / 60 | |
if len(dur) == 2: | |
return float(dur[0]) + float(dur[1]) / 60 | |
return float(dur[0]) | |
def main(minutes, distance, extra_distance=None): | |
"""Main. | |
""" | |
# This is the pace in minutes per km | |
min_per_km = minutes / distance | |
print '{0:.2f}km in {1} gives you:\n'.format(distance, | |
fmt_minutes(minutes)) | |
if extra_distance is None: | |
distances = DISTANCES | |
else: | |
distances = DISTANCES + [(extra_distance, '(*) {0:5.3f}km'.format(extra_distance))] | |
for d, name in sorted(distances, key=itemgetter(0)): | |
print '{0:>15}: {1:<15} ({2:5.3f}km)'.format(name, | |
fmt_minutes(min_per_km * d), | |
float(d)) | |
print '\n{0:>15}: {1} for 1km'.format('Pace', fmt_minutes(min_per_km)) | |
if min_per_km == 0: | |
print 'Infinite speed ;)' | |
else: | |
print '{0:>15}: {1:.3f} km/h'.format('Speed', 60.0 / min_per_km) | |
def _test(): | |
"""Run doctests. | |
""" | |
import doctest | |
doctest.testmod() | |
if __name__ == '__main__': | |
_test() | |
import argparse, sys | |
import os.path as op | |
from textwrap import dedent | |
parser = argparse.ArgumentParser( | |
formatter_class=argparse.RawTextHelpFormatter, | |
description=dedent("""\ | |
Input the duration needed to run 1km, | |
this is your pace in minutes per km, | |
the script will give you reference | |
times on standard running distances. | |
""")) | |
parser.add_argument("duration", | |
help=dedent("""\ | |
Duration, formatted HH:MM:SS. | |
Partial durations will be parsed | |
as MM:SS, then MM. | |
""")) | |
parser.add_argument("-d", "--distance", | |
type=float, | |
default=1.0, | |
help=dedent("""\ | |
Distance in km, default is 1.0, | |
this way the input is the pace | |
in minutes per km. You can change | |
it to input a different distance. | |
""")) | |
parser.add_argument("-D", "--extra-distance", | |
type=float, | |
default=None, | |
help=dedent("""\ | |
If given, in km, add an extra distance | |
to the output. | |
""")) | |
parser.epilog = dedent("""\ | |
Examples: | |
./{0} 4:15 | |
./{1} 1:32:00 -d 12.6 | |
./{2} 00:20 -d 0.1 | |
""".format(*(op.basename(sys.argv[0]),) * 3)) | |
args = parser.parse_args() | |
minutes = duration_to_minutes(args.duration) | |
main(minutes, args.distance, args.extra_distance) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment