--- /dev/null
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# Distribution / packaging
+build/
+dist/
+wheels/
+*.egg-info/
+*.egg
+MANIFEST
+
+# Environments
+env/
+venv/
+++ /dev/null
-=========
-Munter.py
-=========
-
-Helps you speed up your tour and trip planning.
-
-Disclaimer
-==========
-
-The time calculations produced by this program are not guaranteed to be
-accurate. Any harm or hazard encountered due to blindly trusting these
-estimates is your own fault.
-
-Installation
-============
-
-There is no installation and there are no dependencies external to the Python
-standard library.
-
-How to use it
-=============
-
-./munter.py --help
-
-My workflow involves planning my tour using tools like ArcGIS or CalTopo. Then,
-I take the stats between each leg (distance, vertical gain/loss) of the tour
-and run them through Munter.py and thence record its output to my field
-notebook.
-
-The rudimentary "GUI" can be directly transferred to e.g. the format used by
-SnowPit Technologies' "Avalanche Field Notebook" or your own personal format
-(e.g. RitR No. 471).
-
-Future plans
-============
-
-* Personal "fitness" switch (to help fine tune your estimates based on
- your personal fitness level as observed
- over time)
-* GTK mode
-* Use as a Python library from within another project
-* Lint it (e.g. therapist)
-* Pip?
-
-Version History
-===============
-
-1.0.2 (Jun 2020)
- * A few small bugfixes.
-
-1.0.1 (Jun 2020)
- * Add LICENSE and README.
-
-1.0.0 (Jun 2020)
- * First released version. Includes sensible defaults and a rudimentary CLI
- "GUI".
-
-pre-1.0.0 (Mar 2017)
- * In use privately/internally since 2017.
--- /dev/null
+Munter.py
+=========
+
+Helps you speed up your tour and trip planning.
+
+Disclaimer
+----------
+
+The time calculations produced by this program are not guaranteed to be
+accurate. Any harm or hazard encountered due to blindly trusting these
+estimates is your own fault.
+
+Installation
+------------
+
+There is no installation and there are no dependencies external to the Python
+standard library.
+
+How to use it
+-------------
+
+`./munter.py --help`
+
+My workflow involves planning my tour using tools like ArcGIS or CalTopo. Then,
+I take the stats between each leg (distance, vertical gain/loss) of the tour
+and run them through Munter.py and thence record its output to my field
+notebook.
+
+The rudimentary "GUI" can be directly transferred to e.g. the format used by
+SnowPit Technologies' "Avalanche Field Notebook" or your own personal format
+(e.g. RitR No. 471).
+
+Future plans
+------------
+
+* Personal "fitness" switch (to help fine tune your estimates based on
+ your personal fitness level as observed
+ over time)
+* GTK mode
+* Use as a Python library from within another project
+* Lint it (e.g. therapist)
+* Pip?
+* Sphinx/autodoc?
+
+Version History
+---------------
+
+- 2.0.0 (Jun 2020)
+
+ Packaged for distribution as a standalone program (and library).
+
+- 1.0.2 (Jun 2020)
+
+ A few small bugfixes.
+
+- 1.0.1 (Jun 2020)
+
+ Add LICENSE and README.
+
+- 1.0.0 (Jun 2020)
+
+ First released version. Includes sensible defaults and a rudimentary CLI
+ "GUI".
+
+- pre-1.0.0 (Mar 2017)
+
+ In use privately/internally since 2017.
#! /usr/bin/env python
# -*- coding: utf-8 -*-
-
-"""
-Munter Time Calculation
-Alexander Vasarab
-Wylark Mountaineering LLC
-
-Version 1.0.2
-
-A rudimentary program which implements the Munter time calculation.
-"""
-
+"""Wrapper for running directly from the source code directory"""
import sys
-import argparse
-
-class InvalidUnitsException(Exception):
- pass
-
-rates = {
- '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 time_calc(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
-
- 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 retval
-
-def print_ugly_estimate(est):
- hours = int(est['time'])
- minutes = int((est['time'] - hours) * 60)
- print("{human_time}".format(
- human_time="{hours} hours {minutes} minutes".format(
- hours=hours,
- minutes=minutes)))
-
-def print_pretty_estimate(est):
- hours = int(est['time'])
- minutes = int((est['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(est['unit_count']),
- direction=est['direction'],
- pace=est['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")
-
-def get_parser():
- parser = argparse.ArgumentParser(description='Munter Time Calculation')
-
- parser.add_argument('--distance',
- '-d',
- type=float,
- required=True,
- help='Distance (in km, by default)')
-
- 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,
- help='Travel mode (flat, by default)')
-
- parser.add_argument('--units',
- '-u',
- type=str,
- default='imperial',
- required=False,
- choices=unit_choices,
- help='Units of input values')
-
- parser.add_argument('--pretty',
- '-p',
- action='store_true',
- default=False,
- required=False);
-
- return parser
-
-def main():
- parser = get_parser()
- opts = parser.parse_args()
-
- distance = opts.distance
- elevation = opts.elevation
- units = opts.units
- travel_mode = opts.travel_mode
-
- time_estimate = time_calc(distance, elevation, travel_mode, units=units)
-
- if opts.pretty:
- print_pretty_estimate(time_estimate)
- else:
- print_ugly_estimate(time_estimate)
-
- return 0
+from munter.munter import main
if __name__ == "__main__":
sys.exit(main())
--- /dev/null
+"""Main package for Munter.py"""
+__version__ = "2.0.0"
+from .munter import time_calc
--- /dev/null
+# -*- coding: utf-8 -*-
+
+"""entry point for program and library"""
+
+from .munter import main
+main()
+
--- /dev/null
+# -*- coding: utf-8 -*-
+
+
+"""
+Munter Time Calculation
+Alexander Vasarab
+Wylark Mountaineering LLC
+
+A rudimentary program which implements the Munter time calculation.
+"""
+
+import sys
+import argparse
+
+class InvalidUnitsException(Exception):
+ pass
+
+rates = {
+ '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 time_calc(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
+
+ 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 retval
+
+def print_ugly_estimate(est):
+ hours = int(est['time'])
+ minutes = int((est['time'] - hours) * 60)
+ print("{human_time}".format(
+ human_time="{hours} hours {minutes} minutes".format(
+ hours=hours,
+ minutes=minutes)))
+
+def print_pretty_estimate(est):
+ hours = int(est['time'])
+ minutes = int((est['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(est['unit_count']),
+ direction=est['direction'],
+ pace=est['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")
+
+def get_parser():
+ parser = argparse.ArgumentParser(description='Munter Time Calculation')
+
+ parser.add_argument('--distance',
+ '-d',
+ type=float,
+ required=True,
+ help='Distance (in km, by default)')
+
+ 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,
+ help='Travel mode (flat, by default)')
+
+ parser.add_argument('--units',
+ '-u',
+ type=str,
+ default='imperial',
+ required=False,
+ choices=unit_choices,
+ help='Units of input values')
+
+ parser.add_argument('--pretty',
+ '-p',
+ action='store_true',
+ default=False,
+ required=False);
+
+ return parser
+
+def main():
+ parser = get_parser()
+ opts = parser.parse_args()
+
+ distance = opts.distance
+ elevation = opts.elevation
+ units = opts.units
+ travel_mode = opts.travel_mode
+
+ time_estimate = time_calc(distance, elevation, travel_mode, units=units)
+
+ if opts.pretty:
+ print_pretty_estimate(time_estimate)
+ else:
+ print_ugly_estimate(time_estimate)
+
+ return 0
+
+if __name__ == "__main__":
+ sys.exit(main())
--- /dev/null
+#!/usr/bin/env python
+"""munter.py distutils configuration."""
+import os
+import re
+from setuptools import setup
+
+cur_dir = os.path.dirname(__file__)
+version = re.search(
+ '^__version__\s*=\s*"(.*)"',
+ open(os.path.join(cur_dir, 'munter/__init__.py')).read(),
+ re.M
+ ).group(1)
+
+with open(os.path.join(cur_dir, 'README.md'), encoding='utf-8') as readme_file:
+ readme = readme_file.read()
+
+setup(
+ name='munter.py',
+ version=version,
+ description=(
+ 'An easy-to-use implementation of the Munter time calculation'
+ ),
+ long_description=readme,
+ long_description_content_type='text/markdown',
+ author='Alexander Vasarab',
+ author_email='alexander@wylark.com',
+ url='https://wylark.com/munter',
+ packages=['munter'],
+ package_dir={'munter': 'munter'},
+ entry_points={'console_scripts': ['munter = munter.munter:main']},
+ include_package_data=True,
+ python_requires='>=3.6',
+ license='ISC',
+ classifiers=[
+ "Development Status :: 5 - Production/Stable",
+ "Environment :: Console",
+ "Intended Audience :: Other Audience",
+ "Intended Audience :: Developers",
+ "Natural Language :: English",
+ "License :: OSI Approved :: ISC License (ISCL)",
+ "Programming Language :: Python :: 3 :: Only",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
+ "Programming Language :: Python",
+ "Topic :: Software Development",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+ ],
+ keywords=[
+ "munter",
+ "tour planning",
+ "trip planning",
+ "time estimate",
+ ],
+)
--- /dev/null
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+import munter
+
+est = munter.time_calc(3.2, 2300, 'uphill', 'imperial')
+print("Time Estimate: %s hours" % est['time'])