Python Tree data structure, TypeError - python

The code is written is meant to calculate the number of nodes in a tree. However, I am getting a simple type error that keeps referring back to my TreeNode class. I have checked for spellings and typos, but I still can't find the error. Please help
Here is the error
Traceback (most recent call last):
File "C:/Users/Eli/.PyCharmCE2019.2/config/scratches/Tree.py", line 30, in <module>
t1.addChild(t1.Root(),6)
TypeError: 'TreeNode' object is not callable
class TreeNode():
def __init__(self, data= None, parent = None):
self.data = data
self.children = []
self.parent = parent
class Tree():
def __init__(self):
self.Root = None
self.size = 0
def __len__(self):
return self.size
def root (self):
return self.Root
def children (self, node):
return node.children()
def addChild (self,parent,data):
t = TreeNode (data,parent)
if parent == None:
self.Root = t
else:
parent.children.append(t)
self.size +=1
def printTreePreOrder(self,node):
print(node.data)
for n in node.children:
self.printTreePreOrder(n)
if __name__ == "__main__":
t1 = Tree()
t1.addChild(None,5)
t1.addChild(t1.Root(),6)
cl = t1.children(t1.Root())
for n in cl:
t1.addChild(n,3)
t1.addChild(n,9)
t1.printTreePr

t1.Root() should probably be t1.Root because your root is a TreeNode object instead of a function to find the root.
You will likely hit a similar wall when accessing node.children()

Related

Problem in traversing a linked list after finding the middle node

I'm just starting to learn Algorithms and Data Structures in Python and I've come across this linked list problem. Overall I've managed to find the middle node the naive way but I don't understand why after the list is traversed it doesn't output the last print command.
This is the traverse function:
def traverse(self):
actual_node = self.head
print("----------")
while actual_node is not None:
print(actual_node.data)
actual_node = actual_node.next
print("----------") # This is not displayed in the output
Here is the entire program:
# Linked List Question
# Construct an algorithm that's able to find the middle node and traverse the list
class Node:
def __init__(self, data):
self.data = data
self.next = Node
class LinkedList:
def __init__(self):
self.head = None
self.size = 0
def insert_start(self, data):
self.size += 1
new_node = Node(data)
if not self.head:
self.head = new_node
else:
new_node.next = self.head
self.head = new_node
def size_of_linkedList(self):
return self.size
def traverse(self):
actual_node = self.head
print("----------")
while actual_node is not None:
print(actual_node.data)
actual_node = actual_node.next
print("----------")
def middle_node(self):
actual_node = self.head
sizeofNode = 0
while actual_node is not None:
if sizeofNode == self.size // 2:
print("This is the middle node: " + str(actual_node))
print("This is the middle node data: " + str(actual_node.data))
break
else:
actual_node = actual_node.next
sizeofNode += 1
if __name__ == "__main__":
linked_list = LinkedList()
linked_list.insert_start(0)
linked_list.insert_start(1)
linked_list.insert_start(2)
linked_list.insert_start(3)
linked_list.insert_start(4)
linked_list.insert_start(5)
linked_list.insert_start(6)
print("The size of the list is: %d" % linked_list.size_of_linkedList())
linked_list.middle_node()
linked_list.traverse()
These are the errors I receive:
Traceback (most recent call last):
File "linkedListQ1.py", line 66, in <module>
linked_list.traverse()
File "linkedListQ1.py", line 33, in traverse
print(actual_node.data)
AttributeError: type object 'Node' has no attribute 'data'
This is the output:
The size of the list is: 7
This is the middle node: <__main__.Node object at 0x7fb6ee6d1d00>
This is the middle node data: 3
----------
6
5
4
3
2
1
0
The problem with the program besides the errors is that the print("----------") doesn't get executed after the last element of the node. Could someone explain what is it that I'm doing wrong and offer code snippets. Thank you in advance.
This is a simple typo - it should be self.next = None rather than self.next = Node in the .__init__ method.
Note the fun error message - it says "AttributeError: type object 'Node' has no attribute 'data'" and not "AttributeError: 'Node' object has no attribute 'data'". (Well; at least I think it's fun.)

Recursive function in Binary Search Tree returning None (Python)

I am writing a code to search for elements in a binary search tree.
I wrote the code inside the class BinarySearchTree but it returns None.
class Node:
def __init__(self, info):
self.info = info
self.left = None
self.right = None
self.level = None
class BinarySearchTree:
def __init__(self):
self.root = None
def search(self, key):
a = search(self.root)
if self.root is None or self.root == key:
return self.root
if key > self.root:
return self.search(self.root.right)
return self.search(self.root.left)
I tried storing self.search(self.root.right) and self.search(self.root.left) into variables and then returned them using or but still I get None as output.
class Node:
def __init__(self, info):
self.info = info
self.left = None
self.right = None
self.level = None
class BinarySearchTree:
def __init__(self):
self.root = None
def search(self, key):
a = search(self.root)
if self.root is None or self.root == key:
return self.root
if key > self.root:
a = self.search(self.root.right)
b = self.search(self.root.left)
return a or b
I do not understand what I am doing wrong here and why the output is coming as None.
(I am a beginner and this is my first time asking a question here so please forgive me if I have made any silly mistake.)
This was my input
r = Node(1)
r.left = Node(2)
r.right = Node(3)
r.left.left = Node(4)
r.left.right = Node(5)
r.right.right = Node(6)
r.right.left = Node(7)

Python Data structures binary search tree

I can't figure out the type of error that I'm getting.
Traceback (most recent call last):
File "C:/Users/Eli/.PyCharmCE2019.2/config/scratches/BinarySearchTree.py", line 43, in
bt.printTreePreOrder(bt.Root())
TypeError: 'NoneType' object is not callable
class BinaryTreeNode:
def __init__(self,key, data = None):
self.key = key
self.value = data
self.left = None
self.right = None
class BinarySearchTree:
def __init__(self):
self.Root = None
self.size = 0
def __len__(self):
return self.size
def root (self):
return self.Root
def insert(self,key,data):
new_node = BinaryTreeNode(key,data)
x = self.Root
y = None
while x != None:
y = x
if key < y.key:
x = x.left
else:
x = x.right
if y == None:
self. key < y.key
y.left = new_node
else:
y.right = new_node
self.size +=1
def printTreePreOrder(self,node):
print(node.key)
if node.left:
self.printTreePreOrder(node.left)
if node.right:
self.printTreePreOrder(node.right)
if __name__ == "__main__":
bt = BinarySearchTree()
bt.insert(12,'bill')
bt.insert(6,'Tom')
bt.insert(14,'jill')
bt.insert(3,'guy')
bt.printTreePreOrder(bt.Root())
You're attempting to call Root as if it were a function, but it's only a member variable of class BinaryTreeNode, therefore is not callable.
Furthermore, it is returning as NoneType because you initialize it to None and it is never assigned to any other value.
The way you have it implemented, you should do bt.printTreePreOrder(bt.Root)

NameError: name "AnyName" is not defined

I am trying to do an N-Ary tree based on Linked-Lists and Nodes. But whenever I try to add a new value to the tree I keep getting:
NameError: name 'self' is not defined
I work with modules so I have to import the classes from other files.
I get this error in def addTree(self, value, parent = self.root): on Tree Code
Tree Code
from Resources.LinkedList import *
class Tree:
def __init__(self):
self.root = LinkedList()
def addTree(self, value, parent = self.root):
parent.addLinkedList(value)
Node Code
from Resources.LinkedList import *
class Node:
def __init__(self,name):
self.name = name
self.children = LinkedList()
self.next = None
Linked-List Code
from Resources.Node import *
from Resources.Compare import *
class LinkedList:
def __init__(self):
self.first = None
def addLinkedList(self,value):
if (not self.first):
self.first = Node(value)
else:
compare = Compare()
if(compare.compare(self.first,value)>0):
stack = self.first
self.first = Node(value)
self.first.next = stack
return True
else:
previous = self.first
current = self.first.next
while(current):
if (compare.compare(current,value)<0):
previous = current
current = current.next
return True
elif (compare.compare(current,value)>0):
stack = current
previous.next = Node(value)
previous.next.next = stack
return True
else:
previous.next = Node(value)
previous.next.next = current.next
return True
previous.next = Node(value)
return True
Also thanks for your help, I'm kinda new to Python and I don't know what I am doing wrong.
The problem is that "self" is only defined within the method and cannot be used in the arguments, the trick in these cases is to use None as an argument and make the verification:
def addTree(self, value, parent = None):
if parent is None:
parent = self.root
parent.addLinkedList(value)

Binary Search Tree operations

I am trying to implement Binary Search Tree operations in python. As of now, I have written some code to add nodes to this search tree (sorted).
Here's what I've in my code:
class TreeNode:
def __init__(self, data):
self.data = data
self.lLink = None
self.rLink = None
class BinaryTree:
def __init__(self):
self.root = None
def AddNode(self, data):
if self.root is None:
self.root = TreeNode(data)
else:
if data < self.root.data:
if self.root.lLink is None:
self.root.lLink = TreeNode(data)
else:
AddNode(self.root.lLink, data)
else:
if self.root.rLink is None:
self.root.rLink = TreeNode(data)
else:
AddNode(self.root.rLink, data)
def InOrder(self, head):
if self.root.lLink is not None:
InOrder(self.root.lLink)
print self.root.data,
if self.root.rLink is not None:
InOrder(self.root.rLink)
myTree = BinaryTree()
myTree.AddNode(15)
myTree.AddNode(18)
myTree.AddNode(14)
How do I test if my AddNode() method is correct? I know the algorithm but just to be sure.
What I was thinking of is to create an InOrder() method and try to print elements through this InOrder traversal. As a result, my data added to the tree should be displayed in sorted order. If it is displayed in sorted order, I'll be sure that both my AddNode() and InOrder() methods are correct.
Your BinaryTree class is faulty, changing the order of insertions to
myTree.AddNode(14)
myTree.AddNode(18)
myTree.AddNode(15)
raises an error - NameError: global name 'AddNode' is not defined.
This is because in the lines, AddNode(self.root.rLink, data) and AddNode(self.root.lLink, data) you seem to be calling the AddNode function on instances of TreeNode which is not possible. I fixed up some of the errors in your code and it should work great now.
class TreeNode:
def __init__(self, data):
self.data = data
self.lLink = None
self.rLink = None
class BinaryTree:
def __init__(self):
self.root = None
def AddNode(self, data):
if self.root is None:
self.root = TreeNode(data)
else:
self.AddHelper(data, self.root)
def AddHelper(self, data, startingPoint):
if data < startingPoint.data:
if startingPoint.lLink is None:
startingPoint.lLink = TreeNode(data)
else:
self.AddHelper(data, startingPoint.lLink)
else:
if startingPoint.rLink is None:
startingPoint.rLink = TreeNode(data)
else:
self.AddHelper(data, startingPoint.rLink)
def InOrder(self):
self.InOrderHelper(self.root)
def InOrderHelper(self, startingPoint):
if startingPoint is None:
return
self.InOrderHelper(startingPoint.lLink)
print startingPoint.data,
self.InOrderHelper(startingPoint.rLink)
Output Test :
>>> myTree = BinaryTree()
>>> myTree.AddNode(14)
>>> myTree.AddNode(18)
>>> myTree.AddNode(15)
>>> myTree.InOrder()
14 15 18
Inserting can be a little tricky, especially because the function is a part of the tree itself. So, you call the insert function on the tree, but specifying a starting point. This defaults to root, so you can leave the argument when you call the function.
Also, I think you are a little unclear about how self works in a function. You cannot pass it as an argument to the function, which is what it seems you have done.
class TreeNode:
def __init__(self, data):
self.data = data
self.rLink = None
self.lLink = None
class BinaryTree:
def __init__(self):
self.root = None
def AddNode(self, data, node=None):
if not node :
node = self.root
if self.root is None:
self.root = TreeNode(data)
else:
if data < node.data:
if node.lLink is None:
node.lLink = TreeNode(data)
else:
self.AddNode(data, self.root.lLink)
else:
if node.rLink is None:
node.rLink = TreeNode(data)
else:
self.AddNode(data, self.root.rLink)
def InOrder(self, head):
if head.lLink is not None:
self.InOrder(head.lLink)
print head.data,
if head.rLink is not None:
self.InOrder(head.rLink)
myTree = BinaryTree()
myTree.AddNode(14)
myTree.AddNode(15)
myTree.AddNode(18)
myTree.InOrder(myTree.root)
Testing the insert function with an in-order traversal is the best approach.
This should work. You are not going down the tree if you use self.root.lLink every time.
Optionally, you could write one more line of code to check if the output is indeed in ascending order.

Categories

Resources