d235866c2e10e5ed2b32d69d848fabc25d8cdf8f
1 # -*- coding: utf-8 -*-
5 Munter Time Calculation
7 Wylark Mountaineering LLC
9 A rudimentary program which implements the Munter time calculation.
15 class InvalidUnitsException(Exception):
19 'uphill': { 'rate': 4, 'direction': '↑' },
20 'flat': { 'rate': 6, 'direction': '→' }, # or downhill on foot
21 'downhill': { 'rate': 10, 'direction': '↓' },
22 'bushwhacking': { 'rate': 2, 'direction': '↹' },
31 unit_choices
= ['metric', 'imperial']
32 travel_mode_choices
= rates
.keys()
33 fitness_choices
= fitnesses
.keys()
35 def time_calc(distance
, elevation
, fitness
='average', rate
='uphill',
39 if units
not in unit_choices
:
40 raise InvalidUnitsException
44 if 'imperial' == units
:
46 distance
= (distance
* 1.609) # mi to km
47 elevation
= (elevation
* .305) # ft to m
49 unit_count
= distance
+ (elevation
/ 100.0)
51 retval
['time'] = (distance
+ (elevation
/ 100.0)) / rates
[rate
]['rate']
52 retval
['time'] = retval
['time'] * fitnesses
[fitness
]
54 retval
['unit_count'] = unit_count
55 retval
['direction'] = rates
[rate
]['direction']
56 retval
['pace'] = rates
[rate
]['rate']
60 def print_ugly_estimate(est
):
61 hours
= int(est
['time'])
62 minutes
= int((est
['time'] - hours
) * 60)
63 print("{human_time}".format(
64 human_time
="{hours} hours {minutes} minutes".format(
68 def print_pretty_estimate(est
):
69 hours
= int(est
['time'])
70 minutes
= int((est
['time'] - hours
) * 60)
72 # NOTE: Below, the line with the unicode up arrow uses an alignment
73 # value of 31. In the future, consider using e.g. wcwidth
74 # library so that this is more elegant.
75 print("\n\t╒═══════════════════════════════╕")
76 print("\t╎▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒╎╮")
77 print("\t╎▒{:^29}▒╎│".format(''))
78 print("\t╎▒{pace_readable:^31}▒╎│".format(
79 pace_readable
="{units} {direction} @ {pace}".format(
80 units
=round(est
['unit_count']),
81 direction
=est
['direction'],
83 print("\t╎▒{human_time:^29}▒╎│".format(
84 human_time
="{hours} hours {minutes} minutes".format(
87 print("\t╎▒{:^29}▒╎│".format(''))
88 print("\t╎▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒╎│")
89 print("\t╘═══════════════════════════════╛│")
90 print("\t └───────────────────────────────┘\n")
93 parser
= argparse
.ArgumentParser(description
='Implementation of '
94 'the Munter time calculation')
96 parser
.add_argument('--distance',
100 help='Distance (in km, by default)')
102 parser
.add_argument('--elevation',
106 help='Elevation change (in m, by default)')
108 parser
.add_argument('--travel-mode',
112 choices
=travel_mode_choices
, required
=False,
113 help='Travel mode (uphill, by default)')
115 parser
.add_argument('--fitness',
119 choices
=fitness_choices
, required
=False,
120 help='Fitness modifier (average, by default)')
122 parser
.add_argument('--units',
127 choices
=unit_choices
,
128 help='Units of input values')
130 parser
.add_argument('--pretty',
135 help="Make output pretty");
137 parser
.add_argument('--gui',
142 help='Launch GUI mode (overrides --pretty)')
147 parser
= get_parser()
148 opts
= parser
.parse_args()
150 distance
= opts
.distance
151 elevation
= opts
.elevation
152 fitness
= opts
.fitness
154 travel_mode
= opts
.travel_mode
158 time_estimate
= time_calc(distance
=distance
, elevation
=elevation
,
159 fitness
=fitness
, rate
=travel_mode
, units
=units
)
166 print_pretty_estimate(time_estimate
)
168 print_ugly_estimate(time_estimate
)
172 if __name__
== "__main__":