Stack and evaluate postfix - python

I was wondering if anyone can help with this Stack question
there are 2 example in the main function and the answer should be 1024 and 4096, but I will get 100 and 144
the issue must be in evaluate_postfix definition becuase I know the Stack class is working
class Stack:
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def peek(self):
return self.items[len(self.items)-1]
def size(self):
return len(self.items)
def evaluate_postfix(text):
s = Stack()
for element in text:
plus = None
if element.isdigit():
s.push(int(element))
elif element == '^':
plus = s.pop() ** s.pop()
elif element == "+":
plus = s.pop() + s.pop()
elif element == "-":
plus = s.pop() - s.pop()
elif element == "*":
plus = s.pop() * s.pop()
elif element == "/":
plus = s.pop() / s.pop()
if plus is not None:
s.push(plus)
return s.pop()
def main():
print(evaluate_postfix(['2', '10', '^']))
print(evaluate_postfix(['2', '4', '3', '*', '^']))
main()

You're poping the right elements, but in the wrong order:
s.pop() ** s.pop()
Once your program reaches that line, for the first example, the stack will look like this: ['2', '10']. It pops 10, then 2, then raises 10 to the power of 2. Instead, you can use:
right = s.pop()
left = s.pop()
left ** right
You'll receive the desired answer, 1024. The same principle applies to the other operators.

Related

TypeError: 'Stack' object is not subscriptable

class Stack:
max = 10
def __init__(self):
self.Stack =[]
self.top = 0
def getter(self):
print(self.Stack)
def push(self):
if (self.top == self.max):
print("Stack Overflow\n",
"Please pop out the Stack to enter new values :)")
else:
self.Stack.append(exp[index])
self.top += 1
def popup(self):
if (self.top == 0):
print(" Stack Underflow\n", "push some element to pop some")
else:
self.top -= 1
return self.Stack.pop()
allow = ['%', '/', '*', '-', '+', '(', ')','**']
precedencse = {'+': 1, '-': 1, '*': 2, '/': 2, '%': 3,'**':4,'(':0,')':0}
newexp = str()
exp = input("Enter the expression")
index = int(0)
stack = Stack()
while (True):
if (exp[index].isalpha() == True):
newexp = exp[index]
index += 1
elif (exp[index] in allow):
if (stack.top == 0 or exp[index] == '(' or exp[index] == ')' or precedencse[exp[index]] > precedencse[stack[stack.top]] == True):
stack.push()
index += 1
if(stack[stack.top] == ')' and '(' in stack == True):
for i in range(stack.index('(')-1, stack.top):
newexp = stack.popup()
newexp.replace('(','')
newexp.replace(')','')
elif (precedencse[exp[index]] < precedencse[stack.top] == True or precedencse[exp[index]]==precedencse[stack.top] == True):
newexp = stack.popup()
stack.push()
else:
print("You Entered worng character in the expression")
break
print(newexp)
I am trying to do infix to postfix conversion algorithm
when I am creating Stack=[] inside the class it gives the following error but when i create the same stack=[] outside the class it give AttributeError: 'Stack' object has no attribute 'append'
please explain me the solution. am a rookie programmer

Performing arbitrary arithmetic operations that a user provides to the system using stack (stack implementation being done with linked lists)

I'm using the following code to perform stack implementation in the case of solving arbitrary arithmetic operations:
def precedence(op):
if op == '+' or op == '-':
return 1
if op == '*' or op == '/':
return 2
return 0
def operation(a, b, op):
if op == '+': return a + b
if op == '-': return a - b
if op == '*': return a * b
if op == '/': return a / b
def evaluate(tokens):
# This is a stack to store integer values
values = []
# This stack stores operators
ops = []
i = 0
while i < len(tokens):
if tokens[i] == ' ':
i += 1
continue
elif tokens[i] == '(':
ops.append(tokens[i])
elif tokens[i].isdigit():
val = 0
while (i < len(tokens) and
tokens[i].isdigit()):
val = (val * 10) + int(tokens[i])
i += 1
values.append(val)
i -= 1
elif tokens[i] == ')':
while len(ops) != 0 and ops[-1] != '(':
val2 = values.pop()
val1 = values.pop()
op = ops.pop()
values.append(operation(val1, val2, op))
ops.pop()
else:
while (len(ops) != 0 and
precedence(ops[-1]) >=
precedence(tokens[i])):
val2 = values.pop()
val1 = values.pop()
op = ops.pop()
values.append(operation(val1, val2, op))
ops.append(tokens[i])
i += 1
while len(ops) != 0:
val2 = values.pop()
val1 = values.pop()
op = ops.pop()
values.append(operation(val1, val2, op))
return values[-1]
if __name__ == "__main__":
ask = input('Enter your expression here: ')
print(f"\nThe answer is {evaluate(ask)}")
But I have no clue how to translate this implementation of stack using linked list.
Can anyone help me? Or provide me with links that would be helpful in explaining stack using linked lists ?
Thanks!
class LLstack:
def __init__(self):
self.numNodes = 0
self.tail = None
def __iter__(self):
self.n = self.numNodes
self.index = self.tail
return self
def __next__(self):
if (self.n == self.numNodes):
self.n-=1
return self.index.val
if self.n>0:
self.n-=1
self.index = self.index.next
return self.index.val
else:
raise StopIteration
def push(self,val):
self.numNodes+=1
if (self.tail!=None):
temp = self.Node(val)
temp.next = self.tail
self.tail = temp
else:
self.tail = self.Node(val)
def pop(self):
if (self.numNodes==0):
return None
self.numNodes-=1
val = self.tail.val
self.tail = self.tail.next
return val
def size(self):
return self.numNodes
class Node:
def __init__(self,val):
self.val = val
self.next = None
if __name__== "__main__":
stack = LLstack()
for i in range(100):
stack.push(LLstack())
i = iter(stack)
for x in i:
print(x)
https://algs4.cs.princeton.edu/13stacks/
Not sure if this is what you are looking for.

Python program to convert infix to prefix notation

I keep on getting an IndexError: list index out of range, return self.data[-1] # the last element in the list; I think I know what is causing this but I have no clue how to fix it
Here is the Stack Class I used:
class Stack:
# LIFO Stack implementation using a Python list as underlying storage.
def __init__(self):
self.data =[]
def __len__(self):
return len(self.data)
def is_empty(self):
return len(self.data)==0
def push(self, e):
self.data.append(e)
def top(self):
return self.data[-1]
def pop(self):
return self.data.pop()
And the corresponding code I made:
def operatorpriority(x):
if x == "+" or x == "-":
return 1
elif x == "*" or x == "/":
return 2
else:
return 3
return 0
def polishnotation(A):
# Converts Infix to Prefix Notation
stack = Stack()
stack.push(')')
A = A + '('
output = ""
for i in range(len(A)-1, -1, -1):
print(i)
if A[i].isnumeric() == True:
output+=A[i]
elif A[i] == ")":
stack.push(A[i])
elif A[i] == "-" or A[i] == "+" or A[i] == "*" or A[i] == "/" or A[i] == "^":
if A[i] == "^":
while operatorpriority(A[i]) <= operatorpriority(stack.top()):
output+=stack.pop()
else:
while operatorpriority(A[i]) < operatorpriority(stack.top()):
output+=stack.pop()
stack.push(A[i])
elif A[i] == "(":
while stack.is_empty()== False:
if stack.top() != "(":
output+=stack.pop()
stack.pop()
while stack.is_empty()== False:
output+=stack.pop()
print(output)
InfixInput = input("Input infix notation: ")
polishnotation(InfixInput)
Sample Input:
(a+b)*(c-d)
Expected Output:
*+ab-cd
You have A = A + '('. That adds at the wrong end. Just do A = '('+A+')' and skip the extra push.
You are giving ')' the same priority as '^'. In operatorpriority, your else: should be elif x =='^':.
In your elif A[i] == "(" clause, you are popping until '('. That's the wrong type of parens. And you don't break out of that loop until the stack is empty. You need to break when you get to a ')'.
Your example shows (a+b)*(c+d), but your code only allows digits. I haven't changed that.
This works:
class Stack:
# LIFO Stack implementation using a Python list as underlying storage.
def __init__(self):
self.data =[]
def __len__(self):
return len(self.data)
def is_empty(self):
return len(self.data)==0
def push(self, e):
self.data.append(e)
def top(self):
return self.data[-1]
def pop(self):
return self.data.pop()
def operatorpriority(x):
if x in "+-":
return 1
elif x in "*/":
return 2
elif x in "^":
return 3
return 0
def polishnotation(A):
# Converts Infix to Prefix Notation
stack = Stack()
A = '(' + A + ')'
output = ""
for c in A[::-1]:
print(c)
if c.isnumeric():
output+=c
elif c == ")":
stack.push(c)
elif c in "+-*/^":
if c == "^":
while operatorpriority(c) <= operatorpriority(stack.top()):
output+=stack.pop()
else:
while operatorpriority(c) < operatorpriority(stack.top()):
output+=stack.pop()
stack.push(c)
elif c == "(":
while not stack.is_empty():
c1 = stack.pop()
if c1 == ')':
break
output+=c1
while not stack.is_empty():
output+=stack.pop()
return output
print(polishnotation('(3+4)*(5+6)'))

Checking validity of an expression that contains nested parentheses by using stack

I want to use the stack for checking the validity of an expression that contained nested parentheses.
I wrote bellow code but when my input is [{[]}, the code doesn't return anything but I expected to return "left parentheses are more than right ones".
also when my input is (), the response instead of being "balanced" is "mismatched" !!
what is my mistake in the written code?
class Stack:
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def push(self, data):
self.items.append(data)
return
def pop(self):
self.items.pop()
def match(left, right):
if left == '[' and right == ']':
return True
elif left == '{' and right == '}':
return True
elif left == '(' and right == ')':
return True
else:
return False
def validity(text):
st = Stack()
for i in text:
if i in '[{(':
st.push(i)
if i in ']})':
if st.is_empty():
print('right parentheses is more than left one')
return False
else:
compare = st.pop()
if not match(compare, i):
print('mismatched')
return False
if st.is_empty():
print('balanced')
else:
print('left parentheses are more than right ones')
for j in range(4):
example = input('plz enter text ')
validity(example)
st.pop() doesn't return anything so compare is always None.
def pop(self):
return self.items.pop()
Should fix it.

Error in code while converting infix form to prefix form using stack class

class Stack:
def __init__(self):
self.stack=[]
self.top = None
def empty(self):
return not self.stack
def push(self, item):
self.stack.append(item)
self.top = item
def pop(self):
if self.empty():
a = self.stack.pop()
return a
else:
print("Empty stack")
def printall(self):
print(self.stack)
def clear(self):
self.stack = []
self.top = None
ysj = Stack()
jy = []
list = input().split()
leng = len(list)
num = 0
for i in range(0, leng):
if list[i] == '+' or list[i] == '-':
while ysj.top is not None:
jy.append(ysj.pop())
num = num - 1
ysj.push(list[i])
num = num + 1
elif list[i] == '/' or list[i] == '*':
while ysj.top == '/' or ysj.top == '*':
jy.append(ysj.pop())
num = num - 1
ysj.push(list[i])
num = num + 1
else:
jy.append(int(list[i]))
for i in range(1, num + 1):
jy.append(ysj.pop())
for i in range(0, len(jy)):
print(jy[i], end=" ")
I'm trying to convert the equation from infix form to postfix form using Stack class.
This code works when I type in
1 + 2 * 3
but doesn't work well when I type in
1 * 2 + 3 or 1 * 2 * 3 or 1 + 2 + 3
I think there's something wrong with my while loop but I can't figure out what part is wrong. Please help me.
You forgot to insert None to top when the list gets empty, and you are trying to remove a item when the list is empty:
class Stack:
def __init__(self):
self.stack=[]
self.top = None
def empty(self):
return not self.stack
def push(self, item):
self.stack.append(item)
self.top = item
def pop(self):
if not self.empty(): # remove item only if the stack is not empty
a = self.stack.pop()
# after removing a item, check if the stack is empty
if self.empty(): # if it is, set the top as None
self.top = None
return a
else:
print("Empty stack")

Categories

Resources