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, allowing for
6 efficient navigation and modification operations.
7 """
8
9 def __init__(self, tree, breadcrumbs=None):
10 """
11 Initialize a Zipper instance.
12
13 Args:
14 tree (dict): The current subtree that the zipper is focused on.
15 breadcrumbs (list): A list of breadcrumb dictionaries representing the path from root to focus.
16 """
17 self.tree = tree
18 self.breadcrumbs = breadcrumbs or []
19
320 @staticmethod
421 def from_tree(tree: dict) -> "Zipper":
5 pass
6
22 """
23 Create a zipper from a binary tree.
24
25 Args:
26 tree (dict): A binary tree represented as a nested dictionary.
27
28 Returns:
29 Zipper: A new zipper instance focused on the root of the tree.
30
31 Edge Case: Empty tree (None) is handled by creating an empty zipper.
32 """
33 # Edge Case: Handle None 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 current node.
44
45 Edge Case: If the current tree is None, this would raise an error, but we assume valid state.
46 """
47 # Handled Edge Cases: Assumes valid state (tree is not None)
48 return self.tree["value"]
49
1050 def set_value(self, value: int) -> "Zipper":
11 pass
12
51 """
52 Set the value of the focus node.
53
54 Args:
55 value (int): The new value for the focus node.
56
57 Returns:
58 Zipper: A new zipper with the updated value.
59
60 Edge Case: If the current tree is None, creates a new node with the value.
61 """
62 # Edge Case: Handle None tree
63 if self.tree is None:
64 new_tree = {"value": value, "left": None, "right": None}
65 else:
66 new_tree = {"value": value, "left": self.tree["left"], "right": self.tree["right"]}
67 return Zipper(new_tree, self.breadcrumbs)
68 # Handled Edge Cases: None tree
69
1370 def left(self) -> "Zipper | None":
14 pass
15
71 """
72 Move the focus to the left child of the current node.
73
74 Returns:
75 Zipper | None: A new zipper focused on the left child, or None if no left child exists.
76
77 Edge Case: If there's no left child or current tree is None, returns None.
78 """
79 # Edge Case: Handle None tree or missing left child
80 if self.tree is None or self.tree["left"] is None:
81 return None
82
83 new_breadcrumbs = self.breadcrumbs + [{
84 "parent": self.tree,
85 "side": "left",
86 "sibling": self.tree["right"]
87 }]
88
89 return Zipper(self.tree["left"], new_breadcrumbs)
90 # Handled Edge Cases: None tree, missing left child
91
1692 def set_left(self, tree: dict | None) -> "Zipper":
17 pass
18
93 """
94 Set the left child of the focus node.
95
96 Args:
97 tree (dict | None): The new left subtree.
98
99 Returns:
100 Zipper: A new zipper with the updated left child.
101
102 Edge Case: If the current tree is None, creates a new node with the specified left child.
103 """
104 # Edge Case: Handle None tree
105 if self.tree is None:
106 new_tree = {"value": 0, "left": tree, "right": None} # Default value of 0
107 else:
108 new_tree = {"value": self.tree["value"], "left": tree, "right": self.tree["right"]}
109 return Zipper(new_tree, self.breadcrumbs)
110 # Handled Edge Cases: None tree
111
19112 def right(self) -> "Zipper | None":
20 pass
21
113 """
114 Move the focus to the right child of the current node.
115
116 Returns:
117 Zipper | None: A new zipper focused on the right child, or None if no right child exists.
118
119 Edge Case: If there's no right child or current tree is None, returns None.
120 """
121 # Edge Case: Handle None tree or missing right child
122 if self.tree is None or self.tree["right"] is None:
123 return None
124
125 new_breadcrumbs = self.breadcrumbs + [{
126 "parent": self.tree,
127 "side": "right",
128 "sibling": self.tree["left"]
129 }]
130
131 return Zipper(self.tree["right"], new_breadcrumbs)
132 # Handled Edge Cases: None tree, missing right child
133
22134 def set_right(self, tree: dict | None) -> "Zipper":
23 pass
24
135 """
136 Set the right child of the focus node.
137
138 Args:
139 tree (dict | None): The new right subtree.
140
141 Returns:
142 Zipper: A new zipper with the updated right child.
143
144 Edge Case: If the current tree is None, creates a new node with the specified right child.
145 """
146 # Edge Case: Handle None tree
147 if self.tree is None:
148 new_tree = {"value": 0, "left": None, "right": tree} # Default value of 0
149 else:
150 new_tree = {"value": self.tree["value"], "left": self.tree["left"], "right": tree}
151 return Zipper(new_tree, self.breadcrumbs)
152 # Handled Edge Cases: None tree
153
25154 def up(self) -> "Zipper | None":
26 pass
27
155 """
156 Move the focus to the parent of the current node.
157
158 Returns:
159 Zipper | None: A new zipper focused on the parent, or None if already at the root.
160
161 Edge Case: If already at root (no breadcrumbs), returns None.
162 """
163 # Edge Case: Handle already at root
164 if not self.breadcrumbs:
165 return None
166
167 breadcrumb = self.breadcrumbs[-1]
168 parent = breadcrumb["parent"].copy()
169
170 # Reconstruct the parent with the current tree in the correct position
171 if breadcrumb["side"] == "left":
172 parent["left"] = self.tree
173 parent["right"] = breadcrumb["sibling"]
174 else: # breadcrumb["side"] == "right"
175 parent["right"] = self.tree
176 parent["left"] = breadcrumb["sibling"]
177
178 return Zipper(parent, self.breadcrumbs[:-1])
179 # Handled Edge Cases: Already at root
180
28181 def to_tree(self) -> dict:
29 pass
182 """
183 Get the complete binary tree from the zipper.
184
185 Returns:
186 dict: The complete binary tree.
187
188 Edge Case: If the zipper is focused on a None tree, reconstructs the full tree from breadcrumbs.
189 """
190 # Start with the current tree
191 current = self.tree
192
193 # Work backwards through breadcrumbs to reconstruct the full tree
194 for breadcrumb in reversed(self.breadcrumbs):
195 parent = breadcrumb["parent"].copy()
196
197 # Place the current tree in the correct position
198 if breadcrumb["side"] == "left":
199 parent["left"] = current
200 parent["right"] = breadcrumb["sibling"]
201 else: # breadcrumb["side"] == "right"
202 parent["right"] = current
203 parent["left"] = breadcrumb["sibling"]
204
205 current = parent
206
207 return current
208 # Handled Edge Cases: None tree at focus
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.