-1

I'm trying to write a calculator program in Python. I have pretty much everything else figured out, except how to "finish" the calculation after I have every command in a list.

Is there any way to be able to calculate the value this list would have if written directly to the python console (as in 23*2+(5-2)).

Example:

list = ['23', '*', '2', '+' '(', '5', '-', '2', ')'] 

and I would like for it to be handled as in the calculation above (23*2+(5-2)). Preferably without use of any libraries. Tried looking from everywhere, but couldn't find an answer. Neither could I think of one myself.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • You are looking for [`eval`](https://docs.python.org/2/library/functions.html#eval), but you will need to turn the list into a string. – jonrsharpe Jun 06 '14 at 12:53
  • 1
    The [Shunting-yard algorithm](http://en.wikipedia.org/wiki/Shunting-yard_algorithm) may be useful to you. – Kevin Jun 06 '14 at 12:53
  • Well, you could `join` and `eval`uate the terms, but it would be much more fun to do it manually, I guess. – tobias_k Jun 06 '14 at 12:54
  • "I have pretty much everything else figured out, except how to "finish" the calculation" -- You do not seem to appreciate what a complex task expression parsing is! So, like the others point out, use the parsing force of Python's interpreter and use `eval` (which would be cheating if that is an exercise in my opinion) or get your hands dirty an dig into the parsing topic yourself. You will soon realize that what you have so far is only 1 % of the entire project :) – Dr. Jan-Philip Gehrcke Jun 06 '14 at 12:56

4 Answers4

0

One way is to use the eval function like so

>>> a = ['23', '*', '2', '+' '(', '5', '-', '2', ')'] 
>>> eval(''.join(a))
49

This works because you can join the list to form a valid mathematical expression that eval can handle.

Be aware that this brings possible risks if you are working with dynamic input because eval can also do stuff that can potentially harm your system, like delete files.

Tim
  • 41,901
  • 18
  • 127
  • 145
0

You could use the eval function, however this is considered bad practice. Instead, think about implementing an algorithm (like the one @Kevin suggested in the comments) to parse the expression.

Community
  • 1
  • 1
BeetDemGuise
  • 954
  • 7
  • 11
0

I see two ways: 1. Evil: Use the eval function. 2. Proper: Build a CalculatorTree class. Add rules for the precedence of operators to it. Add each string of the list to the tree and let it evaluate the expression.

timgeb
  • 76,762
  • 20
  • 123
  • 145
0

If you are married to the idea of pushing values into a list and evaluating the list there is a fairly easy way to do this.

# Here's your list
a = ['23', '*', '2', '+' '(', '5', '-', '2', ')'] 

# Let's turn that list into a string
b=" ".join(a)

# Let's see what it looks like
print b 
>>>'23 * 2 +( 5 - 2 )'

# Let's evaluate it
c = eval(b)

# is it right?
print c
>>>49

Now there are some issues here right? And that's why I would say that most calculator programs don't function in this way. What if I enter in a super long string of things into my list that don't work?

a = ['22', '23', '+', '46']

Doing the process above will fail because what does 22 23 + 46 even mean right? Most simple calculator apps do something to validate input. My first recommendation would be to start with a reverse polish notation calculator. Here you would input something like:

34 26 +

And this might seem weird but from a programming perspective it's actually a bit easier(namely because you can implement order of operations without parens. You might also try to validate input to the calculator as it is coming in. if a user enters 2 numbers in a row, what should happen? if a user forgets a closed parenthesis what should happen? It's not enough in an app like this to give the correct answer when the input is perfect, rather it's important to fail gracefully and make sure minor errors don't make the user unhappy.

I think it's also valuable to consider if it's worth keeping the entire function around in a list. What if I have a 300 number function that was input and I made a mistake in the first number? What if somehow you end up with a several thousand number function? (Unlikely but worth considering as a mental exercise.) Is it worth keeping around:

(1 + 1) + (1 + 1) + (1 + 1) .......... 

When you could be evaluating as the data is input?

Nahkki
  • 862
  • 8
  • 17