armor

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 functional-style navigation and modification operations.
7 """
8
9 def __init__(self, tree, path=None):
10 """
11 Initialize a Zipper instance.
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 current focus node.
16 Each tuple contains (parent_tree, direction) where direction is 'left' or 'right'.
17 """
18 self.tree = tree
19 self.path = path or []
20
321 @staticmethod
422 def from_tree(tree: dict) -> "Zipper":
5 pass
23 """
24 Create a zipper from a binary tree.
25
26 Args:
27 tree (dict): The binary tree to create a zipper for.
28
629
30 Returns:
31 Zipper: A new zipper with focus on the root node.
32 """
33 # Edge Case: Handle None tree input
34 if tree is None:
35 return None
36 return Zipper(tree)
37
38 def _get_focus_node(self):
39 """
40 Get the current focus node based on the path.
41
42
43 Returns:
44 dict: The current focus node.
45 """
46 node = self.tree
47 for parent, direction in self.path:
48 node = node[direction]
49 return node
50
751 def value(self) -> int:
8 pass
52 """
53 Get the value of the focus node.
54
955
56 Returns:
57 int: The value of the focus node.
58 """
59 return self._get_focus_node()["value"]
60
1061 def set_value(self, value: int) -> "Zipper":
11 pass
62 """
63 Set the value of the focus node, returning a new zipper.
64
65 Args:
66 value (int): The new value for the focus node.
67
1268
69 Returns:
70 Zipper: A new zipper with the updated value.
71 """
72 # Edge Case: Handle None value input
73 if value is None:
74 raise ValueError("Value cannot be None")
75
76 # Create a deep copy of the tree
77 new_tree = self._deep_copy_tree(self.tree)
78
79 # Navigate to the focus node in the new tree
80 node = new_tree
81 for parent, direction in self.path:
82 node = node[direction]
83
84 # Update the value
85 node["value"] = value
86
87 return Zipper(new_tree, list(self.path))
88
1389 def left(self) -> "Zipper | None":
14 pass
90 """
91 Move the focus to the left child of the current node.
92
1593
94 Returns:
95 Zipper | None: A new zipper focused on the left child, or None if no left child exists.
96 """
97 focus_node = self._get_focus_node()
98 # Edge Case: Handle when there is no left child
99 if focus_node["left"] is None:
100 return None
101
102 new_path = list(self.path)
103 new_path.append((focus_node, "left"))
104 return Zipper(self.tree, new_path)
105
16106 def set_left(self, tree: dict | None) -> "Zipper":
17 pass
107 """
108 Set the left child of the focus node, returning a new zipper.
109
110 Args:
111 tree (dict | None): The new left subtree or None.
112
18113
114 Returns:
115 Zipper: A new zipper with the updated left child.
116 """
117 # Create a deep copy of the tree
118 new_tree = self._deep_copy_tree(self.tree)
119
120 # Navigate to the focus node in the new tree
121 node = new_tree
122 for parent, direction in self.path:
123 node = node[direction]
124
125 # Update the left child
126 node["left"] = tree
127
128 return Zipper(new_tree, list(self.path))
129
19130 def right(self) -> "Zipper | None":
20 pass
131 """
132 Move the focus to the right child of the current node.
133
21134
135 Returns:
136 Zipper | None: A new zipper focused on the right child, or None if no right child exists.
137 """
138 focus_node = self._get_focus_node()
139 # Edge Case: Handle when there is no right child
140 if focus_node["right"] is None:
141 return None
142
143 new_path = list(self.path)
144 new_path.append((focus_node, "right"))
145 return Zipper(self.tree, new_path)
146
22147 def set_right(self, tree: dict | None) -> "Zipper":
23 pass
148 """
149 Set the right child of the focus node, returning a new zipper.
150
151 Args:
152 tree (dict | None): The new right subtree or None.
153
24154
155 Returns:
156 Zipper: A new zipper with the updated right child.
157 """
158 # Create a deep copy of the tree
159 new_tree = self._deep_copy_tree(self.tree)
160
161 # Navigate to the focus node in the new tree
162 node = new_tree
163 for parent, direction in self.path:
164 node = node[direction]
165
166 # Update the right child
167 node["right"] = tree
168
169 return Zipper(new_tree, list(self.path))
170
25171 def up(self) -> "Zipper | None":
26 pass
172 """
173 Move the focus to the parent of the current node.
174
27175
176 Returns:
177 Zipper | None: A new zipper focused on the parent, or None if already at the root.
178 """
179 # Edge Case: Handle when already at the root (no parent)
180 if not self.path:
181 return None
182
183 new_path = list(self.path)
184 new_path.pop()
185 return Zipper(self.tree, new_path)
186
28187 def to_tree(self) -> dict:
29 pass
188 """
189 Get the complete binary tree from the zipper.
190
191
192 Returns:
193 dict: The binary tree.
194 """
195 return self.tree
196
197 def _deep_copy_tree(self, tree):
198 """
199 Create a deep copy of a binary tree.
200
201 Args:
202 tree (dict): The tree to copy.
203
204
205 Returns:
206 dict: A deep copy of the tree.
207 """
208 if tree is None:
209 return None
210
211 return {
212 "value": tree["value"],
213 "left": self._deep_copy_tree(tree["left"]),
214 "right": self._deep_copy_tree(tree["right"])
215 }
216
217 # Handled Edge Cases: None tree input in from_tree, None value input in set_value,
218 # No left child in left, No right child in right, No parent 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.