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 movement and modification operations while preserving immutability.
7 """
8
9 def __init__(self, tree, path=None):
10 """
11 Initialize a Zipper.
12
13 Args:
14 tree (dict): The binary tree represented as a nested dictionary.
15 path (list): A list of tuples representing the path to the focus node.
16 Each tuple contains (parent_node, direction) where direction
17 is 'left' or 'right'.
18 """
19 self.tree = tree
20 self.path = path or []
21
322 @staticmethod
423 def from_tree(tree: dict) -> "Zipper":
5 pass
24 """
25 Create a zipper from a binary tree.
26
27 Args:
28 tree (dict): A binary tree with keys "value", "left", and "right".
29
30
31 Returns:
32 Zipper: A new zipper with focus on the root node.
33 """
34 # Edge Case: Handle None tree input
35 if tree is None:
36 return None
37 return Zipper(tree)
638
739 def value(self) -> int:
8 pass
40 """
41 Get the value of the focus node.
42
43
44 Returns:
45 int: The value of the focus node.
46 """
47 current = self.tree
48 for node, direction in self.path:
49 current = current[direction]
50 return current["value"]
951
1052 def set_value(self, value: int) -> "Zipper":
11 pass
53 """
54 Set the value of the focus node.
55
56
57 Args:
58 value (int): The new value for the focus node.
59
60
61 Returns:
62 Zipper: A new zipper with the updated value.
63 """
64 # Edge Case: Handle None value input
65 if value is None:
66 raise ValueError("Value cannot be None")
67
68 new_tree = self._copy_tree()
69 current = new_tree
70
71 # Navigate to the focus node
72 for node, direction in self.path:
73 current = current[direction]
74
75 # Update the value
76 current["value"] = value
77
78 return Zipper(new_tree, self.path)
1279
1380 def left(self) -> "Zipper | None":
14 pass
81 """
82 Move the focus to the left child of the current node.
83
84
85 Returns:
86 Zipper | None: A new zipper focused on the left child, or None if no left child exists.
87 """
88 current = self.tree
89
90 # Navigate to the focus node
91 for node, direction in self.path:
92 current = current[direction]
93
94 # Check if left child exists
95 # Edge Case: Handle missing left child
96 if current["left"] is None:
97 return None
98
99 # Create new path with the left child added
100 new_path = self.path + [(current, "left")]
101 return Zipper(self.tree, new_path)
15102
16103 def set_left(self, tree: dict | None) -> "Zipper":
17 pass
104 """
105 Set the left child of the focus node.
106
107
108 Args:
109 tree (dict | None): The new left subtree or None to remove the left child.
110
111
112 Returns:
113 Zipper: A new zipper with the updated left child.
114 """
115 new_tree = self._copy_tree()
116 current = new_tree
117
118 # Navigate to the focus node
119 for node, direction in self.path:
120 current = current[direction]
121
122 # Update the left child
123 current["left"] = tree
124
125 return Zipper(new_tree, self.path)
18126
19127 def right(self) -> "Zipper | None":
20 pass
128 """
129 Move the focus to the right child of the current node.
130
131
132 Returns:
133 Zipper | None: A new zipper focused on the right child, or None if no right child exists.
134 """
135 current = self.tree
136
137 # Navigate to the focus node
138 for node, direction in self.path:
139 current = current[direction]
140
141 # Check if right child exists
142 # Edge Case: Handle missing right child
143 if current["right"] is None:
144 return None
145
146 # Create new path with the right child added
147 new_path = self.path + [(current, "right")]
148 return Zipper(self.tree, new_path)
21149
22150 def set_right(self, tree: dict | None) -> "Zipper":
23 pass
151 """
152 Set the right child of the focus node.
153
154
155 Args:
156 tree (dict | None): The new right subtree or None to remove the right child.
157
158
159 Returns:
160 Zipper: A new zipper with the updated right child.
161 """
162 new_tree = self._copy_tree()
163 current = new_tree
164
165 # Navigate to the focus node
166 for node, direction in self.path:
167 current = current[direction]
168
169 # Update the right child
170 current["right"] = tree
171
172 return Zipper(new_tree, self.path)
24173
25174 def up(self) -> "Zipper | None":
26 pass
175 """
176 Move the focus to the parent of the current node.
177
178
179 Returns:
180 Zipper | None: A new zipper focused on the parent, or None if already at root.
181 """
182 # Edge Case: Handle attempt to move up from root
183 if not self.path:
184 return None
185
186 # Remove the last element from the path to move up
187 new_path = self.path[:-1]
188 return Zipper(self.tree, new_path)
27189
28190 def to_tree(self) -> dict:
29 pass
191 """
192 Get the complete binary tree from the zipper.
193
194
195 Returns:
196 dict: The binary tree represented as a nested dictionary.
197 """
198 return self.tree
199
200 def _copy_tree(self) -> dict:
201 """
202 Create a deep copy of the tree.
203
204
205 Returns:
206 dict: A deep copy of the tree.
207 """
208 def _deep_copy(node):
209 if node is None:
210 return None
211 return {
212 "value": node["value"],
213 "left": _deep_copy(node["left"]),
214 "right": _deep_copy(node["right"])
215 }
216
217 return _deep_copy(self.tree)
218
219 # Handled Edge Cases: None tree input, None value input, missing left child,
220 # missing right child, attempt to move up from 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.