Skip to content

Instantly share code, notes, and snippets.

@Caster
Created March 24, 2021 11:51
Show Gist options
  • Save Caster/8077200887609cc52052350b868e543e to your computer and use it in GitHub Desktop.
Save Caster/8077200887609cc52052350b868e543e to your computer and use it in GitHub Desktop.
A simple calculator (SCW TU/e March 2021)

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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment