goodagent

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 maintains a focus on a specific node in the tree and allows
6 functional navigation and modification operations.
7 """
8
9 def __init__(self, tree, path):
10 """
11 Initialize a Zipper.
12
13 Args:
14 tree: The full tree structure (dict with 'value', 'left', 'right')
15 path: List of breadcrumbs representing path from root to focus
16 """
17 self.tree = tree
18 self.path = path
19 # Current node is determined by following the path from root
20 self._current = self._get_current_node()
21
322 @staticmethod
423 def from_tree(tree: dict) -> "Zipper":
5 pass
6
24 """
25 Create a zipper from a binary tree.
26
27 Args:
28 tree: A binary tree represented as a dict with keys 'value', 'left', 'right'
29
30 Returns:
31 A new Zipper instance focused on the root node
32 """
33 # Edge Case: Handle None tree
34 if tree is None:
35 return None
36 return Zipper(tree, [])
37
38 def _get_current_node(self):
39 """
40 Get the current node by following the path from the root.
41
42 Returns:
43 The current node dict
44 """
45 # Edge Case: Handle empty path (focus is root)
46 if not self.path:
47 return self.tree
48
49 node = self.tree
50 for direction, parent in self.path:
51 if direction == 'left':
52 node = node['left']
53 else: # direction == 'right'
54 node = node['right']
55 return node
56
757 def value(self) -> int:
8 pass
9
58 """
59 Get the value of the focus node.
60
61 Returns:
62 The value of the current node
63 """
64 # Edge Case: Handle None current node
65 if self._current is None:
66 return None
67 return self._current['value']
68
1069 def set_value(self, value: int) -> "Zipper":
11 pass
12
70 """
71 Set the value of the focus node.
72
73 Args:
74 value: The new value for the focus node
75
76 Returns:
77 A new Zipper with the updated value
78 """
79 # Edge Case: Handle None current node
80 if self._current is None:
81 return self
82
83 # Create a deep copy of the tree
84 new_tree = self._deep_copy_tree(self.tree)
85
86 # Navigate to the correct position in the new tree
87 node = new_tree
88 for direction, parent in self.path:
89 if direction == 'left':
90 node = node['left']
91 else: # direction == 'right'
92 node = node['right']
93
94 # Update the value
95 node['value'] = value
96
97 return Zipper(new_tree, self.path)
98
1399 def left(self) -> "Zipper | None":
14 pass
15
100 """
101 Move the focus to the left child of the current node.
102
103 Returns:
104 A new Zipper focused on the left child, or None if no left child
105 """
106 # Edge Case: Handle None current node
107 if self._current is None or self._current['left'] is None:
108 return None
109
110 # Add breadcrumb for current node before moving left
111 new_path = self.path + [('left', self._current)]
112 return Zipper(self.tree, new_path)
113
16114 def set_left(self, tree: dict | None) -> "Zipper":
17 pass
18
115 """
116 Set the left child of the focus node.
117
118 Args:
119 tree: The new left subtree (or None to remove)
120
121 Returns:
122 A new Zipper with the updated left child
123 """
124 # Create a deep copy of the tree
125 new_tree = self._deep_copy_tree(self.tree)
126
127 # Navigate to the correct position in the new tree
128 node = new_tree
129 for direction, parent in self.path:
130 if direction == 'left':
131 node = node['left']
132 else: # direction == 'right'
133 node = node['right']
134
135 # Update the left child
136 node['left'] = tree
137
138 return Zipper(new_tree, self.path)
139
19140 def right(self) -> "Zipper | None":
20 pass
21
141 """
142 Move the focus to the right child of the current node.
143
144 Returns:
145 A new Zipper focused on the right child, or None if no right child
146 """
147 # Edge Case: Handle None current node
148 if self._current is None or self._current['right'] is None:
149 return None
150
151 # Add breadcrumb for current node before moving right
152 new_path = self.path + [('right', self._current)]
153 return Zipper(self.tree, new_path)
154
22155 def set_right(self, tree: dict | None) -> "Zipper":
23 pass
24
156 """
157 Set the right child of the focus node.
158
159 Args:
160 tree: The new right subtree (or None to remove)
161
162 Returns:
163 A new Zipper with the updated right child
164 """
165 # Create a deep copy of the tree
166 new_tree = self._deep_copy_tree(self.tree)
167
168 # Navigate to the correct position in the new tree
169 node = new_tree
170 for direction, parent in self.path:
171 if direction == 'left':
172 node = node['left']
173 else: # direction == 'right'
174 node = node['right']
175
176 # Update the right child
177 node['right'] = tree
178
179 return Zipper(new_tree, self.path)
180
25181 def up(self) -> "Zipper | None":
26 pass
27
182 """
183 Move the focus to the parent of the current node.
184
185 Returns:
186 A new Zipper focused on the parent, or None if at root
187 """
188 # Edge Case: Handle already at root (no parent)
189 if not self.path:
190 return None
191
192 # Remove the last breadcrumb to move up
193 new_path = self.path[:-1]
194 return Zipper(self.tree, new_path)
195
28196 def to_tree(self) -> dict:
29 pass
197 """
198 Get the complete tree from the zipper.
199
200 Returns:
201 The full tree structure
202 """
203 return self.tree
204
205 def _deep_copy_tree(self, tree):
206 """
207 Create a deep copy of a tree.
208
209 Args:
210 tree: The tree to copy
211
212 Returns:
213 A deep copy of the tree
214 """
215 # Edge Case: Handle None tree
216 if tree is None:
217 return None
218
219 return {
220 'value': tree['value'],
221 'left': self._deep_copy_tree(tree['left']),
222 'right': self._deep_copy_tree(tree['right'])
223 }
224
225 # Handled Edge Cases: None tree in from_tree, empty path in _get_current_node,
226 # None current node in value, None current node in set_value, None current node in left,
227 # None current node in right, already at root in up, None tree in _deep_copy_tree
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.