If I push a character to the Stack and peek at it, it gives me different characters even when no interaction was made after the push.
The relevant class and functions look like this:
class Stack:
def __init__(self):
self.data = []
self.top = -1
self.max = 10
def isFull(self):
if self.top == (self.max-1):
return True
else:
return False
def isEmpty(self):
if self.top == -1:
return True
else:
return False
def push(self, input):
if self.isFull():
print(f"Push({input}) : Stack is full")
else:
self.top += 1
self.data.append(input)
def pop(self):
if self.isEmpty():
print("Pop : Stack is empty")
else:
temp = self.data[self.top]
self.top -= 1
return temp
def peek(self):
if self.isEmpty():
print("Peek : Stack is empty")
else:
return self.data[self.top]
def printStack(self):
if self.isEmpty():
print("Print : Stack is empty")
else:
print("Stack : ", end="")
for i in range(0,self.top+1):
print(self.data[i], end=" ")
print()
def stringToList(input):
input = input.replace(' ', '')
result = []
temp = ''
i = 0
while i < len(input):
char = input[i]
if char.isdigit() or char == '.':
temp += str(char)
else:
if temp != "":
result.append(float(temp))
temp = ''
if char == '*' and i + 1 < len(input) and input[i + 1] == '*' :
result.append('**')
i += 1
else:
result.append(char)
i += 1
if temp != "":
result.append(float(temp))
return result
def infixToPostfix(input):
stack = Stack()
result = []
for i in input:
print(f"i = '{i}'")
if type(i) == float:
result.append(i)
elif i == '(':
stack.push(i)
elif i == ')':
while stack.isEmpty() == False and stack.peek() != '(':
result.append(stack.pop())
stack.pop()
else:
while stack.isEmpty() == False and stack.peek() != '(' and priority(i) <= priority(stack.peek()):
result.append(stack.pop())
stack.push(i)
print(f"stack.peek() = '{stack.peek()}'")
print(f"result = {result}")
stack.printStack()
print()
while stack.isEmpty() == False:
result.append(stack.pop())
return result
def priority(char):
if char == '+' or char == '-':
return 1
elif char == '*' or char == '/':
return 2
elif char == '**':
return 3
else:
return -1
the input itself is given through the following code:
input = input("expression : ")
postfix = infixToPostfix(stringToList(input))
print(f"postfix : {postfix}")
I triple-checked that the other code( including stringToList() ) works correctly.
when given (10+2*1.5)*3
as input, the code outputs the following:
i = '('
result = []
Stack : (
i = '10.0'
result = [10.0]
Stack : (
i = '+'
stack.peek() = '+'
result = [10.0]
Stack : ( +
i = '2.0'
result = [10.0, 2.0]
Stack : ( +
i = '*'
stack.peek() = '*'
result = [10.0, 2.0]
Stack : ( + *
i = '1.5'
result = [10.0, 2.0, 1.5]
Stack : ( + *
i = ')'
result = [10.0, 2.0, 1.5, '*', '+']
Print : Stack is empty
i = '*'
stack.peek() = '('
result = [10.0, 2.0, 1.5, '*', '+']
Stack : (
i = '3.0'
result = [10.0, 2.0, 1.5, '*', '+', 3.0]
Stack : (
postfix : [10.0, 2.0, 1.5, '*', '+', 3.0, '(']
As you can see from the 8th iteration, the '*' became a '(' for no specific reason. Expected output was :
i = '3.0'
result = [10.0, 2.0, 1.5, '*', '+', 3.0]
Stack : *
thus making the postfix : [10.0, 2.0, 1.5, '*', '+', 3.0, '*']
I have moving the print(i) right above the printStack() method, but I am getting the same outputs.
I have tried all the python interpreters that I could get my hand to, but always got the same result, so i don't think it is a local env problem.
The problem is that pop()
decrements self.top
, but it doesn't remove the popped element from the end of self.data
.
So self.data
still has elements at indices greater than self.top
.
The specific problem comes when a push follows a pop. The push()
method calls self.data.append(input)
, and this adds the data at the end of self.data
, not at the position pointed to by self.top
.
The fix is to remove the popped item from self.data
, which you could do using the .pop()
method of a list:
def pop(self):
if self.isEmpty():
print("Pop : Stack is empty")
else:
self.top -= 1
return self.data.pop()
With that change, your test input (10+2*1.5)*3
gives the result you expect:
i = '3.0'
result = [10.0, 2.0, 1.5, '*', '+', 3.0]
Stack : *
postfix : [10.0, 2.0, 1.5, '*', '+', 3.0, '*']
You could further improve the code by removing the use of self.top
. With the fix here, you no longer need it, because len(self.data)
now tells you how many items are on the stack, and the top element (assuming the stack isn't empty) is self.data[-1]
.