Created
May 22, 2016 14:45
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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