1

I am trying to do insert function in python for BST but I am just confused on how to access the public methods properly and its giving me some grief, right now when I test it it just stops at the first test and says nonetype object has no attribute data but how am I suppose to access data when t = tree() and tree doesn't have a data constructor?

class Node(object):
    def __init__(self, data):
       self.parent = None
       self.left = None
       self.right = None
       self.data = data

class Tree(object):
# Binary Search Tree
# class constants
PREORDER = 1
INORDER = 2
POSTORDER = 3

   def __init__(self):
    # Do not create any other private variables.
    # You may create more helper methods as needed.
       self.root = None

   def print(self):
    # Print the data of all nodes in order
      self.__print(self.root)


   def __print(self, curr_node):
    # Recursively print a subtree (in order), rooted at curr_node
       if curr_node is not None:
           self.__print(curr_node.left)
           print(str(curr_node.data), end=' ')  # save space
           self.__print(curr_node.right)


   def insert(self, data):
    # Find the right spot in the tree for the new node
    # Make sure to check if anything is in the tree
    # Hint: if a node n is null, calling n.getData() will cause an error
      root = Node(data)
      print("this is my", self.root)
      if self.root is None:
          self.root = root
          return Node(data)
      else:
          if root.data == data:
              return root
          elif root.data < data:
              root.right = insert(root.right,data)
          else:
              root.left = insert(root.left, data)
      return root

And this is the test cases that I'm running with

import lab3
import unittest

class T0_tree__insert(unittest.TestCase):

    def test_balanced_binary_search_tree(self):
        print("\n")
        print("tree_insert_with_individual_check")
        t = lab3.Tree()

        t.insert(4)
        t.insert(2)
        t.insert(6)
        t.insert(1)
        t.insert(3)
        t.insert(5)
        t.insert(7)

        #The following check is without using tree as an iterator (which uses inorder traversal)
        #So this function also does not check the implementation of the traversal function

        self.assertEqual(t.root.data, 4)
        self.assertEqual(t.root.left.data, 2)
        self.assertEqual(t.root.left.left.data, 1)
        self.assertEqual(t.root.left.right.data, 3)
        self.assertEqual(t.root.right.data, 6)
        self.assertEqual(t.root.right.left.data, 5)
        self.assertEqual(t.root.right.right.data, 7)

        print("\n")
2
  • Would you mind fixing the indentation on your code. It's hard to tell what's a function and what's a method. Commented Nov 8, 2020 at 22:38
  • Definitely just edited it! Commented Nov 8, 2020 at 22:50

1 Answer 1

3

Provided two options

  1. Adds a helper function for insert to Tree (similar to helper print function __print). This allows keeping track of node we are traversing in the tree
  2. Non-recursive insert which processes through nodes.

Both options satisfy unittest.

Option 1 - Add a utility function to insert

File labe3.py

class Node(object):
    def __init__(self, data):
        self.parent = None
        self.left = None
        self.right = None
        self.data = data

class Tree(object):
    # Binary Search Tree
    # class constants
    PREORDER = 1
    INORDER = 2
    POSTORDER = 3

    def __init__(self):
        # Do not create any other private variables.
        # You may create more helper methods as needed.
        self.root = None

    def print(self):
        # Print the data of all nodes in order
        self.__print(self.root)

    def __print(self, curr_node):
        # Recursively print a subtree (in order), rooted at curr_node
        if curr_node is not None:
            self.__print(curr_node.left)
            print(str(curr_node.data), end=' ')  # save space
            self.__print(curr_node.right)

    def insert(self, d):
        print("this is my", self.root)
        if self.root is None:
          self.root = Node(d)
        else:
          self._insert(self.root, d) # here's the call to a "private" function to which we are passing nodes down, starting from root

    def _insert(self, node, value):
        ''' helper function for insert 
               node - node in BST to add value
               value - value to add
        '''
        if value < node.data:  # we know that `node` cannot be None 
                               # so it's safe to check its value! 
              if node.left:
                self._insert(node.left, value) # the recursive call is done only when `node.left` is not None
              else:
                node.left = Node(value)  # direct assignment
        else:
            if node.right:
                self._insert(node.right, value)
            else:
                node.right = Node(value)  # direct assignment
        

Option 2-non-recursive insert function

File labe3.py

class Node(object):
    def __init__(self, data):
        self.parent = None
        self.left = None
        self.right = None
        self.data = data

class Tree(object):
    # Binary Search Tree
    # class constants
    PREORDER = 1
    INORDER = 2
    POSTORDER = 3

    def __init__(self):
        # Do not create any other private variables.
        # You may create more helper methods as needed.
        self.root = None

    def print(self):
        # Print the data of all nodes in order
        self.__print(self.root)

    def __print(self, curr_node):
        # Recursively print a subtree (in order), rooted at curr_node
        if curr_node is not None:
            self.__print(curr_node.left)
            print(str(curr_node.data), end=' ')  # save space
            self.__print(curr_node.right)

    def insert(self, d):
        print("this is my", self.root)
        if self.root is None:
          self.root = Node(d)
        else:
          # current node
          current = self.root

          # Finds node to add data
          while True:
              if current.data > d:
                  if current.left == None:
                      current.left = Node(d)
                      break
                  else:
                      current = current.left

              elif current.data < d:
                  if current.right == None:
                      current.right = Node(d)
                      break
                  else:
                      current = current.right

              else:  
                break
       

File main.py

import lab3
import unittest

class T0_tree__insert(unittest.TestCase):

    def test_balanced_binary_search_tree(self):
        print("\n")
        print("tree_insert_with_individual_check")
        t = lab3.Tree()

        t.insert(4)
        t.insert(2)
        t.insert(6)
        t.insert(1)
        t.insert(3)
        t.insert(5)
        t.insert(7)

        #The following check is without using tree as an iterator (which uses inorder traversal)
        #So this function also does not check the implementation of the traversal function

        self.assertEqual(t.root.data, 4)
        self.assertEqual(t.root.left.data, 2)
        self.assertEqual(t.root.left.left.data, 1)
        self.assertEqual(t.root.left.right.data, 3)
        self.assertEqual(t.root.right.data, 6)
        self.assertEqual(t.root.right.left.data, 5)
        self.assertEqual(t.root.right.right.data, 7)

        print("\n")
        
if __name__ == '__main__':
    unittest.main()

Output

tree_insert_with_individual_check
this is my None
this is my <lab3.Node object at 0x7fa4386b92e0>
this is my <lab3.Node object at 0x7fa4386b92e0>
this is my <lab3.Node object at 0x7fa4386b92e0>
this is my <lab3.Node object at 0x7fa4386b92e0>
this is my <lab3.Node object at 0x7fa4386b92e0>
this is my <lab3.Node object at 0x7fa4386b92e0>


.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
Sign up to request clarification or add additional context in comments.

2 Comments

Unfortunately this is part of a homework assignment and im pretty sure im not allowed to switch the insert function into node like that. Is there any other way I can access the node function how the test cases indicate it should be accessed?
@PatTheTrickster--added two options that kept functionality within Tree. The first option is similar to the way print is implemented to traverse the Tree.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.