Skip to content

Instantly share code, notes, and snippets.

@navid-w
Created May 8, 2021 13:35
Show Gist options
  • Save navid-w/fb7ec6c289fb6f0a917c66695f206d84 to your computer and use it in GitHub Desktop.
Save navid-w/fb7ec6c289fb6f0a917c66695f206d84 to your computer and use it in GitHub Desktop.
Evaluate expression without eval or ast
"""
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