input: Write a function to insert elements into an AVL tree and verify its balanced property using pre-order traversal.
  assert avl_tree.preOrder(root) == [20, 10, 30, 5, 15, 25, 35]
  assert avl_tree.preOrder(root) == [30, 20, 40, 10, 25, 35, 50]
  assert avl_tree.preOrder(root) == [40, 20, 50, 10, 30, 60, 70]
output: class TreeNode:
      def __init__(self, key):
          self.left = None
          self.right = None
          self.val = key
          self.height = 1
  
  class AVL_Tree:
      def insert(self, root, key):
          if not root:
              return TreeNode(key)
          elif key < root.val:
              root.left = self.insert(root.left, key)
          else:
              root.right = self.insert(root.right, key)
  
          root.height = 1 + max(self.getHeight(root.left), self.getHeight(root.right))
  
          balance = self.getBalance(root)
  
          if balance > 1 and key < root.left.val:
              return self.rightRotate(root)
          if balance < -1 and key > root.right.val:
              return self.leftRotate(root)
          if balance > 1 and key > root.left.val:
              root.left = self.leftRotate(root.left)
              return self.rightRotate(root)
          if balance < -1 and key < root.right.val:
              root.right = self.rightRotate(root.right)
              return self.leftRotate(root)
  
          return root
  
      def leftRotate(self, z):
          y = z.right
          T2 = y.left
  
          y.left = z
          z.right = T2
  
          z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right))
          y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right))
  
          return y
  
      def rightRotate(self, z):
          y = z.left
          T3 = y.right
  
          y.right = z
          z.left = T3
  
          z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right))
          y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right))
  
          return y
  
      def getHeight(self, root):
          if not root:
              return 0
          return root.height
  
      def getBalance(self, root):
          if not root:
              return 0
          return self.getHeight(root.left) - self.getHeight(root.right)
  
      def preOrder(self, root):
          res = []
          if root:
              res.append(root.val)
              res = res + self.preOrder(root.left)
              res = res + self.preOrder(root.right)
          return res
  
  avl_tree = AVL_Tree()
  root = None
  keys = [20, 10, 30, 5, 15, 25, 35]
  for key in keys:
      root = avl_tree.insert(root, key)
  assert avl_tree.preOrder(root) == [20, 10, 30, 5, 15, 25, 35]
  
  root = None
  keys = [30, 20, 40, 10, 25, 35, 50]
  for key in keys:
      root = avl_tree.insert(root, key)
  assert avl_tree.preOrder(root) == [30, 20, 40, 10, 25, 35, 50]
  
  root = None
  keys = [40, 20, 50, 10, 30, 60, 70]
  for key in keys:
      root = avl_tree.insert(root, key)
  assert avl_tree.preOrder(root) == [40, 20, 50, 10, 30, 60, 70]