AttributeError: 'LinkedList' object has no attribute 'head' - python-3.x

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.

Related

code should not return any node object(Element)

https://gist.github.com/manaidu-2002/3f7eb60b8521201eba6548ca23cec053
Code returning Node Object(Element), please check the test cases and help me with this
"""Add a couple methods to our LinkedList class,
and use that to implement a Stack.
You have 4 functions below to fill in:
insert_first, delete_first, push, and pop.
Think about this while you're implementing:
why is it easier to add an "insert_first"
function than just use "append"?"""
class Element(object):
def __init__(self, value):
self.value = value
self.next = None
class LinkedList(object):
def __init__(self, head=None):
self.head = head
def append(self, new_element):
current = self.head
if self.head:
while current.next:
current = current.next
current.next = new_element
else:
self.head = new_element
def insert_first(self, new_element):
"Insert new element as the head of the LinkedList"
new_element.next = self.head
self.head = e_insert
def delete_first(self):
"Delete the first (head) element in the LinkedList as return it"
temp = self.head
if temp == None:
return None
s= temp
self.head = temp.next
return s
class Stack(object):
def __init__(self,head=None):
self.ll = LinkedList(head)
def push(self, new_element):
"Push (add) a new element onto the top of the stack"
temp = self.ll.head
while temp.next :
temp = temp.next
temp.next = new_element
def pop(self):
"Pop (remove) the first element off the top of the stack and return it"
if self.ll.head.next == None :
temp = self.ll.head
e= temp
temp = None
return e
elif self.ll.head.next:
temp = self.ll.head
while temp.next.next:
temp = temp.next
e= temp.next
temp.next = None
return e
return None
# Test cases
# Set up some Elements
e1 = Element(1)
e2 = Element(2)
e3 = Element(3)
e4 = Element(4)
# Start setting up a Stack
stack = Stack(e1)
# Test stack functionality
stack.push(e2)
stack.push(e3)
print(stack.pop().value)
print(stack.pop().value)
print(stack.pop().value)
print(stack.pop())
stack.push(e4)
print(stack.pop().value)
First of all, there is an unused name reference in your code: e_insert. This should read new_element.
The main issue is that your Stack class is not re-using the code you already have in your LinkedList class. In the new code you have written there are several mistakes in how you deal with next, but taking a step back, you are making a critical mistake in thinking that the top of the stack should be at the tail of the linked list, but that is very inefficient. The top of the stack should be at the head of the linked list. It is at that side that you can easily remove and insert elements without having to iterate the list.
So take these points into consideration:
Reuse the code you already have for LinkedList. In other words, call the methods defined on the LinkedList class.
The top of the stack is at the head of the linked list.
That means the Stack class can be as simple as this:
class Stack(LinkedList):
def __init__(self, head=None):
self.ll = LinkedList(head)
def push(self, new_element):
self.ll.insert_first(new_element)
def pop(self):
return self.ll.delete_first()

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

Understanding the "self" in classes for Python

I'm trying to understand the solution provided for reversing a linked list. In particular, I don't get why for the very last line we write:
self.head=prev
and not
current=prev
since
current=self.head
I know my reasoning is flawed, that's why I came here for help. Thank you in advance.
class Node:
# Constructor to initialize the node object
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
# Function to initialize head
def __init__(self):
self.head = None
def reverse(self):
prev = None
current = self.head
while(current is not None):
next = current.next
current.next = prev
prev = current
current = next
self.head = prev
= is not equality like in math, it is the assignment/binding operator.
Therefore, after:
current=self.head
current=prev
current will have the value of prev and self.head will have nothing to do with current nor will be modified.

AttributeError: 'int' object has no attribute 'data'

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.

Stack pop using linked list - Python

I am trying to pop an item off a stack (using a linked list as oppose to an array). I first created a LinkedList class with 3 nodes with the values [1,2,3]. So I would like pop off the last node (node_C, value=3), therefore I expect to see the values [1,2]. Instead nothing prints out.
class LinkedList:
def __init__(self, value):
self.value = value
self.next = None
node_A = LinkedList(1)
node_B = LinkedList(2)
node_C = LinkedList(3)
node_A.next = node_B
node_B.next = node_C
def pop(head):
current_node = head
while current_node.next:
if current_node.next == None:
break
else:
current_node = current_node.next
del current_node
return node_A.value, node_B.value, node_C.value
try:
print(pop(node_A))
except NameError:
pass
How can I rewrite this to achieve my desired results (i.e. show values 1,2 .. with 3 popped off)?
The del current node and return node_A.value, node_B.value, node_C.value
commands should belong to the pop function, so they should be intended. But anyway the del current node doesnt work for me. Instead you could write current_node.value = None but then you still return all 3 node values so the result would be 1,2,None.
I would rather write the pop function inside the class and add another printlist function to the class as well. The pop function just removes the last element from the list (changes the next attribute to None for the 2nd last element in the list) and doesn't print or return anything. The printlist function iterates through the list and prints out all elements (while there are next elements). Here is my code:
class LinkedList:
def __init__(self, value):
self.value = value
self.next = None
def pop(self):
current_node = self
while current_node.next:
if current_node.next.next == None:
current_node.next = None
else:
current_node = current_node.next
def printlist(self):
current_node = self
lst = [current_node.value]
while current_node.next:
current_node = current_node.next
lst.append(current_node.value)
print lst
node_A = LinkedList(1)
node_B = LinkedList(2)
node_C = LinkedList(3)
node_A.next = node_B
node_B.next = node_C
try:
node_A.pop()
node_A.printlist()
except NameError:
pass
If I run this, the result is [1,2]. If I remove the node_A.pop() I get [1,2,3]. If I write another node_A.pop() then result is [1]
I guess I have found the issue with your logic, so based on the code provided it seems that pop function doesn't return anything, may be it's just formatting or something else.
But here is the correct version of your code, where I just delete the last node in the pop method and I call another method called listValues which returns me with the node values that exist in the linked list after pop
Look at the below implementation for a clearer view.
class LinkedList:
def __init__(self, value):
self.value = value
self.next = None
node_A = LinkedList(1)
node_B = LinkedList(2)
node_C = LinkedList(3)
node_A.next = node_B
node_B.next = node_C
def pop(head):
current_node = head
while current_node.next:
if current_node.next == None:
del current_node
break
else:
current_node = current_node.next
def listValues(head):
values = []
current_node = head
while current_node.next:
values.append(current_node.value)
current_node = current_node.next
return values
try:
pop(node_A)
print(listValues(node_A))
except NameError:
pass
Hope this helps!

Resources