input: Write a Python function to implement a trie data structure with insert and search methods.
  assert trie.search("apple") == True
  assert trie.search("application") == True
  assert trie.search("hi") == True
  assert trie.search("hello") == False
output: class TrieNode:
      def __init__(self):
          self.children = {}
          self.is_end_of_word = False
  
  class Trie:
      def __init__(self):
          self.root = TrieNode()
      
      def insert(self, word):
          node = self.root
          for char in word:
              if char not in node.children:
                  node.children[char] = TrieNode()
              node = node.children[char]
          node.is_end_of_word = True
      
      def search(self, word):
          node = self.root
          for char in word:
              if char not in node.children:
                  return False
              node = node.children[char]
          return node.is_end_of_word
  
  # Example usage
  trie = Trie()
  trie.insert("apple")
  trie.insert("application")
  trie.insert("hi")