agent

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 to parent and child nodes, as well as modification of the tree.
7 """
8
9 def __init__(self, tree, path):
10 """
11 Initialize a Zipper.
12
13 Args:
14 tree (dict): The complete tree structure
15 path (list): Path from root to focus node, with context at each level
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
32 if tree is None:
33 return None
34 return Zipper(tree, [])
35
36 def _get_focus(self):
37 """
38 Get the current focus node based on the path.
39
40 Returns:
41 dict: The 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 Raises:
59 Exception: If the focus node is None
60 """
61 focus = self._get_focus()
62 # Edge Case: Handle None focus
63 if focus is None:
64 raise Exception("Focus is None")
65 return focus['value']
66
1067 def set_value(self, value: int) -> "Zipper":
11 pass
12
68 """
69 Set the value of the focus node.
70
71 Args:
72 value (int): The new value for the focus node
73
74 Returns:
75 Zipper: A new zipper with the updated value
76 """
77 # Edge Case: Handle empty path (root node)
78 if not self.path:
79 new_tree = {'value': value, 'left': self.tree['left'], 'right': self.tree['right']}
80 return Zipper(new_tree, self.path)
81
82 # Create a copy of the tree and path
83 new_tree = self._copy_tree()
84 new_path = list(self.path)
85
86 # Navigate to the parent of the focus node
87 node = new_tree
88 for direction, parent in new_path[:-1]:
89 if direction == 'left':
90 node = node['left']
91 else: # direction == 'right'
92 node = node['right']
93
94 # Update the value of the focus node
95 if new_path[-1][0] == 'left':
96 node['left'] = {'value': value, 'left': node['left']['left'] if node['left'] else None,
97 'right': node['left']['right'] if node['left'] else None}
98 else: # direction == 'right'
99 node['right'] = {'value': value, 'left': node['right']['left'] if node['right'] else None,
100 'right': node['right']['right'] if node['right'] else None}
101
102 return Zipper(new_tree, new_path)
103
13104 def left(self) -> "Zipper | None":
14 pass
15
105 """
106 Move the focus to the left child of the current focus node.
107
108 Returns:
109 Zipper | None: A new zipper focused on the left child, or None if no left child exists
110 """
111 focus = self._get_focus()
112 # Edge Case: Handle None focus
113 if focus is None or focus['left'] is None:
114 return None
115
116 # Create a new path entry for moving to the left child
117 new_path = list(self.path)
118 new_path.append(('left', {'value': focus['value'], 'right': focus['right']}))
119
120 return Zipper(self.tree, new_path)
121
16122 def set_left(self, tree: dict | None) -> "Zipper":
17 pass
18
123 """
124 Set the left child of the focus node.
125
126 Args:
127 tree (dict | None): The new left subtree
128
129 Returns:
130 Zipper: A new zipper with the updated left child
131 """
132 # Edge Case: Handle empty path (root node)
133 if not self.path:
134 new_tree = {'value': self.tree['value'], 'left': tree, 'right': self.tree['right']}
135 return Zipper(new_tree, self.path)
136
137 # Create a copy of the tree and path
138 new_tree = self._copy_tree()
139 new_path = list(self.path)
140
141 # Navigate to the parent of the focus node
142 node = new_tree
143 for direction, parent in new_path[:-1]:
144 if direction == 'left':
145 node = node['left']
146 else: # direction == 'right'
147 node = node['right']
148
149 # Update the left child of the focus node
150 if new_path[-1][0] == 'left':
151 node['left'] = {'value': node['left']['value'], 'left': tree,
152 'right': node['left']['right'] if node['left'] else None}
153 else: # direction == 'right'
154 node['right'] = {'value': node['right']['value'], 'left': tree,
155 'right': node['right']['right'] if node['right'] else None}
156
157 return Zipper(new_tree, new_path)
158
19159 def right(self) -> "Zipper | None":
20 pass
21
160 """
161 Move the focus to the right child of the current focus node.
162
163 Returns:
164 Zipper | None: A new zipper focused on the right child, or None if no right child exists
165 """
166 focus = self._get_focus()
167 # Edge Case: Handle None focus
168 if focus is None or focus['right'] is None:
169 return None
170
171 # Create a new path entry for moving to the right child
172 new_path = list(self.path)
173 new_path.append(('right', {'value': focus['value'], 'left': focus['left']}))
174
175 return Zipper(self.tree, new_path)
176
22177 def set_right(self, tree: dict | None) -> "Zipper":
23 pass
24
178 """
179 Set the right child of the focus node.
180
181 Args:
182 tree (dict | None): The new right subtree
183
184 Returns:
185 Zipper: A new zipper with the updated right child
186 """
187 # Edge Case: Handle empty path (root node)
188 if not self.path:
189 new_tree = {'value': self.tree['value'], 'left': self.tree['left'], 'right': tree}
190 return Zipper(new_tree, self.path)
191
192 # Create a copy of the tree and path
193 new_tree = self._copy_tree()
194 new_path = list(self.path)
195
196 # Navigate to the parent of the focus node
197 node = new_tree
198 for direction, parent in new_path[:-1]:
199 if direction == 'left':
200 node = node['left']
201 else: # direction == 'right'
202 node = node['right']
203
204 # Update the right child of the focus node
205 if new_path[-1][0] == 'left':
206 node['left'] = {'value': node['left']['value'], 'left': node['left']['left'] if node['left'] else None,
207 'right': tree}
208 else: # direction == 'right'
209 node['right'] = {'value': node['right']['value'], 'left': node['right']['left'] if node['right'] else None,
210 'right': tree}
211
212 return Zipper(new_tree, new_path)
213
25214 def up(self) -> "Zipper | None":
26 pass
27
215 """
216 Move the focus to the parent of the current focus node.
217
218 Returns:
219 Zipper | None: A new zipper focused on the parent, or None if at the root
220 """
221 # Edge Case: Handle already at root
222 if not self.path:
223 return None
224
225 # Create a new path without the last element
226 new_path = list(self.path[:-1])
227
228 return Zipper(self.tree, new_path)
229
28230 def to_tree(self) -> dict:
29 pass
231 """
232 Get the complete tree from the zipper.
233
234 Returns:
235 dict: The complete binary tree
236 """
237 return self.tree
238
239 def _copy_tree(self):
240 """
241 Create a deep copy of the tree.
242
243 Returns:
244 dict: A deep copy of the tree
245 """
246 def copy_node(node):
247 if node is None:
248 return None
249 return {
250 'value': node['value'],
251 'left': copy_node(node['left']),
252 'right': copy_node(node['right'])
253 }
254
255 return copy_node(self.tree)
256
257# Handled Edge Cases: None tree, None focus, empty path (root node), no left child, no 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.