Skip to content

Instantly share code, notes, and snippets.

@WhiskersReneeWe
Last active June 19, 2019 20:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WhiskersReneeWe/8ea977822fd5d1457c262607a1a8d2ec to your computer and use it in GitHub Desktop.
Save WhiskersReneeWe/8ea977822fd5d1457c262607a1a8d2ec to your computer and use it in GitHub Desktop.
# A RouteTrieNode will be similar to our autocomplete TrieNode... with one additional element, a handler.
class RouteTrieNode(object):
def __init__(self, handler = 'root handler', default_handler = 'not found handler'):
# Initialize the node with children as before, plus a handler
self.children = {}
self.handler = handler
self.default_handler = default_handler
def insert(self, part, part_handler):
# Insert the node as before
"""
arg1: part - an item from path_list
arg2: part_handler - the corresponding handler for the current node
"""
if part not in self.children:
self.children[part] = RouteTrieNode(handler = part_handler)
# A RouteTrie will store our routes and their associated handlers
class RouteTrie:
def __init__(self, handler = 'root handler', default_handler = 'not found handler'):
# Initialize the trie with an root node and a handler, this is the root path or home page node
self.root = RouteTrieNode(handler, default_handler)
def Trieinsert(self, path_list, handler):
# Similar to our previous example you will want to recursively add nodes
# Make sure you assign the handler to only the leaf (deepest) node of this path
# ['about', 'me']
curr_node = self.root
for part in path_list:
if part not in curr_node.children:
curr_node.insert(part, curr_node.default_handler)
curr_node = curr_node.children[part]
curr_node.handler = handler
def find(self, path_list):
# Starting at the root, navigate the Trie to find a match for this path
# Return the handler for a match, or None for no match
curr_node = self.root
for part in path_list:
if part in curr_node.children:
curr_node = curr_node.children[part]
else:
return None
break
return curr_node.handler
#The Router class will wrap the Trie and handle
class Router:
def __init__(self, handler = 'root handler', default_handler = 'Not Found Handler'):
# Create a new RouteTrie for holding our routes
# You could also add a handler for 404 page not found responses as well!
self.RouterTrie = RouteTrie(handler, default_handler)
self.RouterTrie.root_handler = handler
def add_handler(self, new_path, path_handler):
# Add a handler for a path
# You will need to split the path and pass the path parts
new_path_list = self.split_path(new_path)
return self.RouterTrie.Trieinsert(new_path_list, path_handler)
def lookup(self, path):
# lookup path (by parts) and return the associated handler
# you can return None if it's not found or
# return the "not found" handler if you added one
# bonus points if a path works with and without a trailing slash
# e.g. /about and /about/ both return the /about handler
path_list = self.split_path(path)
if path_list == ['', '']:
return self.RouterTrie.root_handler
return self.RouterTrie.find(path_list)
def split_path(self, path):
# you need to split the path into parts for
# both the add_handler and loopup functions,
# so it should be placed in a function here
path_parts = path.split('/')
return path_parts
# Here are some test cases and expected outputs you can use to test your implementation
# create the router and add a route
router = Router("root handler", "not found handler") # remove the 'not found handler' if you did not implement this
router.add_handler("/home/about", "about handler") # add a route
# some lookups with the expected output
print(router.lookup("/")) # should print 'root handler'
print(router.lookup("/home")) # should print 'not found handler' or None if you did not implement one
print(router.lookup("/home/about")) # should print 'about handler'
print(router.lookup("/home/about/")) # should print 'about handler' or None if you did not handle trailing slashes
print(router.lookup("/home/about/me")) # should print 'not found handler' or None if you did not implement one
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment