chevron_left chevron_right
Login Register invert_colors photo_library




Bronze Challenge (1) CLI Calculator filter_list
Author
Message
Challenge (1) CLI Calculator #1
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! Wink
151st post! Biggrin

Reply

RE: Challenge (1) CLI Calculator #2
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.

[+] 1 user Likes m0dem's post
Reply

RE: Challenge (1) CLI Calculator #3
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! Smile
I think I will make a guide on CLI calculators soon. (possibly non-language specific -- pseudocode)

Reply

RE: Challenge (1) CLI Calculator #4
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.")

Reply

RE: Challenge (1) CLI Calculator #5
(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. Smile
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!!! Wink

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

Reply

RE: Challenge (1) CLI Calculator #6
If you could explain your code that'd be cool, especially the eval functions.

Why tokens?

Reply

RE: Challenge (1) CLI Calculator #7
(12-15-2015, 08:55 AM)God Wrote: If you could explain your code that'd be cool, especially the eval functions.

Why tokens?

Ok, I will make a separate guide on this.
Be looking for it. Smile

I've finished!
https://www.sinister.ly/Thread-Tutorial-...ator-Works
Enjoy! Wink
(This post was last modified: 12-15-2015, 03:20 PM by m0dem.)

Reply

RE: Challenge (1) CLI Calculator #8
J:
Code:
".;2}input

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:]))
It's often the outcasts, the iconoclasts ... those who have the least to lose because they
don't have much in the first place, who feel the new currents and ride them the farthest.

Reply

RE: Challenge (1) CLI Calculator #9
(12-16-2015, 03:30 PM)Nevermore Wrote: J:
Code:
".;2}input

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.

Reply

RE: Challenge (1) CLI Calculator #10
(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.
It's often the outcasts, the iconoclasts ... those who have the least to lose because they
don't have much in the first place, who feel the new currents and ride them the farthest.

Reply






Users browsing this thread: 1 Guest(s)