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) |