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 The zipper maintains a focus on a specific node in the tree and allows
6 functional-style navigation and modification operations.
7 """
8
9 def __init__(self, tree: dict, path: list = None):
10 """
11 Initialize a Zipper.
12
13 Args:
14 tree: The binary tree represented as a dict with keys 'value', 'left', 'right'
15 path: A list of tuples representing the path from root to focus node.
16 Each tuple contains (parent_node, direction) where direction is 'left' or 'right'
17 """
18 self.tree = tree
19 self.path = path or []
20
21 # Navigate to the focus node based on the path
22 self.focus = self.tree
23 for parent, direction in self.path:
24 if direction == 'left':
25 self.focus = self.focus['left']
26 else: # direction == 'right'
27 self.focus = self.focus['right']
28
329 @staticmethod
430 def from_tree(tree: dict) -> "Zipper":
5 pass
6
31 """
32 Create a zipper from a binary tree, with focus on the root node.
33
34 Args:
35 tree: A binary tree represented as a dict with keys 'value', 'left', 'right'
36
37 Returns:
38 A new Zipper instance focused on the root of the tree
39
40 Edge Case: Empty tree (None) - returns a Zipper with None tree and empty focus
41 """
42 # Edge Case: Handle None tree
43 if tree is None:
44 return Zipper(None)
45
46 return Zipper(tree)
47
748 def value(self) -> int:
8 pass
9
49 """
50 Get the value of the focus node.
51
52 Returns:
53 The value of the focus node
54
55 Edge Case: Focus is None - raises AttributeError
56 """
57 # Edge Case: Handle None focus
58 if self.focus is None:
59 raise AttributeError("Cannot get value of None focus")
60
61 return self.focus['value']
62
1063 def set_value(self, value: int) -> "Zipper":
11 pass
12
64 """
65 Set the value of the focus node, returning a new zipper.
66
67 Args:
68 value: The new value for the focus node
69
70 Returns:
71 A new Zipper with the updated value
72
73 Edge Case: Focus is None - returns a new Zipper with the same state
74 """
75 # Edge Case: Handle None focus
76 if self.focus is None:
77 return Zipper(self.tree, self.path)
78
79 # Create a deep copy of the tree
80 new_tree = self._deep_copy_tree(self.tree)
81
82 # Navigate to the focus node in the new tree
83 new_focus = new_tree
84 for parent, direction in self.path:
85 if direction == 'left':
86 new_focus = new_focus['left']
87 else: # direction == 'right'
88 new_focus = new_focus['right']
89
90 # Update the value
91 new_focus['value'] = value
92
93 return Zipper(new_tree, self.path)
94
1395 def left(self) -> "Zipper | None":
14 pass
15
96 """
97 Move the focus to the left child of the current focus node.
98
99 Returns:
100 A new Zipper focused on the left child, or None if no left child exists
101
102 Edge Case: Focus is None - returns None
103 Edge Case: No left child - returns None
104 """
105 # Edge Case: Handle None focus
106 if self.focus is None:
107 return None
108
109 # Edge Case: No left child
110 if self.focus['left'] is None:
111 return None
112
113 # Create a new path that includes the move to the left child
114 new_path = self.path + [(self.focus, 'left')]
115 return Zipper(self.tree, new_path)
116
16117 def set_left(self, tree: dict | None) -> "Zipper":
17 pass
18
118 """
119 Set the left child of the focus node, returning a new zipper.
120
121 Args:
122 tree: The new left subtree (or None to remove the left child)
123
124 Returns:
125 A new Zipper with the updated left child
126
127 Edge Case: Focus is None - returns a new Zipper with the same state
128 """
129 # Edge Case: Handle None focus
130 if self.focus is None:
131 return Zipper(self.tree, self.path)
132
133 # Create a deep copy of the tree
134 new_tree = self._deep_copy_tree(self.tree)
135
136 # Navigate to the focus node in the new tree
137 new_focus = new_tree
138 for parent, direction in self.path:
139 if direction == 'left':
140 new_focus = new_focus['left']
141 else: # direction == 'right'
142 new_focus = new_focus['right']
143
144 # Update the left child
145 new_focus['left'] = tree
146
147 return Zipper(new_tree, self.path)
148
19149 def right(self) -> "Zipper | None":
20 pass
21
150 """
151 Move the focus to the right child of the current focus node.
152
153 Returns:
154 A new Zipper focused on the right child, or None if no right child exists
155
156 Edge Case: Focus is None - returns None
157 Edge Case: No right child - returns None
158 """
159 # Edge Case: Handle None focus
160 if self.focus is None:
161 return None
162
163 # Edge Case: No right child
164 if self.focus['right'] is None:
165 return None
166
167 # Create a new path that includes the move to the right child
168 new_path = self.path + [(self.focus, 'right')]
169 return Zipper(self.tree, new_path)
170
22171 def set_right(self, tree: dict | None) -> "Zipper":
23 pass
24
172 """
173 Set the right child of the focus node, returning a new zipper.
174
175 Args:
176 tree: The new right subtree (or None to remove the right child)
177
178 Returns:
179 A new Zipper with the updated right child
180
181 Edge Case: Focus is None - returns a new Zipper with the same state
182 """
183 # Edge Case: Handle None focus
184 if self.focus is None:
185 return Zipper(self.tree, self.path)
186
187 # Create a deep copy of the tree
188 new_tree = self._deep_copy_tree(self.tree)
189
190 # Navigate to the focus node in the new tree
191 new_focus = new_tree
192 for parent, direction in self.path:
193 if direction == 'left':
194 new_focus = new_focus['left']
195 else: # direction == 'right'
196 new_focus = new_focus['right']
197
198 # Update the right child
199 new_focus['right'] = tree
200
201 return Zipper(new_tree, self.path)
202
25203 def up(self) -> "Zipper | None":
26 pass
27
204 """
205 Move the focus to the parent of the current focus node.
206
207 Returns:
208 A new Zipper focused on the parent, or None if focus is at the root
209
210 Edge Case: Focus is at root (empty path) - returns None
211 Edge Case: Focus is None - returns None
212 """
213 # Edge Case: Handle None focus
214 if self.focus is None:
215 return None
216
217 # Edge Case: Already at root
218 if not self.path:
219 return None
220
221 # Create a new path that removes the last step (moving up)
222 new_path = self.path[:-1]
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 Returns:
230 The complete binary tree as a dict
231
232 Edge Case: Original tree is None - returns None
233 """
234 # Edge Case: Handle None tree
235 if self.tree is None:
236 return None
237
238 return self.tree
239
240 def _deep_copy_tree(self, tree: dict) -> dict:
241 """
242 Create a deep copy of a binary tree.
243
244 Args:
245 tree: The tree to copy
246
247 Returns:
248 A deep copy of the tree
249 """
250 if tree is None:
251 return None
252
253 return {
254 'value': tree['value'],
255 'left': self._deep_copy_tree(tree['left']),
256 'right': self._deep_copy_tree(tree['right'])
257 }
258
259 # Handled Edge Cases: Empty tree, None focus, No left child, No right child, Focus 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.