Evaluate Expressions Using Stacks

Table Of Contents

Project Description

Write a program to evaluate numeric expressions using stacks.

  1. Ask the user to input a mathematical expression.
  2. Calculate the expression's results.
  3. Display the results or an error message.
  4. Loop

The initial project should:

Note: In general, a stack is LIFO (Last In First Out). A queue is FIFO (First In First Out).

Limit Project

Limit the project to int and float numbers. No scientific notation, trigonometric functions, etc.

Limit operators to '-', '+', '/', '*', '%', and '**' to start with. Add '(' and ')' later.

Allow unary operators '-' and '+', and sub-expressions '()'.

Links

Using a Stack to Evaluate an Expression
Expression Evaluation
Using stacks: parsing of arithmetic expressions (pdf)

Deque

Use deque from the collections or queue Python modules. It can be used to implement stacks and queues. For example, to use deque:

#!/usr/bin/python3

from collections import deque 
stack = deque()

   or

from queue import deque
stack = deque()

collections.deque and queue.deque are the same and have the same interface.

The queue module also implements mult-producer, multi consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads. The queue.Queue class implements all of the locking semantics. It has methods like put_nowait(), get_nowait(), and join(), whereas collections.deque does not. collections.deque is simply intended as a data structure.

Sample of Expressions to Evaluate

ExpressionValueExpressionValue
1 + 2 - 30(-10 + 2) * 3-24
1 + 2 * 37(-10 + 2) * -324
(1 + 2) * 39-((2 * 3) - (4 - 8 * 2))-18
-10 + 2 * 3-4-((2 * 3) - (4 * 8 - 2))24
-10 + (2 * 3)-42**3 - 4 * 20

Operator Precedence

Operator precedence from the Python documentation.
(There are other operators in Python, but only these
mathematical operators are used by this project.)

Highest precedence at top, lowest at bottom.
Operators in the same box evaluate left to right.
OperatorDescription
( )Parenthesis (sub-expression)
**Exponentiation
+X, -XUnary operator1 (Positive, Negative)
*, /, %Multiplication, division, remainder
+, -Addition, Subtraction
1A unary operator is one that takes a single operand/argument and performs an operation.

Sample Program Demonstrating Deque and Program Results

#! /usr/bin/python3

from collections import deque

## ---- if you want to use the queue module
## ---- from queue import deque

lst = [ 'a', 'b', 'c' ]

stack = deque()

## ---- you can feed the complete list directly to deque
## ---- stack = deque(lst)

print()
print('--------------------------------------------')
print('---- LIFO (Last In First Out) --------------')
print('--------------------------------------------')
print(f'List: {lst}')
print()
stacka = deque()
for x in lst:
    print(f'stacka.appendleft {x}')
    stacka.appendleft(x)
print('--------------------------------------------')
for i in range(len(stacka)):
    print(f'stacka [{i}] {stacka[i]}')
print('--------------------------------------------')
while len(stacka) > 0:
    x = stacka.popleft()
    print(f'stacka.popleft {x}')
print()

print('--------------------------------------------')
print('---- LIFO (Last In First Out) --------------')
print('--------------------------------------------')
print(f'List: {lst}')
print()
stackb = deque()
for x in lst:
    print(f'stackb.append {x}')
    stackb.append(x)
print('--------------------------------------------')
for i in range(len(stackb)):
    print(f'stackb [{i}] {stackb[i]}')
print('--------------------------------------------')
while len(stackb) > 0:
    x = stackb.pop()
    print(f'stackb.pop {x}')
print()

print('--------------------------------------------')
print('---- FIFO (First In First Out) -------------')
print('--------------------------------------------')
print(f'List: {lst}')
print()
stackc = deque()
for x in lst:
    print(f'stackc.append {x}')
    stackc.append(x)
print('--------------------------------------------')
for i in range(len(stackc)):
    print(f'stackc [{i}] {stackc[i]}')
print('--------------------------------------------')
while len(stackc) > 0:
    x = stackc.popleft()
    print(f'stackc.popleft {x}')
print()

print('--------------------------------------------')
print('---- FIFO (First In First Out) -------------')
print('--------------------------------------------')
print(f'List: {lst}')
print()
stackd = deque()
for x in lst:
    print(f'stackd.appendleft {x}')
    stackd.appendleft(x)
print('--------------------------------------------')
for i in range(len(stackd)):
    print(f'stackd [{i}] {stackd[i]}')
print('--------------------------------------------')
while len(stackd) > 0:
    x = stackd.pop()
    print(f'stackd.pop {x}')
print()
--------------------------------------
---- LIFO (Last In First Out) --------
--------------------------------------
List: ['a', 'b', 'c']

stacka.appendleft a
stacka.appendleft b
stacka.appendleft c
--------------------------------------
stacka [0] c
stacka [1] b
stacka [2] a
--------------------------------------
stacka.popleft c
stacka.popleft b
stacka.popleft a

--------------------------------------
---- LIFO (Last In First Out) --------
--------------------------------------
List: ['a', 'b', 'c']

stackb.append a
stackb.append b
stackb.append c
--------------------------------------
stackb [0] a
stackb [1] b
stackb [2] c
--------------------------------------
stackb.pop c
stackb.pop b
stackb.pop a

--------------------------------------
---- FIFO (First In First Out) -------
--------------------------------------
List: ['a', 'b', 'c']

stackc.append a
stackc.append b
stackc.append c
--------------------------------------
stackc [0] a
stackc [1] b
stackc [2] c
--------------------------------------
stackc.popleft a
stackc.popleft b
stackc.popleft c

--------------------------------------
---- FIFO (First In First Out) -------
--------------------------------------
List: ['a', 'b', 'c']

stackd.appendleft a
stackd.appendleft b
stackd.appendleft c
--------------------------------------
stackd [0] c
stackd [1] b
stackd [2] a
--------------------------------------
stackd.pop a
stackd.pop b
stackd.pop c

Expand Project

1. Add float and scientific notation.

2. Convert to using a GUI.

3. Redo the project using recursion.

4. Add complex number calculations?