let it go

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 a binary tree that allows navigation and manipulation.
4
5 The zipper maintains a focus on a specific node in the tree and allows
6 movement between parent and child nodes, as well as modification of
7 the tree structure.
8 """
9
10 def __init__(self, tree, breadcrumbs=None):
11 """
12 Initialize a Zipper with a tree and breadcrumbs.
13
14 Args:
15 tree (dict): The current subtree with keys 'value', 'left', 'right'
16 breadcrumbs (list): List of parent nodes and path information
17 """
18 self.tree = tree
19 self.breadcrumbs = breadcrumbs 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): A binary tree with keys 'value', 'left', 'right'
28
629
30 Returns:
31 Zipper: A new zipper focused on the root of the tree
32 """
33 # Edge Case: Empty tree
34 if tree is None:
35 return None
36 return Zipper(tree)
37
738 def value(self) -> int:
8 pass
39 """
40 Get the value of the focus node.
41
942
43 Returns:
44 int: The value of the current node
45 """
46 return self.tree["value"]
47
1048 def set_value(self, value: int) -> "Zipper":
11 pass
49 """
50 Set the value of the focus node.
51
1252
53 Args:
54 value (int): The new value for the focus node
55
56
57 Returns:
58 Zipper: A new zipper with the updated value
59 """
60 # Edge Case: None value
61 if value is None:
62 raise ValueError("Value cannot be None")
63
64 new_tree = {
65 "value": value,
66 "left": self.tree["left"],
67 "right": self.tree["right"]
68 }
69 return Zipper(new_tree, self.breadcrumbs)
70
1371 def left(self) -> "Zipper | None":
14 pass
72 """
73 Move the focus to the left child of the current node.
74
75
76 Returns:
77 Zipper | None: A new zipper focused on the left child, or None if no left child
78 """
79 # Edge Case: No left child
80 if self.tree["left"] is None:
81 return None
82
1583
84 # Create breadcrumb to remember current node when going back up
85 breadcrumb = {
86 "parent": {
87 "value": self.tree["value"],
88 "left": self.tree["left"],
89 "right": self.tree["right"]
90 },
91 "direction": "left"
92 }
93
94 return Zipper(self.tree["left"], self.breadcrumbs + [breadcrumb])
95
1696 def set_left(self, tree: dict | None) -> "Zipper":
17 pass
97 """
98 Replace the left subtree of the focus node.
99
100
101 Args:
102 tree (dict | None): The new left subtree
103
18104
105 Returns:
106 Zipper: A new zipper with the updated left subtree
107 """
108 new_tree = {
109 "value": self.tree["value"],
110 "left": tree,
111 "right": self.tree["right"]
112 }
113 return Zipper(new_tree, self.breadcrumbs)
114
19115 def right(self) -> "Zipper | None":
20 pass
116 """
117 Move the focus to the right child of the current node.
118
21119
120 Returns:
121 Zipper | None: A new zipper focused on the right child, or None if no right child
122 """
123 # Edge Case: No right child
124 if self.tree["right"] is None:
125 return None
126
127
128 # Create breadcrumb to remember current node when going back up
129 breadcrumb = {
130 "parent": {
131 "value": self.tree["value"],
132 "left": self.tree["left"],
133 "right": self.tree["right"]
134 },
135 "direction": "right"
136 }
137
138 return Zipper(self.tree["right"], self.breadcrumbs + [breadcrumb])
139
22140 def set_right(self, tree: dict | None) -> "Zipper":
23 pass
141 """
142 Replace the right subtree of the focus node.
143
144
145 Args:
146 tree (dict | None): The new right subtree
147
24148
149 Returns:
150 Zipper: A new zipper with the updated right subtree
151 """
152 new_tree = {
153 "value": self.tree["value"],
154 "left": self.tree["left"],
155 "right": tree
156 }
157 return Zipper(new_tree, self.breadcrumbs)
158
25159 def up(self) -> "Zipper | None":
26 pass
160 """
161 Move the focus to the parent of the current node.
162
27163
164 Returns:
165 Zipper | None: A new zipper focused on the parent, or None if at root
166 """
167 # Edge Case: Already at root (no breadcrumbs)
168 if not self.breadcrumbs:
169 return None
170
171
172 # Get the last breadcrumb (most recent parent)
173 last_breadcrumb = self.breadcrumbs[-1]
174 rest_breadcrumbs = self.breadcrumbs[:-1]
175
176 parent = last_breadcrumb["parent"]
177 direction = last_breadcrumb["direction"]
178
179 # Reconstruct the parent with the current tree in the correct position
180 if direction == "left":
181 new_parent = {
182 "value": parent["value"],
183 "left": self.tree,
184 "right": parent["right"]
185 }
186 else: # direction == "right"
187 new_parent = {
188 "value": parent["value"],
189 "left": parent["left"],
190 "right": self.tree
191 }
192
193
194 return Zipper(new_parent, rest_breadcrumbs)
195
28196 def to_tree(self) -> dict:
29 pass
197 """
198 Get the complete tree from the zipper.
199
200
201 Returns:
202 dict: The complete binary tree
203 """
204 # If we're at the root, return the tree
205 if not self.breadcrumbs:
206 return self.tree
207
208
209 # Navigate up to the root to get the complete tree
210 current = self
211 while current.breadcrumbs:
212 current = current.up()
213 return current.tree
214
215 # Handled Edge Cases: Empty tree in from_tree, None value in set_value,
216 # 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.