diff --git a/Python/chapter04/p07_build_order/miguelHx.py b/Python/chapter04/p07_build_order/miguelHx.py
new file mode 100644
index 00000000..a8225e00
--- /dev/null
+++ b/Python/chapter04/p07_build_order/miguelHx.py
@@ -0,0 +1,192 @@
+"""Python Version 3.9.2
+4.7 - Build Order:
+You are given a list of projects and a list of dependencies
+(which is a list of pairs of projects, where the second project is dependent on the first project).
+All of a project's dependencies must be built before the project is.
+Find a build order that will allow the projects to be built. If there is no
+valid build order, return an error.
+EXAMPLE
+Input:
+    projects:  a, b, c, d, e, f
+    dependencies: (a, d), (f, b), (b, d), (f, a), (d, c)
+Output:
+    f, e, a, b, d, c
+"""
+import unittest
+
+from dataclasses import dataclass
+from typing import List, Set, Tuple, Dict
+
+
+@dataclass
+class Node:
+    id: int
+    children: 'List[Node]'
+
+    def add_child(self, *nodes: 'Node'):
+        for node in nodes:
+            self.children.append(node)
+
+    def children_as_str(self) -> str:
+        return ', '.join(str(child.id) for child in self.children)
+
+    def print_children(self):
+        print('Adjacency list for node {}: {}'.format(self.id, self.children_as_str()))
+
+    def __str__(self):
+        return f'Node ({self.id}), children: {self.children_as_str()}'
+
+
+@dataclass
+class DependencyNode:
+    id: str
+    children: 'List[DependencyNode]'
+
+    def add_child(self, *nodes: 'DependencyNode'):
+        for node in nodes:
+            self.children.append(node)
+
+    def children_as_str(self) -> str:
+        return ', '.join(str(child.id) for child in self.children)
+
+    def print_children(self):
+        print('Adjacency list for node {}: {}'.format(self.id, self.children_as_str()))
+
+    def __str__(self):
+        return f'Node ({self.id}), children: {self.children_as_str()}'
+
+@dataclass
+class DependencyGraph:
+    nodes: 'List[DependencyNode]'
+
+    def print_graph(self):
+        for node in self.nodes:
+            node.print_children()
+
+
+def build_order(projects: List[str], dependencies: List[Tuple[str, str]]) -> List[str]:
+    """Given a list of projects and dependencies,
+    this function will find a build order that will
+    allow the projects to be build given the dependencies.
+    If there is no valid build order, an error will be raised.
+    All of a project's dependencies must be built before the project
+    is.
+
+    EXAMPLE
+    Input:
+        projects:  a, b, c, d, e, f
+        dependencies: (a, d), (f, b), (b, d), (f, a), (d, c)
+    Output:
+        f, e, a, b, d, c
+
+    Args:
+        projects (List[str]): a list of projects
+        dependencies (List[Tuple[str, str]]):
+            a list of pairs of dependencies (2nd project is dependent on 1st)
+
+    Returns:
+        List[str]: a valid build order
+    """
+    # 0. define output
+    output: List[str] = []
+    # 1. build a dependency graph
+    project_to_node_map: Dict[str, DependencyNode] = {}
+    for p in projects:
+        project_to_node_map[p] = DependencyNode(p, [])
+    for d in dependencies:
+        p1 = d[0]
+        p2 = d[1]
+        project_to_node_map[p2].add_child(project_to_node_map[p1])
+    nodes = []
+    for node in project_to_node_map.values():
+        nodes.append(node)
+    # g = DependencyGraph(nodes)
+    # print("BUILT GRAPH, HERE IS RESULT:")
+    # g.print_graph()
+
+    # 2. define set to keep track of what we already built
+    projects_built: Set[str] = set()
+    # 3. for each project node, perform a depth-first search
+    for project_node in project_to_node_map.values():
+        # 4. perform a depth first search
+        visited = set()
+        stack = []
+        stack.append(project_node)
+        not_built = []
+        while stack:
+            node = stack.pop()
+            if node.id not in visited:
+                visited.add(node.id)
+            # get adjacent vertices of popped node.
+            # if it has not been visited, push it to stack
+            for n in node.children:
+                if n.id not in visited and n.id not in projects_built:
+                    stack.append(n)
+            # check if all children are built.
+            all_adjacent_built = True
+            for n in node.children:
+                if n.id not in projects_built:
+                    all_adjacent_built = False
+            # if all adjacent nodes are built,
+            # then this node can be safely built.
+            # otherwise, add to not_built list to check
+            # if children are built after traversal
+            if all_adjacent_built and node.id not in projects_built:
+                projects_built.add(node.id)
+                output.append(node.id)
+            else:
+                not_built.append(node)
+        # after traversing, we may have built all children.
+        # check nodes that haven't been built from this traversal.
+        for node in not_built:
+            all_adjacent_built = True
+            for n in node.children:
+                if n.id not in projects_built:
+                    all_adjacent_built = False
+            if all_adjacent_built and node.id not in projects_built:
+                projects_built.add(node.id)
+                output.append(node.id)
+    return output
+
+
+class TestBuildOrder(unittest.TestCase):
+    def test_build_order_ctci_example(self) -> None:
+        projects = ['a', 'b', 'c', 'd', 'e', 'f']
+        dependencies = [
+            ('a', 'd'),
+            ('f', 'b'),
+            ('b', 'd'),
+            ('f', 'a'),
+            ('d', 'c')
+        ]
+        result = build_order(projects, dependencies)
+        # this is the textbook answer, but it is possible to get a
+        # different valid build order (depends on algorithm)
+        # self.assertEqual(result, ['f', 'e', 'a', 'b', 'd', 'c'])
+        self.assertEqual(result, ['f', 'a', 'b', 'd', 'c', 'e'])
+
+
+class TestMyDependencyGraphSearch(unittest.TestCase):
+
+    def test_basic_graph_creation(self):
+        n0 = Node(0, [])
+        n1 = Node(1, [])
+        n2 = Node(2, [])
+        n3 = Node(3, [])
+        n4 = Node(4, [])
+        n5 = Node(5, [])
+        n6 = Node(6, [])
+        n0.add_child(n1)
+        n1.add_child(n2)
+        n2.add_child(n0, n3)
+        n3.add_child(n2)
+        n4.add_child(n6)
+        n5.add_child(n4)
+        n6.add_child(n5)
+        nodes = [n0, n1, n2, n3, n4, n5, n6]
+        g = DependencyGraph(nodes)
+        # g.print_graph()
+
+
+if __name__ == '__main__':
+    unittest.main()