Last active
June 16, 2017 10:26
-
-
Save quxiaowei/ad5846ec6d4a99bb1bdbf5d4a85386c3 to your computer and use it in GitHub Desktop.
A humble calculator
This file contains hidden or 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
import re | |
from copy import deepcopy | |
import operator | |
RE_NUM = re.compile('\s*([-+]?\d+(\.\d+)?)') | |
def number(word): | |
result = RE_NUM.match(word) | |
groups = result.groups() | |
num_str = result.groups[0] | |
if groups[1] is not None: | |
return float(num_str) | |
else: | |
return int(num_str) | |
class Chain: | |
_dict = { | |
'+': {'w':2, 'func': operator.add}, | |
'-': {'w':2, 'func': operator.sub}, | |
'*': {'w':4, 'func': operator.mul}, | |
'/': {'w':4, 'func': operator.truediv}, | |
'(': {'w':5, 'func': None}, | |
')': {'w':-5, 'func': None} | |
} | |
_border = {'w': -100000, 'func': None} | |
def __init__(self, raw_string): | |
self._operators = [] | |
self._num = [] | |
base = 0 | |
for i in raw_string.split(): | |
if i in set(Chain._dict.keys()): | |
if i in set('()'): | |
base = base + Chain._dict[i]['w'] | |
else: | |
oper = deepcopy(Chain._dict[i]) | |
oper['w'] += base | |
self._operators.append(oper) | |
else: | |
self._num.append(number(i)) | |
if base != 0: | |
pass #error | |
def __len__(self): | |
return len(self._operators) | |
def __getitem__(self, i): | |
if i < 0 or i >= len(self): | |
return Chain._border | |
else: | |
return self._operators[i] | |
def reduce_chain(self, i): | |
self._num[i] = \ | |
self._operators[i]['func'](self._num[i], self._num[i+1]) | |
del(self._operators[i]) | |
del(self._num[i+1]) | |
def result(self): | |
return self._num | |
i = 0 | |
raw_string = '1 + 2 + ( 2 * 3 + 1 ) * 2 + 2 * 3 + ( 1 + 2 * 8 )' | |
chain = Chain(raw_string) | |
while len(chain) != 0: | |
j = max((i, i-1, i+1), key=lambda a: chain[a]['w']) | |
if i == j: | |
chain.reduce_chain(i) | |
if i == len(chain): # not necessary but ... | |
i = i-1 | |
else: | |
i = j | |
print(chain.result()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment