Skip to content

Instantly share code, notes, and snippets.

@pbronez
Created May 22, 2016 14:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pbronez/8ba2b75c553415f762c8c17d4fc0caea to your computer and use it in GitHub Desktop.
Save pbronez/8ba2b75c553415f762c8c17d4fc0caea to your computer and use it in GitHub Desktop.
A complete Python 3 program with a command-line interface powered by docopt.
# The module docstring starts the file and defines the CLI
"""cli_calc.py
Usage:
cli_calc.py add <x> <y>
cli_calc.py subtract <x> <y>
cli_calc.py multiply <x> <y>
cli_calc.py divide <x> <y> [--integer]
Note:
To actually call this program, you need to send it to a python interpreter.
There are ways to make this automatic, allowing you to type exactly what's
listed in the "Usage" section into the command line, but that requires some
additional work. For now, just add "python" before the call.
Real Examples:
python cli_calc.py add 3 4
python cli_calc.py subtract 15 12
python cli_calc.py multiply 8 7
python cli_calc.py divide 12 5
python cli_calc.py divide 12 5 --integer
python cli_calc.py --help
Options:
-h, --help display this help message.
--integer use floor division rather than true division
"""
# Do all your imports right after the docstring
from docopt import docopt
import operator
# Now we define the top-level functions for our program.
# These should have a 1:1 correspondence to the top-level program commands
# Note that the function parameters include all the information it needs to run
def add(x, y):
"""Calculate the sum of the arguments"""
return operator.add(x, y)
def subtract(x, y):
"""Calculate the difference of the arguments"""
return operator.sub(x, y)
def multiply(x, y):
"""Calculate the product of the arguments"""
return operator.mul(x, y)
def divide(x, y, integer=False):
"""Calculate the quotient of the arguments"""
if integer:
return operator.floordiv(x, y)
else:
return operator.truediv(x, y)
# The last thing in the file is the main function. It choses which functions to
# execute, gives them the parameters they need, collects the output, and returns
# it to the user.
def main(args):
"""The main function is the master logic for the program."""
# All our functions require numeric inputs, but docopt collects arguments
# as strings. Main takes care of the transformation.
args['<x>'] = float(args['<x>'])
args['<y>'] = float(args['<y>'])
# This is the main switcher -- we look at what function the user asked for
# and run it with the provided arguments.
result = ''
if args['add']:
result = add(args['<x>'], args['<y>'])
elif args['subtract']:
result = subtract(args['<x>'], args['<y>'])
elif args['multiply']:
result = multiply(args['<x>'], args['<y>'])
elif args['divide']:
result = divide(args['<x>'], args['<y>'], integer=args['--integer'])
# Finally, we print the result to stdout using print()
print(result)
# We want the main() function to get called whenever we run this file directly.
# this basic if statement handles this task. Note that it has ZERO INTENT. That
# means the interpreter will run this code directly when it parses the file.
if __name__ == '__main__':
# First get the arguments from the command line via docopt
args = docopt(__doc__)
# Then print the arguments (now a parsed dict) to stdout for debugging
# The docopt examples typically end here because seeing the parsed arguments
# is sufficient to know what docopt is doing. They assume you know what to
# do with the arguments dict once you have it.
# See https://github.com/docopt/docopt/tree/master/examples
print(args)
# We actually want to do something with the parsed arguments, so send them
# arugments over to the main function, running the program
main(args)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment