Touch-up header and fix an alignment issue
[munter.git] / munter.py
index b7a7f725b44882531f1245df49ca00304a071dfe..fd5e48509b9a79d3f5ca20b30eb843a92a781c32 100755 (executable)
--- a/munter.py
+++ b/munter.py
@@ -1,8 +1,16 @@
 #! /usr/bin/env python
+# -*- coding: utf-8 -*-
 
-# Munter Time Calculation
-#
-# Rudimentary program written by ALV to implement the Munter time calculation
+
+"""
+Munter Time Calculation
+Alexander Vasarab
+Wylark Mountaineering LLC
+
+Version 1.0.2
+
+A rudimentary program which implements the Munter time calculation.
+"""
 
 import sys
 import argparse
@@ -11,42 +19,59 @@ class InvalidUnitsException(Exception):
     pass
 
 rates = {
-    'uphill': 4,
-    'flat': 6, # or downhill on foot
-    'downhill': 10,
-    'bushwhacking': 2
+    'uphill': { 'rate': 4, 'direction': '↑' },
+    'flat': { 'rate': 6, 'direction': '→' }, # or downhill on foot
+    'downhill': { 'rate': 10, 'direction': '↓' },
+    'bushwhacking': { 'rate': 2, 'direction': '↹' },
 }
 
 unit_choices = ['metric', 'imperial']
 travel_mode_choices = rates.keys()
 
-def munter(distance, elevation, rate='flat', units='metric'):
+def munter(distance, elevation, rate, units):
+    retval = {}
+
     if units not in unit_choices:
         raise InvalidUnitsException
 
+    unit_count = 0
+
     if 'imperial' == units:
         # convert to metric
         distance = (distance * 1.609) # mi to km
         elevation = (elevation * .305) # ft to m
 
-    time = (distance + (elevation / 100.0)) / rates[rate]
+    unit_count = distance + (elevation / 100.0)
+
+    retval['time'] = (distance + (elevation / 100.0)) / rates[rate]['rate']
+    retval['unit_count'] = unit_count
+    retval['direction'] = rates[rate]['direction']
+    retval['pace'] = rates[rate]['rate']
 
-    return time
+    return retval
 
 def main():
     parser = argparse.ArgumentParser(description='Munter Time Calculation')
 
-    parser.add_argument('--distance', '-d', type=float, required=True,
+    parser.add_argument('--distance', '-d', type=float,
+        required=True,
         help='Distance (in km, by default)')
-    parser.add_argument('--elevation', '-e', type=float, required=True,
+
+    parser.add_argument('--elevation', '-e', type=float,
+        required=True,
         help='Elevation change (in m, by default)')
+
     parser.add_argument('--travel-mode', '-t', type=str,
-        default='uphill', choices=travel_mode_choices, required=False,
+        default='uphill',
+        choices=travel_mode_choices, required=False,
         help='Travel mode (flat, by default)')
-    parser.add_argument('--units', '-u', type=str, default='metric',
+
+    parser.add_argument('--units', '-u', type=str,
+        default='imperial',
         required=False,
         choices=unit_choices,
         help='Units of input values')
+
     opts = parser.parse_args()
 
     distance = opts.distance
@@ -54,8 +79,30 @@ def main():
     units = opts.units
     travel_mode = opts.travel_mode
 
-    print("Estimated Time (in hours) = %8.2f"
-        % munter(distance, elevation, travel_mode, units=units))
+    time_calc = munter(distance, elevation, travel_mode, units=units)
+
+    hours = int(time_calc['time'])
+    minutes = int((time_calc['time'] - hours) * 60)
+
+    # NOTE: Below, the line with the unicode up arrow uses an alignment
+    #       value of 31. In the future, consider using e.g. wcwidth
+    #       library so that this is more elegant.
+    print("\n\t╒═══════════════════════════════╕")
+    print("\t╎▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒╎╮")
+    print("\t╎▒{:^29}▒╎│".format(''))
+    print("\t╎▒{pace_readable:^31}▒╎│".format(
+            pace_readable="{units} {direction} @ {pace}".format(
+                units=round(time_calc['unit_count']),
+                direction=time_calc['direction'],
+                pace=time_calc['pace'])))
+    print("\t╎▒{human_time:^29}▒╎│".format(
+            human_time="{hours} hours {minutes} minutes".format(
+                hours=hours,
+                minutes=minutes)))
+    print("\t╎▒{:^29}▒╎│".format(''))
+    print("\t╎▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒╎│")
+    print("\t╘═══════════════════════════════╛│")
+    print("\t └───────────────────────────────┘\n")
 
 if __name__ == "__main__":
     main()