python int object is not callable? - python

Relatively new to Python.
I'm trying to practice linked list but I'm stuck with an error and couldn't figure out what the issue is.
The error:
self.assertEqual(l.size(), 1)
TypeError: 'int' object is not callable
The code:
from node import Node
class List:
def __init__(self):
self.head = None
self.size = 0
def add(self, item):
temp = Node(item)
temp.setNext(self.head) # ERROR ON THIS LINE
self.head = temp
size += 1
def size(self):
return self.size
...
Node:
class Node:
def __init__(self, data):
self.data = data
self.next = None
....
Test:
import unittest
import unorderedlist
class TestUnorderedList(unittest.TestCase):
def test_add(self):
l = unorderedlist.List()
l.add(8)
self.assertEqual(l.size(), 1)
if __name__ == '__main__':
unittest.main()
It's funny because if I rename the size() to len and call it like l.len() it works fine. Anyone have a clue?

With the line self.size = 0 you hide the methode size, so size is an int and not a method anymore.

You have hidden your method with the attribute.
In your code you are then accessing the attribute which is of type int and so not callable.
Avoid to name methods and attributes the same.
In case you want to achieve properties. There is the #property decorator:
#property
def size(self):
return self._size
In your constructor you just define self._size and work internally with it.

Related

Linked List Implementation Error In Python

So I was trying to make a Linked List in python, but I'm getting this error:
If currentNode.nextNode is None:
AttributeError: 'str' object has no attribute 'nextNode'
Not sure why I get that as currentNode.nextNode should have a .nextNode attribute just like every other node.
Here's the code:
class linkedListNode:
def __init__(self, value, nextNode=None):
self.value=value
self.nextNode=nextNode
class linkedList():
def __init__(self, head=None):
self.head=head
def insert(self, value):
node=linkedListNode(value)
if self.head==None:
self.head=node
return
currentNode = self.head
while True:
if currentNode.nextNode is None:
currentNode.nextNode=node
break
currentNode = currentNode.nextNode
def printLinkedList (self):
curNode=self.head
while curNode!=None:
print(curNode.value)
curNode=curNode.nextNode
#Just testing out the linked list below to see if it works:
ll=linkedList("10")
ll.insert("50")
ll.insert(4)
ll.insert(6)
ll.insert(3)
ll.insert(1)
ll.printLinkedList()
The way you defined linkedList, it expects an instance of linkListNode as an argument, not a value.
ll = linkedList(linkedListNode("10"))
When you initialize the linkedList object you are passing a string as a parameter:
ll=linkedList("10")
As a result self.head will be equal to string "10"

How to call a function and receive parameter in a function outside a linked list class using variables present in linked list

I am using two python files, one file in which a class of linked list present and another file is the one in which I am importing first file so that I can use linked list I built in first file. The second file is for reverse file. I have already done reverse using iteration part, now trying to build a code for reverse using recursion and for that I am calling and passing arguments inside function but something did not work out and it is showing TypeError like this function has no arguments.
Please check it out my code followed by error
Second file
from code.linkedlist import *
llist=linkedlist()
llist.appendnodesatbegin(23)
llist.appendnodesatbegin(45)
llist.appendnodesatbegin(67)
llist.appendnodesatbegin(12)
llist.appendnodesatbegin(-11)
llist.appendnodesatbegin(0)
print ("Before reverse")
llist.display()
def reverseiterative():
llist.current = llist.head
llist.prev = None
while (llist.current):
llist.next = llist.current.next
llist.current.next = llist.prev
llist.prev = llist.current
llist.current = llist.next
llist.head = llist.prev
reverseiterative()
print("After the reverse of list using iterative method")
llist.display()
llist.p=llist.head
llist.prev=None
def reverserecursive(p,prev):
next1=llist.p.next
p.next=prev
if llist.next1 is None:
return
else:
reverserecursive(next1,p)
reverserecursive(llist.p,llist.prev)
print("After the reverse of list using recursive method")
llist.display()
first file:
class node:
def __init__(self,data):
self.data=data
self.next=None
class linkedlist:
def __init__(self):
self.head=None
self.last_pointer=None
def appendnodesatbegin(self,data):
newnode=node(data)
if(self.head==None):
self.head=newnode
self.last_pointer=newnode
else:
self.last_pointer.next=newnode
self.last_pointer=self.last_pointer.next
def appendnodesatend(self,data):
newnode=node(data)
newnode.next=self.head
self.head=newnode
def appendatmid(self,prev,new):
temp=self.head
newnode=node(new)
while(temp):
if(temp.data==prev):
newnode.next=temp.next
temp.next=newnode
temp=temp.next
def display(self):
temp=self.head
while(temp):
print(temp.data)
temp=temp.next
#def reversedisplay(self):
error is
reverseiterative(llist.p,llist.prev)
TypeError: reverseiterative() takes no arguments (2 given)
reverseiterative as defined:
def reverseiterative():
takes no argument, you are calling it with 2.
You were probably supposed to call reverserecursive given the arguments you passed and the argument's in the function signature:
def reverserecursive(p,prev):
Your function doesn't take any parameters in it's deceleration:
reverseiterative(foo, bar):
This (or whatever values you wish to process) will fix it.
from code.linkedlist import *
llist=linkedlist()
llist.appendnodesatbegin(23)
llist.appendnodesatbegin(45)
llist.appendnodesatbegin(67)
llist.appendnodesatbegin(12)
llist.appendnodesatbegin(-11)
llist.appendnodesatbegin(0)
print ("Before reverse")
llist.display()
def reverseiterative(self):
self.current = self.head
self.prev = None
while (self.current):
self.next = self.current.next
self.current.next = self.prev
self.prev = self.current
self.current = self.next
self.head = self.prev
llist.reverseiterative=reverseiterative
llist.reverseiterative()
print("After the reverse of list using iterative method")
llist.display()
def reverserecursive(self,p,prev):
next=p.next
p.next=prev
if next is None:
return
else:
self.reverserecursive(next,p)
llist.p=llist.head
llist.prev=None
llist.reverserecursive(llist.p,llist.prev)
print("After the reverse of list using recursive method")
llist.display()
Here is the second part to fix your issue:
class node:
def __init__(self,data):
self.data=data
self.next=None
class linkedlist:
def __init__(self):
self.head=None
self.last_pointer=None
def appendnodesatbegin(self,data):
newnode=node(data)
if(self.head==None):
self.head=newnode
self.last_pointer=newnode
else:
self.last_pointer.next=newnode
self.last_pointer=self.last_pointer.next
def appendnodesatend(self,data):
newnode=node(data)
newnode.next=self.head
self.head=newnode
def appendatmid(self,prev,new):

object has no attribute error in python

I am new to python programming and I have encountered an error for the below mentioned program. It is a simple program to add a node to the end of the linked list. The error says object LinkedList has no attribute head. Please Help me with the problem.
class Node:
def _init_(self, data):
self.data = data
self.next = None
class LinkedList:
def _init_(self):
self.head=None
def createNode(self, data):
newNode = Node(data)
return newNode
def insertNodeHelper(self, head, data):
if(head==None):
return self.createNode(data)
head.next = self.insertNodeHelper(head.next,data)
return head
def insertNode(self, data):
self.head = self.insertNodeHelper(self.head,data)
def printList(self, head):
if(head==None):
return;
print(head.data)
self.printList(head.next)
def printLinkedList(self):
self.printList(self.head)
l = LinkedList()
l.insertNode(12)
l.insertNode(13)
l.insertNode(15)
l.printList()
I am getting the following error:
Message File Name Line Position
Traceback
<module> <module1> 35
insertNode <module1> 21
AttributeError: 'LinkedList' object has no attribute 'head'
Change def _init_(self): to def __init__(self):(two underscore). Because this method is a constructor method, it must be writen in this form.

Creating python objects of same type from nested class

My List class has a nested _Node class within it. With these 2 classes, I can:
Initialize an object of type List within List.
Initialize an object of type _Node within List.
Initialize an object of type List within _Node.
I can't, however, initialize a _Node within a _Node. The last line of the code is below causes NameError: global name '_Node' is not defined
class List:
def __init__(self):
self.root = None
self.brother = None
def set_root(self):
self.root = self._Node()
def set_brother(self):
self.brother = List()
def set_root_next(self):
self.root.set_next()
class _Node:
def __init__(self, next_node=None, data=None):
self.next_node = next_node
self.data = data
def set_next(self):
self.next_node = _Node()
if __name__ == '__main__':
x = List()
x.set_root()
x.set_brother()
x.set_root_next()
How do I solve this? Making the _Node class unnested works but I am planning to have many types of list in the same file. All accompanying nodes will inherit from a single abstract class so keeping this structure is important.
Try using self.__class__() instead
class List:
def __init__(self):
self.root = None
self.brother = None
def set_root(self):
self.root = self._Node()
def set_brother(self):
self.brother = List()
def set_root_next(self):
self.root.set_next()
class _Node:
def __init__(self, next_node=None, data=None):
self.next_node = next_node
self.data = data
def set_next(self):
self.next_node = self.__class__()
if __name__ == '__main__':
x = List()
x.set_root()
x.set_brother()
x.set_root_next()

Using a callback function to find the sum of values in a bst (without a global)

I've got a binary search tree full of objects. I'm traversing the tree using a callback function that adds a property of all the objects to a global variable. I've got this working, but I'd like to find a way to accomplish this without using a global.
Here's the relevant code:
TOTAL_AGE = 0.0
class Node(object):
def __init__(self, data):
self.left = None
self.right = None
self.data = data
class Tree(object):
def __init__(self):
self.root = None
self.size = 0
def traverse(self, callback):
self._traverse(callback, self.root)
def _traverse(self, callback, node):
if node is None:
return
self._traverse(callback, node.left)
callback(node.data)
self._traverse(callback, node.right)
def add_ages(tree):
tree.traverse(callback)
def callback(student):
global TOTAL_AGE
TOTAL_AGE += student.age
def main():
tree = bst.Tree()
add_ages(tree)
print TOTAL_AGE
This is admittedly for an assignment, which requires that I use the current traverse function and not a different implementation. That's mainly my issue though because I don't see a way to do this without using a global or modifying traverse().
Thanks in advance for any help.
You could pass a method of a class instance as callback so that you can keep track of the state in the instance:
class Count(object):
def __init__(self):
self.total_age = 0
def callback(self, student):
self.total_age += student.age
And then instantiate Count and pass its callback method to the Tree:
count = Count()
tree.traverse(count.callback)

Categories