In this Python challenge, you will attempt to a make a CLI (Command Line Interface) calculator. Basically, what that means is: a calculator that can interpret simple math equations (e.g.

2+3-5*6 => -25). It must correctly compute addition, subtraction, multiplication, and division. It sounds simple, but it can get a little complicated at times. You cannot use

eval() or anything like that, you MUST parse everything yourself.

I am really interested in what you come up with. Good luck!

151st post!

Done!

Code:

`import re`

def isMore(tokens):

for t in tokens:

if t == "*" or t == "/":

return True

return False

def lex(equation):

# remove all the whitespaces from the equation string

equation = equation.replace(" ", "")

return re.findall("[0-9]+|[\+, \-, \*, \/]", equation)

def evaluate1(tokens, isOrigin = False):

for i in range(0, len(tokens)):

if tokens[i] == "*":

a = int(tokens[i - 1]) * int(tokens[i + 1])

tokens = tokens[:i - 1]

tokens.insert(i, a)

break

elif tokens[i] == "/":

a = int(tokens[i - 1]) / int(tokens[i + 1])

tokens = tokens[:i - 1]

tokens.insert(i, a)

break

if isMore(tokens):

tokens = evaluate1(tokens)

return tokens

def evaluate2(tokens, isOrigin = False):

if tokens[1] == "+":

a = int(tokens[0]) + int(tokens[2])

tokens = tokens[3:]

tokens.insert(0, a)

elif tokens[1] == "-":

a = int(tokens[0]) - int(tokens[2])

tokens = tokens[3:]

tokens.insert(0, a)

if len(tokens) > 1:

tokens = evaluate2(tokens)

if isOrigin:

return tokens[0]

else:

return tokens

equation = raw_input("Enter an equation: ")

tokens = lex(equation)

tokens = evaluate1(tokens, isOrigin = True)

print(evaluate2(tokens, isOrigin = True))

And no, I didn't search up anything about this type of calculator for help.

Well, since my last code was just a lame hack... I re-wrote it to make it much neater and more professional.

No recursion this time... too clunky.

Code:

`import re`

def lex(equation):

# remove all the whitespaces from the equation string

equation = equation.replace(" ", "")

return re.findall("[0-9]+|[\+, \-, \*, \/]", equation)

def evalMulDiv(tokens):

i = 0

while i < len(tokens):

if tokens[i] == "*":

tokens = tokens[:i - 1] + [int(tokens[i - 1]) * int(tokens[i + 1])] + tokens[i + 2:]

i -= 2

elif tokens[i] == "/":

tokens = tokens[:i - 1] + [int(tokens[i - 1]) / int(tokens[i + 1])] + tokens[i + 2:]

i -= 2

i += 1

return tokens

def evalAddSub(tokens):

i = 0

while i < len(tokens):

if tokens[i] == "+":

tokens = tokens[:i - 1] + [int(tokens[i - 1]) + int(tokens[i + 1])] + tokens[i + 2:]

i -= 2

elif tokens[i] == "-":

tokens = tokens[:i - 1] + [int(tokens[i - 1]) - int(tokens[i + 1])] + tokens[i + 2:]

i -= 2

i += 1

return tokens

def calc(equation):

tokens = lex(equation)

tokens = evalMulDiv(tokens)

return int(evalAddSub(tokens)[0])

equation = raw_input("> ")

print(calc(equation))

@

Megan! You try!

I think I will make a guide on CLI calculators soon. (possibly non-language specific -- pseudocode)

I'm new to Python and don't really know how your script works. Mine sucks but I did my best. Don't know if this is what you were looking for or not.

Code:

`def a(n1,n2):`

return float(n1 + n2)

def s(n1,n2):

return float(n1 - n2)

def m(n1,n2):

return float(n1 * n2)

def d(n1,n2):

return float(n1 / n2)

c = raw_input("Operation? (add, sub, mult, div): ")

n1 = float(raw_input("Enter the first number: "))

n2 = float(raw_input("Enter the second number: "))

if c == "add":

print(a(n1,n2))

elif c == "sub":

print(s(n1,n2))

elif c == "mult":

print(m(n1,n2))

elif c == "div":

print(d(n1,n2))

else:

print("The operation you entered does not exist.")

(12-15-2015, 04:22 AM)meow Wrote: [ -> ]I'm new to Python and don't really know how your script works. Mine sucks but I did my best. Don't know if this is what you were looking for or not.

Code:

`def a(n1,n2):`

return float(n1 + n2)

def s(n1,n2):

return float(n1 - n2)

def m(n1,n2):

return float(n1 * n2)

def d(n1,n2):

return float(n1 / n2)

c = raw_input("Operation? (add, sub, mult, div): ")

n1 = float(raw_input("Enter the first number: "))

n2 = float(raw_input("Enter the second number: "))

if c == "add":

print(a(n1,n2))

elif c == "sub":

print(s(n1,n2))

elif c == "mult":

print(m(n1,n2))

elif c == "div":

print(d(n1,n2))

else:

print("The operation you entered does not exist.")

Well, that's not exactly what I was looking for. But it is okay; your did your best! Cool on you for learning Python though.

Basically, what I meant by a CLI calculator is that it takes a string such as "2 +8/2 * 4" and outputs the correct number (18). (note the use of

operator precedence -- I do not require parentheses though)

Thanks for trying!!!

NOTE: Windows

calc.exe doesn't even use operator precedence!?!?!

If you could explain your code that'd be cool, especially the eval functions.

Why tokens?

J:

Python (supports addition, subtraction, multiplication, division, exponents, and modulus):

Code:

`import re`

import operator as op

ops={'+': op.add,'-': op.sub,'*': op.mul,'/': op.div,'^': op.pow,'%': op.mod}

while 1:

e=raw_input('} ')

for i in re.finditer('[\+,\-,\*,\/,\^,\%]',e): print ops[i.group()](int(e[:i.start()]),int(e[i.start()+1:]))

(12-16-2015, 03:30 PM)Nevermore Wrote: [ -> ]J:

Python (supports addition, subtraction, multiplication, division, exponents, and modulus):

Code:

`import re`

import operator as op

ops={'+': op.add,'-': op.sub,'*': op.mul,'/': op.div,'^': op.pow,'%': op.mod}

while 1:

e=raw_input('} ')

for i in re.finditer('[\+,\-,\*,\/,\^,\%]',e): print ops[i.group()](int(e[:i.start()]),int(e[i.start()+1:]))

Cool! Really compact code.

But.. your code can only do one operation per input. (you can't do "5+5*5" or "4*3-2*3")

You should be able to do an equation of arbitrary length.

(12-16-2015, 03:51 PM)m0dem Wrote: [ -> ]Cool! Really compact code.

But.. your code can only do one operation per input. (you can't do "5+5*5" or "4*3-2*3")

You should be able to do an equation of arbitrary length.

I just got bored in history, I'll take it seriously and finish it later.