Tidy up structure of briefcase
I had a spare fifteen minutes and decided that I should tidy up my monorepo. The work of tidying up is not finished; this is a small step in the right direction. TL;DR - Created a tools directory - Created a scratch directory (see README.md for more information) - Added README.md to third_party - Renamed delete_dotfile_symlinks -> symlinkManager - Packaged symlinkManager as an executable symlink-mgr using buildGo
This commit is contained in:
		
							parent
							
								
									5ec5a6da8c
								
							
						
					
					
						commit
						fabf1c9334
					
				
					 89 changed files with 53 additions and 41 deletions
				
			
		|  | @ -0,0 +1,179 @@ | |||
| import unittest | ||||
| from collections import deque | ||||
| 
 | ||||
| 
 | ||||
| ################################################################################ | ||||
| # Implementation | ||||
| ################################################################################ | ||||
| def is_leaf(node): | ||||
|     return node.left is None and node.right is None | ||||
| 
 | ||||
| 
 | ||||
| def find_largest(node): | ||||
|     current = node | ||||
|     while current.right is not None: | ||||
|         current = current.right | ||||
|     return current.value | ||||
| 
 | ||||
| 
 | ||||
| def find_second_largest(node): | ||||
|     history = deque() | ||||
|     current = node | ||||
| 
 | ||||
|     while current.right: | ||||
|         history.append(current) | ||||
|         current = current.right | ||||
| 
 | ||||
|     if current.left: | ||||
|         return find_largest(current.left) | ||||
|     elif history: | ||||
|         return history.pop().value | ||||
|     else: | ||||
|         raise TypeError | ||||
| 
 | ||||
| 
 | ||||
| def find_second_largest_backup(node): | ||||
|     history = deque() | ||||
|     current = node | ||||
| 
 | ||||
|     # traverse -> largest | ||||
|     while current.right: | ||||
|         history.append(current) | ||||
|         current = current.right | ||||
| 
 | ||||
|     if current.left: | ||||
|         return find_largest(current.left) | ||||
|     elif history: | ||||
|         return history.pop().value | ||||
|     else: | ||||
|         raise ArgumentError | ||||
| 
 | ||||
| 
 | ||||
| # Write a iterative version to avoid consuming memory with the call stack. | ||||
| # Commenting out the recursive code for now. | ||||
| def find_second_largest_backup(node): | ||||
|     if node.left is None and node.right is None: | ||||
|         raise ArgumentError | ||||
| 
 | ||||
|     elif node.right is None and is_leaf(node.left): | ||||
|         return node.left.value | ||||
| 
 | ||||
|     # recursion | ||||
|     # elif node.right is None: | ||||
|     #     return find_largest(node.left) | ||||
| 
 | ||||
|     # iterative version | ||||
|     elif node.right is None: | ||||
|         current = node.left | ||||
|         while current.right is not None: | ||||
|             current = current.right | ||||
|         return current.value | ||||
| 
 | ||||
|     # recursion | ||||
|     # TODO: Remove recursion from here. | ||||
|     elif not is_leaf(node.right): | ||||
|         return find_second_largest(node.right) | ||||
| 
 | ||||
|     # could do an else here, but let's be more assertive. | ||||
|     elif is_leaf(node.right): | ||||
|         return node.value | ||||
| 
 | ||||
|     else: | ||||
|         raise ArgumentError | ||||
| 
 | ||||
| 
 | ||||
| ################################################################################ | ||||
| # Tests | ||||
| ################################################################################ | ||||
| class Test(unittest.TestCase): | ||||
|     class BinaryTreeNode(object): | ||||
|         def __init__(self, value): | ||||
|             self.value = value | ||||
|             self.left = None | ||||
|             self.right = None | ||||
| 
 | ||||
|         def insert_left(self, value): | ||||
|             self.left = Test.BinaryTreeNode(value) | ||||
|             return self.left | ||||
| 
 | ||||
|         def insert_right(self, value): | ||||
|             self.right = Test.BinaryTreeNode(value) | ||||
|             return self.right | ||||
| 
 | ||||
|     def test_full_tree(self): | ||||
|         tree = Test.BinaryTreeNode(50) | ||||
|         left = tree.insert_left(30) | ||||
|         right = tree.insert_right(70) | ||||
|         left.insert_left(10) | ||||
|         left.insert_right(40) | ||||
|         right.insert_left(60) | ||||
|         right.insert_right(80) | ||||
|         actual = find_second_largest(tree) | ||||
|         expected = 70 | ||||
|         self.assertEqual(actual, expected) | ||||
| 
 | ||||
|     def test_largest_has_a_left_child(self): | ||||
|         tree = Test.BinaryTreeNode(50) | ||||
|         left = tree.insert_left(30) | ||||
|         right = tree.insert_right(70) | ||||
|         left.insert_left(10) | ||||
|         left.insert_right(40) | ||||
|         right.insert_left(60) | ||||
|         actual = find_second_largest(tree) | ||||
|         expected = 60 | ||||
|         self.assertEqual(actual, expected) | ||||
| 
 | ||||
|     def test_largest_has_a_left_subtree(self): | ||||
|         tree = Test.BinaryTreeNode(50) | ||||
|         left = tree.insert_left(30) | ||||
|         right = tree.insert_right(70) | ||||
|         left.insert_left(10) | ||||
|         left.insert_right(40) | ||||
|         right_left = right.insert_left(60) | ||||
|         right_left_left = right_left.insert_left(55) | ||||
|         right_left.insert_right(65) | ||||
|         right_left_left.insert_right(58) | ||||
|         actual = find_second_largest(tree) | ||||
|         expected = 65 | ||||
|         self.assertEqual(actual, expected) | ||||
| 
 | ||||
|     def test_second_largest_is_root_node(self): | ||||
|         tree = Test.BinaryTreeNode(50) | ||||
|         left = tree.insert_left(30) | ||||
|         tree.insert_right(70) | ||||
|         left.insert_left(10) | ||||
|         left.insert_right(40) | ||||
|         actual = find_second_largest(tree) | ||||
|         expected = 50 | ||||
|         self.assertEqual(actual, expected) | ||||
| 
 | ||||
|     def test_descending_linked_list(self): | ||||
|         tree = Test.BinaryTreeNode(50) | ||||
|         left = tree.insert_left(40) | ||||
|         left_left = left.insert_left(30) | ||||
|         left_left_left = left_left.insert_left(20) | ||||
|         left_left_left.insert_left(10) | ||||
|         actual = find_second_largest(tree) | ||||
|         expected = 40 | ||||
|         self.assertEqual(actual, expected) | ||||
| 
 | ||||
|     def test_ascending_linked_list(self): | ||||
|         tree = Test.BinaryTreeNode(50) | ||||
|         right = tree.insert_right(60) | ||||
|         right_right = right.insert_right(70) | ||||
|         right_right.insert_right(80) | ||||
|         actual = find_second_largest(tree) | ||||
|         expected = 70 | ||||
|         self.assertEqual(actual, expected) | ||||
| 
 | ||||
|     def test_error_when_tree_has_one_node(self): | ||||
|         tree = Test.BinaryTreeNode(50) | ||||
|         with self.assertRaises(Exception): | ||||
|             find_second_largest(tree) | ||||
| 
 | ||||
|     def test_error_when_tree_is_empty(self): | ||||
|         with self.assertRaises(Exception): | ||||
|             find_second_largest(None) | ||||
| 
 | ||||
| 
 | ||||
| unittest.main(verbosity=2) | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue