weekends

Finished
11class Zipper:
2 # Tree is a dict with keys "value" (int), "left" (dict or None), "right" (dict or None)
2 """
3 A zipper for navigating and manipulating a binary tree.
4
5 The zipper maintains a focus on a specific node in the tree and allows
6 navigation and modification operations while preserving the tree structure.
7 """
8
9 def __init__(self, tree, path):
10 """
11 Initialize a Zipper instance.
12
13 Args:
14 tree (dict): The full tree structure
15 path (list): Path from root to current focus node, containing breadcrumb information
16 """
17 self.tree = tree
18 self.path = path
19
320 @staticmethod
421 def from_tree(tree: dict) -> "Zipper":
5 pass
6
22 """
23 Create a zipper from a binary tree.
24
25 Args:
26 tree (dict): A binary tree with keys "value", "left", and "right"
27
28 Returns:
29 Zipper: A new zipper focused on the root of the tree
30 """
31 # Edge Case: Handle None tree input
32 if tree is None:
33 return None
34 return Zipper(tree, [])
35
36 def _get_focus_node(self):
37 """
38 Get the current focus node by following the path from root.
39
40 Returns:
41 dict: The current focus node
42 """
43 node = self.tree
44 for direction, parent in self.path:
45 if direction == 'left':
46 node = node['left']
47 else: # direction == 'right'
48 node = node['right']
49 return node
50
751 def value(self) -> int:
8 pass
9
52 """
53 Get the value of the focus node.
54
55 Returns:
56 int: The value of the focus node
57 """
58 return self._get_focus_node()['value']
59
1060 def set_value(self, value: int) -> "Zipper":
11 pass
12
61 """
62 Set the value of the focus node, returning a new zipper.
63
64 Args:
65 value (int): The new value for the focus node
66
67 Returns:
68 Zipper: A new zipper with the updated value
69 """
70 # Edge Case: Handle None value input
71 if value is None:
72 raise ValueError("Value cannot be None")
73
74 new_tree = self._reconstruct_tree()
75 focus = new_tree
76
77 # Navigate to focus node in the new tree
78 for direction, parent in self.path:
79 if direction == 'left':
80 focus = focus['left']
81 else: # direction == 'right'
82 focus = focus['right']
83
84 focus['value'] = value
85 return Zipper(new_tree, self.path)
86
1387 def left(self) -> "Zipper | None":
14 pass
15
88 """
89 Move focus to the left child of the current node.
90
91 Returns:
92 Zipper | None: A new zipper focused on the left child, or None if no left child exists
93 """
94 focus = self._get_focus_node()
95 # Edge Case: Handle missing left child
96 if focus['left'] is None:
97 return None
98
99 # Create a new path with the current node as breadcrumb
100 new_path = self.path + [('left', {
101 'value': focus['value'],
102 'left': focus['left'],
103 'right': focus['right']
104 })]
105
106 return Zipper(self.tree, new_path)
107
16108 def set_left(self, tree: dict | None) -> "Zipper":
17 pass
18
109 """
110 Set the left child of the focus node, returning a new zipper.
111
112 Args:
113 tree (dict | None): The new left subtree or None
114
115 Returns:
116 Zipper: A new zipper with the updated left child
117 """
118 new_tree = self._reconstruct_tree()
119 focus = new_tree
120
121 # Navigate to focus node in the new tree
122 for direction, parent in self.path:
123 if direction == 'left':
124 focus = focus['left']
125 else: # direction == 'right'
126 focus = focus['right']
127
128 focus['left'] = tree
129 return Zipper(new_tree, self.path)
130
19131 def right(self) -> "Zipper | None":
20 pass
21
132 """
133 Move focus to the right child of the current node.
134
135 Returns:
136 Zipper | None: A new zipper focused on the right child, or None if no right child exists
137 """
138 focus = self._get_focus_node()
139 # Edge Case: Handle missing right child
140 if focus['right'] is None:
141 return None
142
143 # Create a new path with the current node as breadcrumb
144 new_path = self.path + [('right', {
145 'value': focus['value'],
146 'left': focus['left'],
147 'right': focus['right']
148 })]
149
150 return Zipper(self.tree, new_path)
151
22152 def set_right(self, tree: dict | None) -> "Zipper":
23 pass
24
153 """
154 Set the right child of the focus node, returning a new zipper.
155
156 Args:
157 tree (dict | None): The new right subtree or None
158
159 Returns:
160 Zipper: A new zipper with the updated right child
161 """
162 new_tree = self._reconstruct_tree()
163 focus = new_tree
164
165 # Navigate to focus node in the new tree
166 for direction, parent in self.path:
167 if direction == 'left':
168 focus = focus['left']
169 else: # direction == 'right'
170 focus = focus['right']
171
172 focus['right'] = tree
173 return Zipper(new_tree, self.path)
174
25175 def up(self) -> "Zipper | None":
26 pass
27
176 """
177 Move focus to the parent of the current node.
178
179 Returns:
180 Zipper | None: A new zipper focused on the parent, or None if already at root
181 """
182 # Edge Case: Handle attempt to move up from root
183 if not self.path:
184 return None
185
186 new_path = self.path[:-1] # Remove last breadcrumb
187 return Zipper(self.tree, new_path)
188
189 def _reconstruct_tree(self):
190 """
191 Reconstruct the full tree with any modifications applied at the focus.
192
193 Returns:
194 dict: A new tree with all modifications applied
195 """
196 # Start with a deep copy of the original tree
197 import copy
198 new_tree = copy.deepcopy(self.tree)
199
200 # Navigate to the focus node, keeping track of the path
201 current = new_tree
202 path_to_focus = []
203
204 for direction, parent in self.path:
205 path_to_focus.append((direction, current))
206 if direction == 'left':
207 current = current['left']
208 else: # direction == 'right'
209 current = current['right']
210
211 # Update the focus node with current values
212 focus = self._get_focus_node()
213 current['value'] = focus['value']
214 current['left'] = focus['left']
215 current['right'] = focus['right']
216
217 return new_tree
218
28219 def to_tree(self) -> dict:
29 pass
220 """
221 Get the full tree from the zipper.
222
223 Returns:
224 dict: The full binary tree
225 """
226 return self._reconstruct_tree()
227
228 # Handled Edge Cases: None tree input, missing left child, missing right child, attempt to move up from root, None value input
Test NameStatus
test_data_is_retained
Pass
test_dead_end
Pass
test_different_paths_to_same_zipper
Pass
test_left_right_and_up
Pass
test_left_right_and_value
Pass
test_set_left_with_leaf
Pass
test_set_right_with_null
Pass
test_set_right_with_subtree
Pass
test_set_value
Pass
test_set_value_after_traversing_up
Pass
test_set_value_on_deep_focus
Pass
test_test_ability_to_descend_multiple_levels_and_return
Pass
test_traversing_up_from_top
Pass
test_tree_from_deep_focus
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.