Python balance brackets checker - python

I'm trying to create a function that checks for balance brackets, according to the class I created.
But I keep getting False all the time.
I would really appreciate if you could show me where I was wrong and explain me the solution to my mistake.
class Stack:
def __init__(self):
self.__items = []
self.__top = 0
def is_Empty(self):
if self.__top <= 0:
return "Stack Empty!"
else:
return f"Your stack is not Empty!\nThe current stack is {self.my_stack()}"
def __str__(self):
"""Print current stack"""
return self.my_stack()
def push(self, item):
"""Push item in stack."""
self.__items.append(item)
self.__top += 1
def pop(self):
"""Remove top of the stack."""
if self.__top <= 0:
return self.is_Empty()
self.__top -= 1
return self.__items.pop()
def top(self):
"""Return top of the stack."""
if self.__top <= 0:
return self.is_Empty()
else:
return self.__items[-1]
def my_stack(self):
"""Show the current stack"""
if not self.__items:
return self.is_Empty()
else:
return f"The current stack is {self.__items}"
def check_balance(test):
"""
Return True if brackets are balanced, False otherwise.
"""
oppositeBracket = {']': '[', ')': '(', '}': '{'}
lefts = Stack()
for char in test:
if char in '[({':
lefts.push(char)
if char in '])}':
if lefts.is_Empty():
return False
else:
if lefts.top() != oppositeBracket[char]:
return False
lefts.pop()
if not lefts:
return True
return False
for example:
print(check_balance("(10+10)"))
And I get
False

You have 2 small bugs in your code:
isEmpty method returns always True since you return non empty string.
Your final check for empty stack (if not lefts) is always True as well since lefts is equal to your stack object and it even if it's empty, it won't be logical False.
The code should be:
class Stack:
def __init__(self):
self.__items = []
self.__top = 0
def is_Empty(self):
return self.__top <= 0
def __str__(self):
"""Print current stack"""
return self.my_stack()
def push(self, item):
"""Push item in stack."""
self.__items.append(item)
self.__top += 1
def pop(self):
"""Remove top of the stack."""
if self.__top <= 0:
return self.is_Empty()
self.__top -= 1
return self.__items.pop()
def top(self):
"""Return top of the stack."""
if self.__top <= 0:
return self.is_Empty()
else:
return self.__items[-1]
def my_stack(self):
"""Show the current stack"""
if not self.__items:
return self.is_Empty()
else:
return f"The current stack is {self.__items}"
def check_balance(test):
"""
Return True if brackets are balanced, False otherwise.
"""
oppositeBracket = {']': '[', ')': '(', '}': '{'}
lefts = Stack()
for char in test:
if char in '[({':
lefts.push(char)
elif char in '])}':
if lefts.is_Empty():
return False
else:
if lefts.top() != oppositeBracket[char]:
return False
lefts.pop()
return lefts.is_Empty()

You are treating is_Empty as returning a boolean, but it doesn't. It returns a string in either case. (and such is always "True" in a boolean sense)
UnitTest:
l = Stack()
l.push('1')
assert not l.is_Empty()
This assert should not fail, but does.

Related

I did define but why asking checkBrackets not defined

I did define the class as below but it gives me error message says, name 'checkBrackets' is not defined.---> 50 result = checkBrackets(equation)
I did define the class as below but it gives me error message says, name 'checkBrackets' is not defined.
class Stack:
def __init__(self):
self.stack = []
def push(self, item):
self.stack.append(item)
def isEmpty (self):
return len(self.stack) == 0
def peek (self):
if len(self.stack) != 0:
return self.stack[-1]
def pop(self):
if len(self.stack) != 0:
return self.stack.pop(-1)
###
def checkBrackets(statement):
stack = Stack()
size = 0
flag = "Wrong"
for ch in statement:
if ch in ('{','[','('):
size += 1
statck.push(ch)
elif ch in ('}',']',')'):
size += 1
if stack.isEmpty():
return (flag, size)
else:
left = stack.pop()
if (ch=="}" and left !="{") or (ch=="]" and left !="[") or (ch==")" and left !="(") :
return (flag, size)
if stack.isEmpty():
flag ="OK"
return (flag, size)
else:
return (flg, size)
equation = input ("Enter_qauation: ")
result = checkBrackets(equation)
print ("%s_%d"%(result[0],result[1]))
The function is defined, but it is defined in the class Stack so you need to call it as Stack.checkBrackets(equation). There were two more errors(spelling errors), so the final code looks like:
class Stack:
def __init__(self):
self.stack = []
def push(self, item):
self.stack.append(item)
def isEmpty (self):
return len(self.stack) == 0
def peek (self):
if len(self.stack) != 0:
return self.stack[-1]
def pop(self):
if len(self.stack) != 0:
return self.stack.pop(-1)
###
def checkBrackets(statement):
stack = Stack()
size = 0
flag = "Wrong"
for ch in statement:
if ch in ('{','[','('):
size += 1
stack.push(ch) # spelling correction
elif ch in ('}',']',')'):
size += 1
if stack.isEmpty():
return (flag, size)
else:
left = stack.pop()
if (ch=="}" and left !="{") or (ch=="]" and left !="[") or (ch==")" and left !="(") :
return (flag, size)
if stack.isEmpty():
flag ="OK"
return (flag, size)
else:
return (flag, size) # spelling correction
equation = input ("Enter_equation: ")
result = Stack.checkBrackets(equation) # Changed Line
print ("%s_%d"%(result[0],result[1]))
Sample Output 1:
Enter_qauation:
(1+2)=3
OK_2
Sample Output 2:
Enter_qauation:
1+2=(3
Wrong_1

Issues inserting into arbitrary positions (not beginning or end) of doubly linked list

Ok to preface, this is to help with a school assignment. I understand there are unpythonic methods in the following code but this is the format they insist upon. In my insert method I have 4 cases to account for. All of them are dealt with appropriately except for else and im unsure why. For some reason the method insert isn't updating the linked list to include the new_node when this new_node is not placed at the end or start of the list. I'm unsure why this is as at the appropriate position we store the old value of current, we then store its previous and we set current = new_node, we then set new_node's next to be the old value of current and new_node's previous to be the old currents previous. I'm confused as to why this won't work.
class DLinkedListNode:
# An instance of this class represents a node in Doubly-Linked List
def __init__(self,initData,initNext,initPrevious):
self.data = initData
self.next = initNext
self.previous = initPrevious
if initNext != None:
self.next.previous = self
if initPrevious != None:
self.previous.next = self
def getData(self):
return self.data
def setData(self,newData):
self.data = newData
def getNext(self):
return self.next
def getPrevious(self):
return self.previous
def setNext(self,newNext):
self.next = newNext
def setPrevious(self,newPrevious):
self.previous = newPrevious
class DLinkedList:
# An instance of this class represents the Doubly-Linked List
def __init__(self):
self.__head=None
self.__tail=None
self.__size=0
def search(self, item):
current = self.__head
found = False
while current != None and not found:
if current.getData() == item:
found= True
else:
current = current.getNext()
return found
def index(self, item):
current = self.__head
found = False
index = 0
while current != None and not found:
if current.getData() == item:
found= True
else:
current = current.getNext()
index = index + 1
if not found:
index = -1
return index
def add(self, item):
new_node=DLinkedListNode(item,None,None)
new_node.setNext(self.__head)
self.__head=new_node
current=self.__head
new_node.setPrevious(None)
current=current.getNext()
self.__size+=1
def remove(self, item):
# remove the node containing the item from the list
if self.__size == 0:
raise Exception('List is Empty')
current = self.__head
previous = None
found = False
while current != None and not found:
if current.getData() == item:
found = True
else:
previous = current
current = current.getNext()
if not found:
raise Exception('Item not in list')
else:
if previous == None: # the item is in the first node of the list
self.__head = current.getNext()
else: # item is not in the first node
previous.setNext(current.getNext())
self.__size = self.__size -1
def append(self, item):
# adds an item at the end of the list
new_node = DLinkedListNode(item,None,None)
current = self.__head # Start the traversal
if self.__size == 0: # check if list is empty
self.add(item)
else:
while (current.getNext()!=None):
current= current.getNext() # traversing the list
new_node.setNext(None)
new_node.setPrevious(current)
current.setNext(new_node)
self.__size = self.__size +1
def insert(self, pos, item):
# inserts the item at pos
# pos should be a positive number (or zero) of type int
assert type(pos)==int,'Error:pos is not an integer'
assert pos>=0,'Error:pos must be positive'
current=self.__head
new_node= DLinkedListNode(item,None,None)
if pos==0:
self.add(item)
elif pos==self.__size:
self.append(item)
elif pos>self.__size:
raise Exception('Position attempted to enter is larger than the size of linked list.')
else:
current_pos=0
while(current.getNext()!=None):
if (pos)==current_pos:
# storage is a holder variable
storage=current
right=current.getNext()
left=current.getPrevious()
current=new_node
new_node.setPrevious(left)
new_node.setNext(storage)
return True
current=current.getNext()
current_pos+=1
self.__size+=1
# doubly linked list
#Hello(prev)<-->World(store data)-->None
def pop1(self):
current = self.__head
previous = None
while (current.getNext() != None):
previous = current
current = current.getNext()
if (previous == None):
self.__head = None
else:
previous.setNext(None)
self.__size -= 1
return current.getData()
def pop(self, pos=None):
if pos!=None:
assert pos<=self.__size,'Pos must be within list'
assert type(pos)==int,'Pos must be an int'
assert pos>=0,'Pos must not be negative'
current=self.__head
current_pos=0
if pos==(self.getSize()-1) or pos==None:
data_from_method=self.pop1()
return data_from_method
else:
while current.getNext()!=None:
if pos==current_pos:
data=current.getData()
left=current.getPrevious()
right=current.getNext()
left.setNext(right)
right.setPrevious(left)
return data
current_pos+=1
current=current.getNext()
# doubly linked list
#Hello(prev)<-->World(store data)-->None
def searchLarger(self, item):
current=self.__head
current_pos=0
while current.getNext()!=None:
if item<current.getData():
return current_pos
current=current.getNext()
current_pos+=1
return -1
def getSize(self):
return self.__size
def getItem(self, pos):
assert type(pos)==int,'position must be type int'
assert pos<=self.__size,'Position is outside of the list'
current=self.__head
current_pos=0
if pos>=0:
while current!=None:
if current_pos==pos:
return current.getData()
current_pos+=1
current=current.getNext()
else:
current=self.__tail
while current!=None:
if current_pos==pos:
return current.getData()
current_pos-=1
current=current.getPrevious()
def __str__(self):
# returns a string representation of the list
current = self.__head
string = ''
while current != None:
if current.getNext()==None:
string = string + str(current.getData())+''
else:
string=string+str(current.getData())+' '
current = current.getNext()
return string
def test():
new_list=DLinkedList()
for i in range(20):
new_list.insert(i,i)
new_list.insert(1,90)
print(new_list)
test()
You currently have code that links the new node to nodes in the list, but no code that links the existing nodes to the new node. The only gesture you have in that direction is current=new_node, which doesn't achieve anything useful (since current is a local variable and you're about to return from the function).
You probably want something like left.setNext(newnode) and right.setPrevious(newnode), though I'm not sure you've set up both of those variables correctly (one of them should probably be current, unless you're intending to replace an existing node).

Python Sum even numbers and odd number with Node, tail, Empty

So I am trying some things with linked lists using Node, tail and empty but I have no clue on how to make a summs_even or summs_odd function.
class Node:
def __init__(self, value, tail):
self.IsEmpty = False
self.Value = value
self.Tail = tail
def __str__(self):
return str(Node)
class Empty:
def __init__(self):
self.IsEmpty = True
Empty = Empty()
l = Node(1, Node(2, Node(3, Node(4, Empty))))
def summ(l):
if l.IsEmpty:
return 0
else:
return l.Value + summ(l.Tail)
print("Sum: " + str(summ(l)))
Something along the lines
def summ_even(l):
if l.IsEmpty:
return 0
elif l.Value%2==1: # check if value is odd
return summ_even(l.Tail)
else:
return return l.Value + summ_even(l.Tail)

Reverse Class Method Not Working

So I created a simple class method to reverse a string and yet it returns to me the original? The Method that I created works outside of the class but for some reason it does not when I try to implement it.
See my code below:
class Stack:
def __init__(self):
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 is_empty(self):
return len(self.__items) == 0
def size(self):
return len(self.__items)
def reverse(self):
if len(self.__items) <= 1:
return self.__items
return self.__items.reverse(self.__items[1:]) + self.__items[0]
s=Stack()
rev=input("Enter string to reverse; ")
s.push(rev)
print(s.reverse())
You need to reverse each string in self.__items not self.__items itself:
def reverse(self):
if not self.__items: # if items is empty return empty string
return ""
return " ".join(s[::-1] for s in self.__items)
self.__items[::-1] will reverse the list items not the string/strings inside.
If you wanted to do it without slicing:
def reverse(self):
if not self.__items:
return ""
out = ""
for item in self.__items:
temp = ""
for i in range(len(item)-1, -1, -1):
temp += item[i]
out += temp
return out
Or recursively:
def reverse(self):
if not self.__items:
return ""
def recur(s):
if not s:
return ""
return s[-1] + recur(s[:-1])
return " ".join(recur(w) for w in self.__items)

Recursion and return statements in python

I am trying to implement a 2-3 tree but I am having trouble with the find method.
This method given an int as parameter should return the node that contains the int.
The problem is that sometimes it works, sometimes it does't and I don't know why.
I have added a test print. For a particular int that I know for sure that is part of the tree, the code executes the print statement, meaning that it has found the node, but does not return this node. Instead it return False which is at the end of the code.
Can you help me solving this ?
def find(self,data,node=0): #return problem ???
if node==0:
a=self.root
else:
a=node
if a.data2==None:
if data==a.data: ### here is the problem
print("qwertyuiop") ### it does not execute the return statement
return a
elif data < a.data:
if a.left!=None:
return self.find(data,a.left)
elif data > a.data:
if a.right!=None:
return self.find(data,a.right)
else:
if a.data2!=None:
if (data==a.data or data==a.data2):
return a
elif data<a.data:
if a.left!=None:
return self.find(data,a.left)
elif (data>a.data and data<a.data2):
if a.middle!=None:
return self.find(data,a.middle)
elif data>a.data2:
if a.right!=None:
return self.find(data,a.right)
print("Not Found") ### function executes this print
return False
self.root is the root of the tree and is an object of the following class
class Node:
def __init__(self, data=None, left=None, right=None):
self.data = data
self.data2 = None
self.data3 = None
self.left = left
self.right = right
self.middle = None
self.middle2 = None
Binary Search Tree:
class Nodeee:
def __init__(self, data=None, left=None, right=None):
self.data = data
self.left = left
self.right = right
class BST:
def __init__(self, root=None):
self.c=[]
self.total=0
self.root = None
def parent(self,data,node=5):
def search(nodee,cc,data):
if data==cc.data:
return nodee
else:
if data<cc.data:
nodee=cc
return search(nodee,cc.left,data)
elif data>cc.data:
nodee=cc
return search(nodee,cc.right,data)
print("Parent Error")
return False
if node==self.root:
print("Root has no parent")
else:
a=self.root
c=self.root
return search(a,c,data)
def lookup(self,data,node=0):
if node==0:
a=self.root
else:
a=node
if data < a.data:
if a.left==None:
return a
else:
return self.lookup(data,a.left)
elif data > a.data:
if a.right==None:
return a
else:
return self.lookup(data,a.right)
def find(self,data,node=0):
if node==0:
a=self.root
else:
a=node
if data==a.data:
print("WTF")
return a
elif data < a.data:
if a.left!=None:
return self.find(data,a.left)
elif data > a.data:
if a.right!=None:
return self.find(data,a.right)
print("Not Found")
return False
def find2(self,data,node=0):
if node==0:
a=self.root
else:
a=node
if data==a.data:
return True
elif data < a.data:
return self.find2(data,a.left)
elif data > a.data:
return self.find2(data,a.right)
return False
def is_empty(self):
if self.root==None:
return True
def is_leaf(self,n):
if (n.left==None and n.right==None):
return True
return False
def delete(self):
self.root=None
def insert(self, data):
if self.root==None:
self.root=Nodeee(data)
self.total+=1
return True
else:
b=self.lookup(data)
if data < b.data:
b.left=Nodeee(data)
self.total+=1
return True
elif data > b.data:
b.right=Nodeee(data)
self.total+=1
return True
print("Insert Error !")
return False
def inorder_swap(self,data):
a=self.find(data)
b=a.right
while self.is_leaf(b)!=True:
if b.left!=None:
b=b.left
elif b.left==None:
b=b.right
temp=a.data
a.data=b.data
b.data=temp
def remove(self,data):
a=self.find(data)
if self.is_leaf(a)==True:
b=self.parent(data)
if b.left==a:
b.left=None
elif b.right==a:
b.right=None
elif self.is_leaf(a)==False:
if a.left==None:
b=self.parent(data)
if b.left==a:
b.left=b.left.right
elif b.right==a:
b.right=b.right.right
elif a.right==None:
b=self.parent(data)
if b.left==a:
b.left=b.left.left
elif b.right==a:
b.right=b.right.left
elif (a.left!=None and a.right!=None):
self.inorder_swap(data)
self.remove(data)
def inorder(self,node):
if node!=None:
self.inorder(node.left)
self.c.append(node.data)
self.inorder(node.right)
def inorder_print(self):
self.c=[]
self.inorder(self.root)
print("\nStart")
for x in range(len(self.c)):
print(self.c[x], end=",")
print("\nFinish\n")
a=BST()
print(a.insert(234)==True)
print(a.insert(13)==True)
print(a.insert(65)==True)
print(a.insert(658)==True)
print(a.insert(324)==True)
print(a.insert(86)==True)
print(a.insert(5)==True)
print(a.insert(76)==True)
print(a.insert(144)==True)
print(a.insert(546)==True)
print(a.insert(2344)==True)
print(a.insert(1213)==True)
print(a.insert(6345)==True)
print(a.insert(653348)==True)
print(a.insert(35324)==True)
print(a.insert(8463)==True)
print(a.insert(5555)==True)
print(a.insert(76539)==True)
print(a.insert(14499)==True)
print(a.insert(59999946)==True)
a.inorder_print()
a.remove(35324)
a.remove(1213)
a.remove(2344)
a.remove(144)
a.remove(5555)
a.remove(6345)
a.remove(59999946)
a.remove(76)
print(a.root.data)
a.inorder_print()
def inorder_swap(self,data):
a=self.find(data)
b=a.right
while self.is_leaf(b)!=True:
if b.left!=None:
b=b.left
elif b.left==None:
b=b.right
temp=a.data
a.data=b.data
b.data=temp
a here is the node containing the passed data. This method does nothing else than swapping a's data with some leaf's data (first one while finds), thereby distorting the tree order. A follow-up find on the same data therefore fails and returns False. Since your code has no error checks, this results in an AttributeError.
You probably want to move nodes around in inorder_swap. However you only assign to the local name b. If you want to change nodes, then you need to use b.left = or b.right =.
It might be that there are more problems, that I don't see right now.
Also your code has several style problems, some of them:
You have four functions doing the same: find, find2, lookup and search in parent.
Most of the naming is not informative or even confusing.
Lines like if a.right==None: should be written as if not a.right: (or maybe if a.right is None:).
Check the return value of functions and don't just assume they return a valid node if they might not (i.e. find might return False instead of a node). Or alternatively use exception handling.
If you have an if ... elif ... elif block you don't have to check the last possibility if it is sure to be true, for example:
if b.left!=None:
# something
elif b.left==None:
# something else
should be
if b.left:
# something
else:
# something else

Categories

Resources