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 A zipper contains a data structure and a pointer (focus) into that data structure.
6 It supports functional navigation and manipulation operations.
7
8 Attributes:
9 _focus (dict): The current node in focus with keys 'value', 'left', 'right'
10 _path (list): A list of tuples representing the path from root to focus
11 Each tuple contains (parent_node, is_left_child)
12 """
13
14 def __init__(self, focus: dict, path: list):
15 """
16 Initialize a Zipper.
17
18 Args:
19 focus (dict): The node currently in focus
20 path (list): The path from root to focus
21 """
22 self._focus = focus
23 self._path = path
24
325 @staticmethod
426 def from_tree(tree: dict) -> "Zipper":
5 pass
6
27 """
28 Create a zipper from a binary tree.
29
30 Args:
31 tree (dict): A binary tree represented as a dict with keys 'value', 'left', 'right'
32
33 Returns:
34 Zipper: A new zipper with focus on the root node
35
36 # Handled Edge Cases: None (tree is assumed to be valid per problem constraints)
37 """
38 # Edge Case: Handle None tree by creating an empty focus
39 if tree is None:
40 return Zipper(None, [])
41 return Zipper(tree, [])
42
743 def value(self) -> int:
8 pass
9
44 """
45 Get the value of the focus node.
46
47 Returns:
48 int: The value of the focus node
49
50 # Handled Edge Cases: Focus node is None
51 """
52 # Edge Case: If focus is None, return None or raise an exception
53 # Based on problem context, we assume valid operations, but we should handle None
54 if self._focus is None:
55 return None
56 return self._focus["value"]
57
1058 def set_value(self, value: int) -> "Zipper":
11 pass
12
59 """
60 Set the value of the focus node.
61
62 Args:
63 value (int): The new value for the focus node
64
65 Returns:
66 Zipper: A new zipper with updated focus node value
67
68 # Handled Edge Cases: Focus node is None
69 """
70 # Edge Case: If focus is None, we can't set a value
71 if self._focus is None:
72 return self
73
74 new_focus = {
75 "value": value,
76 "left": self._focus["left"],
77 "right": self._focus["right"]
78 }
79 return Zipper(new_focus, self._path)
80
1381 def left(self) -> "Zipper | None":
14 pass
15
82 """
83 Move the focus to the left child of the current node.
84
85 Returns:
86 Zipper | None: A new zipper with focus on the left child, or None if no left child
87
88 # Handled Edge Cases: Focus node is None, No left child exists
89 """
90 # Edge Case: If focus is None, we can't move left
91 if self._focus is None:
92 return None
93
94 # Edge Case: If there's no left child, return None
95 if self._focus["left"] is None:
96 return None
97
98 # Create a new path entry: (current_focus, True) where True indicates we went left
99 new_path = [(self._focus, True)] + self._path
100 return Zipper(self._focus["left"], new_path)
101
16102 def set_left(self, tree: dict | None) -> "Zipper":
17 pass
18
103 """
104 Set the left child of the focus node.
105
106 Args:
107 tree (dict | None): The new left subtree
108
109 Returns:
110 Zipper: A new zipper with updated left child
111
112 # Handled Edge Cases: Focus node is None
113 """
114 # Edge Case: If focus is None, we can't set a left child
115 if self._focus is None:
116 return self
117
118 new_focus = {
119 "value": self._focus["value"],
120 "left": tree,
121 "right": self._focus["right"]
122 }
123 return Zipper(new_focus, self._path)
124
19125 def right(self) -> "Zipper | None":
20 pass
21
126 """
127 Move the focus to the right child of the current node.
128
129 Returns:
130 Zipper | None: A new zipper with focus on the right child, or None if no right child
131
132 # Handled Edge Cases: Focus node is None, No right child exists
133 """
134 # Edge Case: If focus is None, we can't move right
135 if self._focus is None:
136 return None
137
138 # Edge Case: If there's no right child, return None
139 if self._focus["right"] is None:
140 return None
141
142 # Create a new path entry: (current_focus, False) where False indicates we went right
143 new_path = [(self._focus, False)] + self._path
144 return Zipper(self._focus["right"], new_path)
145
22146 def set_right(self, tree: dict | None) -> "Zipper":
23 pass
24
147 """
148 Set the right child of the focus node.
149
150 Args:
151 tree (dict | None): The new right subtree
152
153 Returns:
154 Zipper: A new zipper with updated right child
155
156 # Handled Edge Cases: Focus node is None
157 """
158 # Edge Case: If focus is None, we can't set a right child
159 if self._focus is None:
160 return self
161
162 new_focus = {
163 "value": self._focus["value"],
164 "left": self._focus["left"],
165 "right": tree
166 }
167 return Zipper(new_focus, self._path)
168
25169 def up(self) -> "Zipper | None":
26 pass
27
170 """
171 Move the focus to the parent node.
172
173 Returns:
174 Zipper | None: A new zipper with focus on the parent, or None if at root
175
176 # Handled Edge Cases: Already at root (no parent), Focus node is None
177 """
178 # Edge Case: If focus is None, we can't move up
179 if self._focus is None:
180 return None
181
182 # Edge Case: If path is empty, we're at the root and can't go up
183 if not self._path:
184 return None
185
186 # Get the parent node and whether we were in the left subtree
187 parent, is_left = self._path[0]
188
189 # Reconstruct the parent with the current focus as the appropriate child
190 if is_left:
191 new_parent = {
192 "value": parent["value"],
193 "left": self._focus,
194 "right": parent["right"]
195 }
196 else:
197 new_parent = {
198 "value": parent["value"],
199 "left": parent["left"],
200 "right": self._focus
201 }
202
203 # Return a new zipper with the parent as focus and the rest of the path
204 return Zipper(new_parent, self._path[1:])
205
28206 def to_tree(self) -> dict:
29 pass
207 """
208 Get the complete binary tree from the zipper.
209
210 Returns:
211 dict: The complete binary tree
212
213 # Handled Edge Cases: Focus node is None
214 """
215 # Edge Case: If focus is None, return None
216 if self._focus is None:
217 return None
218
219 # Start with the current focus
220 tree = self._focus
221
222 # Reconstruct the tree by moving up the path
223 for parent, is_left in self._path:
224 if is_left:
225 tree = {
226 "value": parent["value"],
227 "left": tree,
228 "right": parent["right"]
229 }
230 else:
231 tree = {
232 "value": parent["value"],
233 "left": parent["left"],
234 "right": tree
235 }
236
237 return 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.