Example usage:
$ python arith.py 1 + 1
2
$ python arith.py 3 x 4
12
$ python arith.py 5 + 4 x 3
17
$ python arith.py 4 / 2
2
$ python arith.py 4 / 3 + 6 x 3
19.333333333333332
| #!/usr/bin/env python3 | |
| import re | |
| import sys | |
| def divide_args(a, b): | |
| if b == 0: | |
| raise ZeroDivisionError('cannot divide by zero') | |
| r = a / b | |
| if isinstance(r, float) and r.is_integer(): | |
| r = int(r) | |
| return r | |
| def find_operator(args, ops='all'): | |
| if ops == 'all': | |
| index, op = find_operator(args, 'x/') | |
| if not index: | |
| index, op = find_operator(args, '+-') | |
| return (index, op) | |
| for i, arg in enumerate(args): | |
| if isinstance(arg, str) and arg in ops: | |
| return (i, arg) | |
| return (False, False) | |
| def parse_arg(arg): | |
| if not isinstance(arg, str): | |
| return arg | |
| if re.fullmatch('\d+', arg): | |
| return int(arg) | |
| elif re.fullmatch('\d+.\d*', arg): | |
| return float(arg) | |
| raise 'invalid argument' | |
| try: | |
| arguments = list(sys.argv) | |
| arguments.pop(0) | |
| while True: | |
| index, op = find_operator(arguments) | |
| if not index: | |
| break | |
| arguments.pop(index) | |
| arg1 = parse_arg(arguments.pop(index - 1)) | |
| arg2 = parse_arg(arguments.pop(index - 1)) | |
| result = { | |
| '+': lambda a, b: a + b, | |
| '-': lambda a, b: a - b, | |
| 'x': lambda a, b: a * b, | |
| '/': divide_args | |
| }[op](arg1, arg2) | |
| arguments.insert(index - 1, result) | |
| if len(arguments) == 1: | |
| print(arguments[0]) | |
| else: | |
| print('error') | |
| print(arguments) | |
| except ZeroDivisionError as err: | |
| print(err) |