In [ ]:
class Node:
    
    def __init__(self, data):
        self.value = data
        self.smaller = None
        self.larger = None
        
    def __str__(self):
        return str(self.value)
    
class BinTree:
    def __init__(self,lst=[]):
        self.root = None
        self.size = 0
        for x in lst:
            self.insert(x)
    
    def insert(self,data):
        if self.root is None:
            self.root = Node(data)
            self.size += 1
        else:
            current = self.root
            while True:
                if data == current.value:
                    return
                if data < current.value:
                    if current.smaller is None:
                        current.smaller = Node(data)
                        self.size += 1
                        return
                    else:
                        current = current.smaller
                else:
                    if current.larger is None:
                        current.larger = Node(data)
                        self.size += 1
                        return
                    else:
                        current = current.larger

    def length(self):
        return self.size
    
    def has(self,data):
        current = self.root
        while True:
            if current is None:
                return False
            if data == current.value:
                return True
            if data < current.value:
                current = current.smaller
            else:
                current = current.larger
    
    def get_ordered_list(self):
        # yes, we can create a helper-function inside a method and then use it
        def build_list(current,answer):
            if current.smaller:  # this is the same as "if current.smaller != None" or "if current.smaller is not None"
                build_list(current.smaller,answer)
            answer.append(current.value)
            if current.larger:
                build_list(current.larger,answer)
                
        if self.root is None:
            return []
        answer = []
        build_list(self.root,answer)
        return answer

    def clear(self):
        def clear_subtree(subtree):
            # walk the list, and from the bottom up, set all nodes' smaller and larger pointers to None
            if subtree.smaller:
                clear_subtree(subtree.smaller)
            subtree.smaller = None
            if subtree.larger:
                clear_subtree(subtree.larger)
            subtree.larger = None
            
        if self.root:
            clear_subtree(self.root)
            self.root = None
        self.size = 0