viola

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, node, path):
10 """
11 Initialize a Zipper instance.
12
13 Args:
14 node (dict): The current focus node with keys 'value', 'left', 'right'
15 path (list): List of breadcrumbs representing the path from root to focus
16 """
17 self._node = node
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, with focus on the root node.
24
25 Args:
26 tree (dict): A binary tree represented as nested dictionaries
27
28 Returns:
29 Zipper: A new zipper instance focused on the root of the tree
30
31 Edge Case: Empty tree (None) - Returns a zipper with None node and empty path
32 """
33 # Edge Case: Empty tree
34 if tree is None:
35 return Zipper(None, [])
36 return Zipper(tree, [])
37
738 def value(self) -> int:
8 pass
9
39 """
40 Get the value of the focus node.
41
42 Returns:
43 int: The value of the focus node
44
45 Edge Case: Focus node is None - Raises AttributeError
46 """
47 # Edge Case: Focus node is None
48 if self._node is None:
49 raise AttributeError("Cannot get value of None node")
50 return self._node["value"]
51
1052 def set_value(self, value: int) -> "Zipper":
11 pass
12
53 """
54 Set the value of the focus node, returning a new zipper.
55
56 Args:
57 value (int): The new value for the focus node
58
59 Returns:
60 Zipper: A new zipper with updated focus node value
61
62 Edge Case: Focus node is None - Returns a new zipper with None node
63 """
64 # Edge Case: Focus node is None
65 if self._node is None:
66 return Zipper(None, self._path)
67
68 new_node = {
69 "value": value,
70 "left": self._node["left"],
71 "right": self._node["right"]
72 }
73 return Zipper(new_node, self._path)
74
1375 def left(self) -> "Zipper | None":
14 pass
15
76 """
77 Move the focus to the left child of the current node.
78
79 Returns:
80 Zipper | None: A new zipper focused on the left child, or None if no left child
81
82 Edge Case: Focus node is None - Returns None
83 Edge Case: No left child - Returns None
84 """
85 # Edge Case: Focus node is None
86 if self._node is None:
87 return None
88
89 # Edge Case: No left child
90 if self._node["left"] is None:
91 return None
92
93 # Create breadcrumb to store current node context
94 breadcrumb = {
95 "parent": {
96 "value": self._node["value"],
97 "right": self._node["right"]
98 },
99 "is_left": True
100 }
101
102 new_path = [breadcrumb] + self._path
103 return Zipper(self._node["left"], new_path)
104
16105 def set_left(self, tree: dict | None) -> "Zipper":
17 pass
18
106 """
107 Set the left child of the focus node, returning a new zipper.
108
109 Args:
110 tree (dict | None): The new left subtree or None
111
112 Returns:
113 Zipper: A new zipper with updated left child
114
115 Edge Case: Focus node is None - Returns a new zipper with None node
116 """
117 # Edge Case: Focus node is None
118 if self._node is None:
119 return Zipper(None, self._path)
120
121 new_node = {
122 "value": self._node["value"],
123 "left": tree,
124 "right": self._node["right"]
125 }
126 return Zipper(new_node, self._path)
127
19128 def right(self) -> "Zipper | None":
20 pass
21
129 """
130 Move the focus to the right child of the current node.
131
132 Returns:
133 Zipper | None: A new zipper focused on the right child, or None if no right child
134
135 Edge Case: Focus node is None - Returns None
136 Edge Case: No right child - Returns None
137 """
138 # Edge Case: Focus node is None
139 if self._node is None:
140 return None
141
142 # Edge Case: No right child
143 if self._node["right"] is None:
144 return None
145
146 # Create breadcrumb to store current node context
147 breadcrumb = {
148 "parent": {
149 "value": self._node["value"],
150 "left": self._node["left"]
151 },
152 "is_left": False
153 }
154
155 new_path = [breadcrumb] + self._path
156 return Zipper(self._node["right"], new_path)
157
22158 def set_right(self, tree: dict | None) -> "Zipper":
23 pass
24
159 """
160 Set the right child of the focus node, returning a new zipper.
161
162 Args:
163 tree (dict | None): The new right subtree or None
164
165 Returns:
166 Zipper: A new zipper with updated right child
167
168 Edge Case: Focus node is None - Returns a new zipper with None node
169 """
170 # Edge Case: Focus node is None
171 if self._node is None:
172 return Zipper(None, self._path)
173
174 new_node = {
175 "value": self._node["value"],
176 "left": self._node["left"],
177 "right": tree
178 }
179 return Zipper(new_node, 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 Zipper | None: A new zipper focused on the parent, or None if at root
187
188 Edge Case: Already at root (empty path) - Returns None
189 Edge Case: Focus node is None - Returns None
190 """
191 # Edge Case: Focus node is None or already at root
192 if self._node is None or not self._path:
193 return None
194
195 # Get the top breadcrumb
196 breadcrumb = self._path[0]
197 rest_path = self._path[1:]
198
199 parent = breadcrumb["parent"]
200
201 # Reconstruct the parent node with the current node in the correct position
202 if breadcrumb["is_left"]:
203 # Current node was the left child
204 reconstructed_parent = {
205 "value": parent["value"],
206 "left": self._node,
207 "right": parent.get("right")
208 }
209 else:
210 # Current node was the right child
211 reconstructed_parent = {
212 "value": parent["value"],
213 "left": parent.get("left"),
214 "right": self._node
215 }
216
217 return Zipper(reconstructed_parent, rest_path)
218
28219 def to_tree(self) -> dict:
29 pass
220 """
221 Convert the zipper back to a tree representation.
222
223 Returns:
224 dict: The complete tree with all modifications applied
225
226 Edge Case: Focus node is None - Reconstructs tree from path
227 """
228 # Navigate back to the root to get the complete tree
229 current_zipper = self
230
231 # Edge Case: Current zipper is already at root
232 if not self._path:
233 return self._node
234
235 # Move up until we reach the root
236 while True:
237 up_zipper = current_zipper.up()
238 if up_zipper is None:
239 break
240 current_zipper = up_zipper
241
242 return current_zipper._node
243
244# Handled Edge Cases: Empty tree in from_tree, None focus node in value, set_value, left, set_left, right, set_right, up, to_tree, No left child in left, No right child in right, Already at root in up
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.