AttributeError: 'int' object has no attribute 'data' - python-3.x

I was trying to implement some basic operations of Binary search tree in Python3.7. I have just started coding problems from Hackerrank and I got stuck while implementing levelOrder traversal in BST. What should I do to resolve this AttributeError: 'int' object has no attribute 'data'?
I am using queue to solve this problem, initially, the queue will point to root node, then checks for left and right children. If found, the children will get append to the queue and the process continues until the queue is empty. I am popping out the first element in each iteration and storing it in temp variable. This way i will get nodes at each level of tree.
class Node:
def __init__(self, data):
self.data = data
self.leftChild = None
self.rightChild = None
def insert(self, data):
if self.data is not None:
if data < self.data:
if self.leftChild is None:
self.leftChild = Node(data)
else:
self.leftChild.insert(data)
elif data > self.data:
if self.rightChild is None:
self.rightChild = Node(data)
else:
self.rightChild.insert(data)
else:
self.data = data
def traverseLevelOrder(self):
queue = []
queue.append(self.data)
while queue:
# Print front of queue and remove it from queue
print(queue[0].data)
temp = queue.pop(0)
# Enqueue left child
if temp.leftChild is not None:
queue.append(temp.leftChild)
# Enqueue right child
if temp.rightChild is not None:
queue.append(temp.rightChild)
class BST:
def __init__(self):
self.rootNode = None
def insert(self, data):
if self.rootNode is None:
self.rootNode = Node(data)
else:
self.rootNode.insert(data)
def traverseLevelOrder(self):
if self.rootNode is None:
return
else:
self.rootNode.traverseLevelOrder()
bst = BST()
bst.insert(2)
bst.insert(4)
bst.insert(1)
bst.insert(3)
bst.traverseLevelOrder()
The code should return the level traversal order like one given below(within a level it should print first left node then right node):
2
1
4
3
Instead, I am having the below error:
Traceback (most recent call last):
print(queue[0].data)
AttributeError: 'int' object has no attribute 'data'

You're appending an integer, self.data to the queue, then attempting to access a property on the integer with queue[0].data, causing the AttributeError to be raised.
Instead, append the node itself with:
queue.append(self)

queue.append(self.data)
Did you mean:
queue.append(self)
?
Right now you're only adding a number to the queue, not the whole object.

Related

AttributeError: 'LinkedList' object has no attribute 'head'

I don't understand what is wrong with my code. it says
AttributeError: 'LinkedList' object has no attribute 'head'
Here is my code:
class Node:
def __init__(self, data):
self.data = data
self.next = None
I created an empty linked list and added nodes:
class LinkedList():
def __int__(self):
self.head = None
def insert(self, newNode):
if self.head is None:
self.head = newNode
else:
#head =>john->Ben->Matthew->None
lastNode = self.head
while True:
if lastNode.next is None:
break
lastNode = lastNode.next
lastNode.next = newNode
def printList(self):
#head=>john->Ben->Matthew->None
currentNode = self.head
while True:
if currentNode is None:
break
print(currentNode.data)
currentNode = currentNode.next
# node => data, next
#firstnode.data => data, firstnode.next => None
firstNode = Node('john')
linkedlist = LinkedList()
linkedlist.insert(firstNode)
secondNode = Node('Ben')
linkedlist.insert(secondNode)
thridNode = Node('Matthew')
linkedlist.insert
linkedlist.printList()
You have some errors which you could easily spot with some debugging (stepping through the code):
The LinkedList function __int__ is never executed (you could spot this by putting a breakpoint there). It should be named __init__.
The main program does not add the third node, because it does not call the insert method -- it merely references it. You could spot this easily when stepping through the code, one instruction at a time, with a debugger. Add the parentheses and pass the argument.
The printList has a loop that runs infinitely, because the line that moves the currentNode reference is not part of the loop's body. You could spot this easily again by stepping through the code with a debugger. This statement should be indented more to become part of the loop.
This should fix your problems.
Note: this was just a matter of debugging. You really can do this yourself in a good programming environment.

AttributeError: 'NoneType' object has no attribute 'data' in displaying linked list

I'm trying to display linked list elements in the form of a list but keep getting this error:
AttributeError: 'NoneType' object has no attribute 'data'
class Node:
def __init__(self,data=None,next=None):
self.data = data
self.next = next
class LinkedList:
def __init__(self):
self.head = None
def insert_at_beginning(self,data):
node = Node(data,self.head)
self.head = node
def display(self):
elements = []
currNode = self.head
while currNode:
currNode = currNode.next
elements.append(currNode.data)
print(elements)
if __name__ == "__main__":
ll = LinkedList()
ll.insert_at_beginning(1)
ll.insert_at_beginning(2)
ll.insert_at_beginning(3)
ll.display()
Can anyone explain the error here?
After the while loop, append data first then go to the next. You're getting the error because if currNode.next is null then it's showing the object has no attribute 'data'. So, append first then go to next. If currNode.next is null then the loop will stop.
while currNode:
elements.append(currNode.data)
currNode = currNode.next

Binary Tree implementation with Separate class for node and tree

I am new to Python and data structures. While learning binary tree, I found all the available implementations have the methods of the tree inside the node class.
But I want to implement it differently, where along with the Node class, there will be a Binary tree class, which will contain the methods of the Binary tree.
This is the code I came up with, but it raises an error with the arguments I am passing to the functions insertleft() and insertright().
class Node():
def __init__(self, arg):
self.left = None
self.right = None
self.data = arg
class Bt():
def __init__(self, root):
self.root = root
def insertleft(temp.left, data):
if (temp.left == None):
temp.left.data = data
elif(data<temp.left.data):
t1 = temp.left
insertleft(t1.left, data)
elif(data>temp.left.data):
t1 = temp.left
insertright(t1.left, data)
def insertright(temp.right, data):
if (temp.right == None):
temp.right.data = data
elif(data<temp.right.data):
t1 = temp.right
insertleft(t1.right, data)
elif(data>temp.right.data):
t1 = temp.right
insertright(t1.right, data)
def insert(self, data):
temp = self.root
if(temp.data = None):
temp.data = data
elif(data<temp.data):
insertleft(temp.left, data)
elif(data>temp.data):
insertright(temp.right, data)
r = Bt()
r.root = Node(5)
r.insert(4)
r.insert(6)
These is the error I received:
def insertleft(temp.left, data):
^
SyntaxError: invalid syntax
I am not sure what the right syntax should be. Thanks in advance for your help
When you define a function, you also define the parameters you will be accepting. Inside a class though, as long as the method is not static or a class method, the first parameter should be self or a variable that represents the instanciated object itself.
In your case, you are already passing the value of temp.left and temp.right when calling the function. Changing the function definitions to just use temp should work just fine. Or even more readible, node since that is what you are actually referring to.
Your insertleft and insertright functions do the same thing as insert, and including them is not necessary. Just modify the insert function to do it all.
Here's what the end result should resemble:
class Node():
def __init__(self, arg):
self.left = None
self.right = None
self.data = arg
class Bt():
def __init__(self, root=None): #Added default value
self.root = Node(root)
def insert(self, data):
if self.root.data is None:
self.root.data = data #Set the root data if it doesn't exist.
else:
self._insert(self.root, data) #Prime the helper function with root node
def _insert(self, node, data): #Insert helper function to do the insertion
if data < node.data: #Check if data needs to be inserted on the left
if node.left is None: #Set left node if it doesn't exist
node.left = Node(data)
else: #Else let the left node decide where it goes as a child
self._insert(node.left, data)
else: #Else data needs to be inserted on the right
if node.right is None: #Set right node if it doesn't exist
node.right = Node(data)
else: #Else let the right node decide where it goes as a child
self._insert(node.right, data)
r = Bt(5)
r.insert(4)
r.insert(6)
Now you're just missing functions to print the Tree and Data... and accessing the data.
Each Node in the binary search tree is considered as a another binary search tree. Hence we don't need to create a separate class for node.

how to print vertex using BFS Algo in python?

The problem is in this line (graph.vertList[currentVert].getConnections()) I am unable to get the list of all connected node which is currently connected to currentVert , when I print this code i get the all connected object print(g.vertList[1].getConnections())
dict_keys([<__main__.Vertex object at 0x7f7a7db9a3c8>, <__main__.Vertex object at 0x7f7a7db9a2e8>])
I am unable to find node(vertex) or id for these object so that ,I can Travers easily from one node to another node and print the result at same time .
I am unable to fine the bug , here is the complete code :-
class Queue:
def __init__(self):
self.queue=[]
def enqueue(self,item):
self.queue.insert(0,item)
def isEmpty(self):
return self.queue == []
def dequeue(self):
return self.queue.pop()
def size(self):
return len(self.queue)
Then I create an another class Vertex :
class Vertex:
def __init__(self,key):
self.id=key
self.connectedTo={}
def addNeighbor(self,nbr,weight=0):
self.connectedTo[nbr]=weight
def __str__(self):
return str(self.id)+' Connected To : '+str([x.id for x in self.connectedTo])
def getConnections(self):
return self.connectedTo.keys()
def getId(self):
return self.id
def getWeight(self,nbr):
return self.connectedTo[nbr]
Another class Graph :
class Graph:
def __init__(self):
self.vertList={}
self.numVertices=0
def addVertex(self,key):
self.numVertices=self.numVertices+1
newVertex=Vertex(key)
self.vertList[key]=newVertex
return newVertex
def addEdges(self,f,t,cost=0):
if f in self.vertList:
if t in self.vertList:
self.vertList[f].addNeighbor(self.vertList[t],cost)
else:
return "Not present in Graph"
else:
return "Not present in Graph"
def getVertex(self,n):
if n in self.vertList:
return self.vertList[n]
else:
return None
def getVertices(self):
return self.vertList.keys()
After that I created a function bfs (Breadth First Search) :
def bfs(graph,start):
#Keep track of all visited nodes
visited=[]
#keep track of nodes to be checked using queue
vertQueue= Queue()
vertQueue.enqueue(start)
#Keep looking until there are nodes still to be checked
while vertQueue:
#pop shallowest node (first node ) from queue
currentVert=vertQueue.dequeue()
print(currentVert,end="")
for nbr in (graph.vertList[currentVert].getConnections()):
if nbr not in visited:
#add node to list of checked nodes
vertQueue.enqueue(nbr)
visited.append(currentVert)
How can I fix this problem ?
The problem is here:
self.vertList[f].addNeighbor(self.vertList[t],cost)
Change this to
self.vertList[f].addNeighbor(t,cost)
and it should work.

binary search tree - recursive insertion python

I'm trying to correctly construct a binary search tree with a recursive insert function that will allow me to initialize a tree and continue to add nodes (stems). Here is the code that I've done so far (newer to coding, so probably way too wordy):
class Binary_Search_Tree:
class __BST_Node:
def __init__(self, value):
self.value = value
self.right_child = None
self.left_child = None
def __init__(self):
self.__root = None
self.__height = 0
self.value = None
def _recursive_insert(self, value):
new_stem = Binary_Search_Tree.__BST_Node(value)
if self.__root is None:
self.__root = new_stem
self.__root.value = new_stem.value
else:
if self.__root.value > new_stem.value:
if self.__root.right_child is None:
self.__root.right_child = new_stem
self.__root.right_child.value = new_stem.value
else:
self.__root.right_child._recursive_insert(self.__root, value)
else:
if self.__root.left_child is None:
self.__root.left_child = new_stem
self.__root.left_child.value = new_stem.value
else:
self.__root.left_child._recursive_insert(self.__root, value)
def insert_element(self, value):
element_to_insert = self._recursive_insert(value)
return element_to_insert
I then try to add values to this new tree in the main method:
if __name__ == '__main__':
new = Binary_Search_Tree()
new.insert_element(23)
new.insert_element(42)
new.insert_element(8)
new.insert_element(15)
new.insert_element(4)
new.insert_element(16)
The error that I keep getting is: '__BST_Node' object has no attribute '_recursive_insert' This pops up after inserting the first element, so I'm guessing the error occurs somewhere in the else statement. If anyone can figure out where my error is or has any tips on how to make this code more readable/user friendly, I'd be appreciative!
The issue is with this line:
self.__root.right_child._recursive_insert(self.__root, value)
As well as this:
self.__root.left_child._recursive_insert(self.__root, value)
You've defined _recursive_insert to be a method of Binary_Search_Tree, but you're calling it with an instance of __BST_Node, in self.__root.xxxxx_child._recursive_insert, where xxxx_child is an instance of BST_Node.
In fact, your entire _recursive_insert function leaves something to be desired. You're not returning anything from it, but you are assigning it's (non-existent) return value to something in insert_element.
Fixed code:
def _recursive_insert(self, root, value):
new_stem = Binary_Search_Tree.__BST_Node(value)
if root is None:
root = new_stem
else:
if root.value < new_stem.value:
if root.right_child is None:
root.right_child = new_stem
else:
root = self._recursive_insert(root.right_child, value)
elif root.value > new_stem.value:
if root.left_child is None:
root.left_child = new_stem
else:
root = self._recursive_insert(root.left_child, value)
return root
def insert_element(self, value):
self.__root = self._recursive_insert(self.__root, value)
return element_to_insert
Your function did not return an updated root
Your function does not handle a case when the value being inserted would be equal to an existing value, causing spurious entries.
With each recursive call, your function was being passed the same values, so it would not be able to know what to do. A new parameter for the node must be passed across calls. This makes it possible to establish a base case and return.

Resources