let it go

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 A zipper contains a data structure and a pointer (focus) into that structure.
6 It supports moving through the tree and modifying it in a functional way.
7 """
8
9 def __init__(self, tree, path=None):
10 """
11 Initialize a Zipper.
12
13 Args:
14 tree (dict): The binary tree represented as a dict with keys 'value', 'left', 'right'
15 path (list): A list of tuples representing the path from root to focus node
16 """
17 self.tree = tree
18 self.path = path or []
19
320 @staticmethod
421 def from_tree(tree: dict) -> "Zipper":
5 pass
22 """
23 Create a zipper from a binary tree.
24
25 Args:
26 tree (dict): The binary tree with keys 'value', 'left', 'right'
27
628
29 Returns:
30 Zipper: A new zipper focused on the root of the tree
31 """
32 # Edge Case: Handle None tree input
33 if tree is None:
34 return None
35 return Zipper(tree)
36
37 def _get_focus_node(self):
38 """
39 Get the current focus node by traversing the path.
40
41
42 Returns:
43 dict: The focus node
44 """
45 node = self.tree
46 for direction, parent in self.path:
47 if direction == 'left':
48 node = node['left']
49 else: # direction == 'right'
50 node = node['right']
51 return node
52
753 def value(self) -> int:
8 pass
54 """
55 Get the value of the focus node.
56
957
58 Returns:
59 int: The value of the focus node
60 """
61 # Edge Case: Handle None tree
62 if self.tree is None:
63 return None
64 return self._get_focus_node()['value']
65
1066 def set_value(self, value: int) -> "Zipper":
11 pass
67 """
68 Set the value of the focus node, returning a new zipper.
69
70 Args:
71 value (int): The new value
72
1273
74 Returns:
75 Zipper: A new zipper with the updated value
76 """
77 # Edge Case: Handle None tree
78 if self.tree is None:
79 return self
80
81 # Create a deep copy of the tree
82 new_tree = self._deep_copy_tree(self.tree)
83
84 # Navigate to the focus node in the new tree and update its value
85 node = new_tree
86 for direction, parent in self.path:
87 if direction == 'left':
88 node = node['left']
89 else: # direction == 'right'
90 node = node['right']
91
92 node['value'] = value
93
94 return Zipper(new_tree, list(self.path))
95
1396 def left(self) -> "Zipper | None":
14 pass
97 """
98 Move the focus to the left child of the current node.
99
15100
101 Returns:
102 Zipper | None: A new zipper focused on the left child, or None if no left child
103 """
104 # Edge Case: Handle None tree
105 if self.tree is None:
106 return None
107
108 focus_node = self._get_focus_node()
109
110 # Edge Case: Handle None left child
111 if focus_node['left'] is None:
112 return None
113
114 # Create a new path entry for moving to the left child
115 new_path = list(self.path)
116 new_path.append(('left', focus_node))
117
118 return Zipper(self.tree, new_path)
119
16120 def set_left(self, tree: dict | None) -> "Zipper":
17 pass
121 """
122 Set the left child of the focus node, returning a new zipper.
123
124 Args:
125 tree (dict | None): The new left subtree
126
18127
128 Returns:
129 Zipper: A new zipper with the updated left child
130 """
131 # Edge Case: Handle None tree
132 if self.tree is None:
133 return self
134
135 # Create a deep copy of the tree
136 new_tree = self._deep_copy_tree(self.tree)
137
138 # Navigate to the focus node in the new tree and update its left child
139 node = new_tree
140 for direction, parent in self.path:
141 if direction == 'left':
142 node = node['left']
143 else: # direction == 'right'
144 node = node['right']
145
146 node['left'] = tree
147
148 return Zipper(new_tree, list(self.path))
149
19150 def right(self) -> "Zipper | None":
20 pass
151 """
152 Move the focus to the right child of the current node.
153
21154
155 Returns:
156 Zipper | None: A new zipper focused on the right child, or None if no right child
157 """
158 # Edge Case: Handle None tree
159 if self.tree is None:
160 return None
161
162 focus_node = self._get_focus_node()
163
164 # Edge Case: Handle None right child
165 if focus_node['right'] is None:
166 return None
167
168 # Create a new path entry for moving to the right child
169 new_path = list(self.path)
170 new_path.append(('right', focus_node))
171
172 return Zipper(self.tree, new_path)
173
22174 def set_right(self, tree: dict | None) -> "Zipper":
23 pass
175 """
176 Set the right child of the focus node, returning a new zipper.
177
178 Args:
179 tree (dict | None): The new right subtree
180
24181
182 Returns:
183 Zipper: A new zipper with the updated right child
184 """
185 # Edge Case: Handle None tree
186 if self.tree is None:
187 return self
188
189 # Create a deep copy of the tree
190 new_tree = self._deep_copy_tree(self.tree)
191
192 # Navigate to the focus node in the new tree and update its right child
193 node = new_tree
194 for direction, parent in self.path:
195 if direction == 'left':
196 node = node['left']
197 else: # direction == 'right'
198 node = node['right']
199
200 node['right'] = tree
201
202 return Zipper(new_tree, list(self.path))
203
25204 def up(self) -> "Zipper | None":
26 pass
205 """
206 Move the focus to the parent of the current node.
207
27208
209 Returns:
210 Zipper | None: A new zipper focused on the parent, or None if at root
211 """
212 # Edge Case: Handle None tree
213 if self.tree is None:
214 return None
215
216 # Edge Case: Handle already at root (empty path)
217 if not self.path:
218 return None
219
220 # Create a new path without the last element
221 new_path = list(self.path[:-1])
222
223 return Zipper(self.tree, new_path)
224
28225 def to_tree(self) -> dict:
29 pass
226 """
227 Get the complete tree from the zipper.
228
229
230 Returns:
231 dict: The complete binary tree
232 """
233 # Edge Case: Handle None tree
234 if self.tree is None:
235 return None
236 return self.tree
237
238 def _deep_copy_tree(self, tree):
239 """
240 Create a deep copy of a binary tree.
241
242 Args:
243 tree (dict): The tree to copy
244
245
246 Returns:
247 dict: A deep copy of the tree
248 """
249 if tree is None:
250 return None
251
252 return {
253 'value': tree['value'],
254 'left': self._deep_copy_tree(tree['left']),
255 'right': self._deep_copy_tree(tree['right'])
256 }
257 # Handled Edge Cases: None tree input, None left child, None right child, already at root
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.