# Path: py_algorithms/trees/bst_from_list.py
# class BstFromList:
#     @staticmethod
#     def apply(xs: List[Any]) -> Union[TreeNode, None]:
#         return BstFromList._apply(xs, 0, len(xs) - 1)
# 
#     @staticmethod
#     def _apply(xs: List[Any], lo: int, hi: int) -> Union[TreeNode, None]:
#         if lo > hi:
#             return None
# 
#         mid = (lo + hi) // 2
# 
#         root = new_tree_node(element=xs[mid])
#         root.set_left(BstFromList._apply(xs, lo, mid - 1))
#         root.set_right(BstFromList._apply(xs, mid + 1, hi))
# 
#         return root


from math import ceil
from math import log2
from py_algorithms.trees.bst_from_list import BstFromList



def tree_height(root):
    if root is None:
        return 0
    return 1 + max(tree_height(root.left), tree_height(root.right))


class TestBstFromList:
    def test_apply(self):
        exponent = 7
        xs = list(range((2 ** exponent) - 1))
        tree = BstFromList.apply(xs)

# Path: py_algorithms/trees/bst_from_list.py
# class BstFromList:
#     @staticmethod
#     def apply(xs: List[Any]) -> Union[TreeNode, None]:
#         return BstFromList._apply(xs, 0, len(xs) - 1)
# 
#     @staticmethod
#     def _apply(xs: List[Any], lo: int, hi: int) -> Union[TreeNode, None]:
#         if lo > hi:
#             return None
# 
#         mid = (lo + hi) // 2
# 
#         root = new_tree_node(element=xs[mid])
#         root.set_left(BstFromList._apply(xs, lo, mid - 1))
#         root.set_right(BstFromList._apply(xs, mid + 1, hi))
# 
#         return root


# Path: tests/py_algorithms/trees/bst_from_list_test.py
from math import ceil
from math import log2
from py_algorithms.trees.bst_from_list import BstFromList




def tree_height(root):
    if root is None:
        return 0
    return 1 + max(tree_height(root.left), tree_height(root.right))


class TestBstFromList:
    def test_apply(self):
        exponent = 7
        xs = list(range((2 ** exponent) - 1))
        tree = BstFromList.apply(xs)

        height = tree_height(tree)