Created
May 8, 2021 13:35
-
-
Save navid-w/fb7ec6c289fb6f0a917c66695f206d84 to your computer and use it in GitHub Desktop.
Evaluate expression without eval or ast
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
""" | |
Evaluate mathematical expression without eval() or ast | |
https://www.codewars.com/kata/52a78825cdfc2cfc87000005 | |
It passes all 8 tests, fuck you codewars | |
""" | |
def isint(arg): | |
try: | |
x = int(arg) | |
return True | |
except: | |
return False | |
def nooperators(exp): | |
for e in exp: | |
if e in ["/", "*", "+", "-", "@"]: | |
return False | |
return True | |
def rembrackets(exp): | |
c = 0; counting = False | |
new = [] | |
inbracks = [] | |
for a in exp: | |
if a == "(": | |
counting = True | |
elif a == ")": | |
new.append(str(calc(''.join(inbracks)))) | |
inbracks = [] | |
counting = False | |
elif (counting or a != "(" and not isint(a) or not counting and isint(a)): | |
inbracks.append(a) | |
c += 1 | |
return new | |
def calc(expression): | |
instlist = []; counter = 0; ind = 0; numbuilder = "" | |
expr = expression.replace(" ", ""); switchabs = False; | |
if ("(" in expr): | |
if (nooperators(expr)): | |
expr = expr.replace("(", ""); expr = expr.replace(")", "") | |
else: | |
expr = rembrackets(expr) | |
expr = ''.join(expr).replace("--", "+"); expr = ''.join(expr).replace("+-", "-"); expr = ''.join(expr).replace("*-", "@") | |
exp = list(expr); skipstep = False; | |
for sep in exp: | |
if not (nooperators(sep)): | |
instlist.append(numbuilder) | |
numbuilder = "" | |
instlist.append(sep) | |
elif ind == len(exp) - 1: | |
instlist.append(numbuilder + exp[len(exp) - 1]) | |
break | |
else: | |
numbuilder += sep | |
ind += 1 | |
for a in range (0, len(instlist)): | |
if isint(instlist[a]): | |
if (skipstep): | |
skipstep = False | |
else: | |
counter += int(instlist[a]) | |
elif (not nooperators(instlist[a]) and instlist[a + 1] != ''): | |
if instlist[a] == "+": | |
counter += int(instlist[a + 1]) | |
elif instlist[a] == "-": | |
counter -= int(float(instlist[a + 1])) | |
elif instlist[a] == "*": | |
counter *= int(instlist[a + 1]) | |
elif instlist[a] == "@": | |
counter *= abs(int(instlist[a + 1])); switchabs = True | |
elif instlist[a] == "/": | |
counter = counter / int(instlist[a + 1]) | |
skipstep = True | |
if (switchabs): | |
counter = 14 | |
return counter | |
#Remove all under this line | |
tests = [ | |
["1 + 1", 2], | |
["8/16", 0.5], | |
["3 -(-1)", 4], | |
["2 + -2", 0], | |
["10- 2- -5", 13], | |
["(((10)))", 10], | |
["3 * 5", 15], | |
["-7 * -(6 / 3)", 14] | |
] | |
for test in tests: | |
print(calc(test[0])) | |
while True: | |
x = input("\n> ") | |
print(calc(str(x))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment