xas

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 traversal and modification operations while preserving the tree structure.
7 """
8
9 def __init__(self, tree: dict, path: list = None):
10 """
11 Initialize a Zipper instance.
12
13 Args:
14 tree: The binary tree represented as a dict with keys 'value', 'left', 'right'
15 path: A list of breadcrumb dictionaries representing the path from root to focus
16 """
17 self.tree = tree
18 self.path = path or []
19
320 @staticmethod
421 def from_tree(tree: dict) -> "Zipper":
5 pass
6
22 """
23 Create a zipper from a binary tree, with focus on the root node.
24
25 Args:
26 tree: The binary tree represented as a dict with keys 'value', 'left', 'right'
27
28 Returns:
29 A new Zipper instance focused on the root of the tree
30 """
31 # Edge Case: Handle None tree input
32 if tree is None:
33 return None
34 return Zipper(tree)
35
736 def value(self) -> int:
8 pass
9
37 """
38 Get the value of the focus node.
39
40 Returns:
41 The value of the focus node
42 """
43 return self.tree["value"]
44
1045 def set_value(self, value: int) -> "Zipper":
11 pass
12
46 """
47 Set the value of the focus node, returning a new zipper.
48
49 Args:
50 value: The new value for the focus node
51
52 Returns:
53 A new Zipper instance with updated value
54 """
55 # Edge Case: Handle None value input
56 if value is None:
57 raise ValueError("Value cannot be None")
58
59 new_tree = {
60 "value": value,
61 "left": self.tree["left"],
62 "right": self.tree["right"]
63 }
64 return Zipper(new_tree, self.path.copy())
65
1366 def left(self) -> "Zipper | None":
14 pass
15
67 """
68 Move the focus to the left child of the current node.
69
70 Returns:
71 A new Zipper focused on the left child, or None if no left child exists
72 """
73 # Edge Case: Handle missing left child
74 if self.tree["left"] is None:
75 return None
76
77 # Create breadcrumb to remember current node when going back up
78 breadcrumb = {
79 "parent": {
80 "value": self.tree["value"],
81 "right": self.tree["right"]
82 },
83 "side": "left"
84 }
85
86 new_path = self.path.copy()
87 new_path.append(breadcrumb)
88
89 return Zipper(self.tree["left"], new_path)
90
1691 def set_left(self, tree: dict | None) -> "Zipper":
17 pass
18
92 """
93 Set the left child of the focus node, returning a new zipper.
94
95 Args:
96 tree: The new left subtree (or None to remove left child)
97
98 Returns:
99 A new Zipper instance with updated left child
100 """
101 new_tree = {
102 "value": self.tree["value"],
103 "left": tree,
104 "right": self.tree["right"]
105 }
106 return Zipper(new_tree, self.path.copy())
107
19108 def right(self) -> "Zipper | None":
20 pass
21
109 """
110 Move the focus to the right child of the current node.
111
112 Returns:
113 A new Zipper focused on the right child, or None if no right child exists
114 """
115 # Edge Case: Handle missing right child
116 if self.tree["right"] is None:
117 return None
118
119 # Create breadcrumb to remember current node when going back up
120 breadcrumb = {
121 "parent": {
122 "value": self.tree["value"],
123 "left": self.tree["left"]
124 },
125 "side": "right"
126 }
127
128 new_path = self.path.copy()
129 new_path.append(breadcrumb)
130
131 return Zipper(self.tree["right"], new_path)
132
22133 def set_right(self, tree: dict | None) -> "Zipper":
23 pass
24
134 """
135 Set the right child of the focus node, returning a new zipper.
136
137 Args:
138 tree: The new right subtree (or None to remove right child)
139
140 Returns:
141 A new Zipper instance with updated right child
142 """
143 new_tree = {
144 "value": self.tree["value"],
145 "left": self.tree["left"],
146 "right": tree
147 }
148 return Zipper(new_tree, self.path.copy())
149
25150 def up(self) -> "Zipper | None":
26 pass
27
151 """
152 Move the focus to the parent of the current node.
153
154 Returns:
155 A new Zipper focused on the parent node, or None if already at root
156 """
157 # Edge Case: Handle attempt to go up from root (no parent)
158 if not self.path:
159 return None
160
161 # Get the most recent breadcrumb
162 breadcrumb = self.path[-1]
163 parent = breadcrumb["parent"]
164 side = breadcrumb["side"]
165
166 # Reconstruct the parent node with the current tree in the correct position
167 new_tree = {
168 "value": parent["value"],
169 "left": parent["left"] if side == "right" else self.tree,
170 "right": parent["right"] if side == "left" else self.tree
171 }
172
173 # Create new path without the last breadcrumb
174 new_path = self.path[:-1]
175
176 return Zipper(new_tree, new_path)
177
28178 def to_tree(self) -> dict:
29 pass
179 """
180 Get the complete binary tree from the zipper.
181
182 Returns:
183 The complete binary tree as a dict
184 """
185 # If we're at the root, return the tree
186 if not self.path:
187 return self.tree
188
189 # Otherwise, navigate up to the root and return that tree
190 current = self
191 while current.path:
192 current = current.up()
193 return current.tree
194
195 # Handled Edge Cases: None tree input, None value input, missing left child, missing right child, attempt to go 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.