Table Of Contents
Write a program to evaluate numeric expressions using stacks.
The initial project should:
Note: In general, a stack is LIFO (Last In First Out). A queue is FIFO (First In First Out).
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 '()'.
Using a Stack to Evaluate an Expression
Expression Evaluation
Using stacks: parsing of arithmetic expressions (pdf)
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.
Expression | Value | Expression | Value |
---|---|---|---|
1 + 2 - 3 | 0 | (-10 + 2) * 3 | -24 |
1 + 2 * 3 | 7 | (-10 + 2) * -3 | 24 |
(1 + 2) * 3 | 9 | -((2 * 3) - (4 - 8 * 2)) | -18 |
-10 + 2 * 3 | -4 | -((2 * 3) - (4 * 8 - 2)) | 24 |
-10 + (2 * 3) | -4 | 2**3 - 4 * 2 | 0 |
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. | |
---|---|
Operator | Description |
( ) | Parenthesis (sub-expression) |
** | Exponentiation |
+X, -X | Unary operator1 (Positive, Negative) |
*, /, % | Multiplication, division, remainder |
+, - | Addition, Subtraction |
#! /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
1. Add float and scientific notation.
2. Convert to using a GUI.
3. Redo the project using recursion.
4. Add complex number calculations?