d8683491f2bd899aa08e1baea82697c935ca547a
1 # -*- coding: utf-8 -*-
5 Munter Time Calculation
7 Wylark Mountaineering LLC
9 A rudimentary program which implements the Munter time calculation.
15 from . import __progname__
as progname
16 from . import __version__
as version
18 class InvalidUnitsException(Exception):
22 'uphill': { 'rate': 4, 'direction': '↑' },
23 'flat': { 'rate': 6, 'direction': '→' }, # or downhill on foot
24 'downhill': { 'rate': 10, 'direction': '↓' },
25 'bushwhacking': { 'rate': 2, 'direction': '↹' },
34 unit_choices
= ['metric', 'imperial']
35 travel_mode_choices
= rates
.keys()
36 fitness_choices
= fitnesses
.keys()
38 def time_calc(distance
, elevation
, fitness
='average', rate
='uphill',
42 if units
not in unit_choices
:
43 raise InvalidUnitsException
47 if 'imperial' == units
:
49 distance
= (distance
* 1.609) # mi to km
50 elevation
= (elevation
* .305) # ft to m
52 unit_count
= distance
+ (elevation
/ 100.0)
54 retval
['time'] = (distance
+ (elevation
/ 100.0)) / rates
[rate
]['rate']
55 retval
['time'] = retval
['time'] * fitnesses
[fitness
]
57 retval
['unit_count'] = unit_count
58 retval
['direction'] = rates
[rate
]['direction']
59 retval
['pace'] = rates
[rate
]['rate']
63 def print_ugly_estimate(est
):
64 hours
= int(est
['time'])
65 minutes
= int((est
['time'] - hours
) * 60)
66 print("{human_time}".format(
67 human_time
="{hours} hours {minutes} minutes".format(
71 def print_pretty_estimate(est
):
72 hours
= int(est
['time'])
73 minutes
= int((est
['time'] - hours
) * 60)
75 # NOTE: Below, the line with the unicode up arrow uses an alignment
76 # value of 31. In the future, consider using e.g. wcwidth
77 # library so that this is more elegant.
78 print("\n\t╒═══════════════════════════════╕")
79 print("\t╎▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒╎╮")
80 print("\t╎▒{:^29}▒╎│".format(''))
81 print("\t╎▒{pace_readable:^31}▒╎│".format(
82 pace_readable
="{units} {direction} @ {pace}".format(
83 units
=round(est
['unit_count']),
84 direction
=est
['direction'],
86 print("\t╎▒{human_time:^29}▒╎│".format(
87 human_time
="{hours} hours {minutes} minutes".format(
90 print("\t╎▒{:^29}▒╎│".format(''))
91 print("\t╎▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒╎│")
92 print("\t╘═══════════════════════════════╛│")
93 print("\t └───────────────────────────────┘\n")
96 parser
= argparse
.ArgumentParser(description
='Implementation of '
97 'the Munter time calculation')
99 # No required args anymore, since -g overrides any requirement
100 parser
.add_argument('--distance',
105 help='Distance (in km, by default)')
107 parser
.add_argument('--elevation',
112 help='Elevation change (in m, by default)')
114 parser
.add_argument('--travel-mode',
118 choices
=travel_mode_choices
, required
=False,
119 help='Travel mode (uphill, by default)')
121 parser
.add_argument('--fitness',
125 choices
=fitness_choices
, required
=False,
126 help='Fitness modifier (average, by default)')
128 parser
.add_argument('--units',
133 choices
=unit_choices
,
134 help='Units of input values')
136 parser
.add_argument('--pretty',
141 help="Make output pretty");
143 parser
.add_argument('--gui',
148 help='Launch GUI mode (overrides --pretty)')
150 parser
.add_argument('--version',
155 help='Print version and exit')
160 parser
= get_parser()
161 opts
= parser
.parse_args()
163 distance
= opts
.distance
164 elevation
= opts
.elevation
165 fitness
= opts
.fitness
167 travel_mode
= opts
.travel_mode
170 get_version
= opts
.version
173 print("%s - v%s" % (progname
, version
))
176 time_estimate
= time_calc(distance
=distance
, elevation
=elevation
,
177 fitness
=fitness
, rate
=travel_mode
, units
=units
)
184 print_pretty_estimate(time_estimate
)
186 print_ugly_estimate(time_estimate
)
190 if __name__
== "__main__":