sourdough

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 through the tree structure while keeping track of the path taken.
7 """
8
9 def __init__(self, tree: dict, path: list = None):
10 """
11 Initialize a Zipper with a tree and optional path.
12
13 Args:
14 tree: The binary tree represented as a dict with keys 'value', 'left', 'right'
15 path: A list of tuples tracking the path to the current focus
16 """
17 self.tree = tree
18 self.path = path or []
19
320 @staticmethod
421 def from_tree(tree: dict) -> "Zipper":
5 pass
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
29 Returns:
30 A new Zipper instance focused on the root of the tree
31 """
32 # Edge Case: Handle None tree input
33 if tree is None:
34 return None
35 return Zipper(tree)
636
737 def value(self) -> int:
8 pass
38 """
39 Get the value of the focus node.
40
41
42 Returns:
43 The value of the current focus node
44 """
45 current = self.tree
46 for direction, parent in self.path:
47 if direction == 'left':
48 current = current['left']
49 else: # direction == 'right'
50 current = current['right']
51 return current['value']
952
1053 def set_value(self, value: int) -> "Zipper":
11 pass
54 """
55 Set the value of the focus node and return a new zipper.
56
57 Args:
58 value: The new value for the focus node
59
60
61 Returns:
62 A new Zipper instance 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(self.tree)
69 current = new_tree
70
71 for direction, parent in self.path:
72 if direction == 'left':
73 current = current['left']
74 else: # direction == 'right'
75 current = current['right']
76
77 current['value'] = value
78 return Zipper(new_tree, self.path.copy())
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 A new Zipper focused on the left child, or None if no left child exists
87 """
88 current = self.tree
89 for direction, parent in self.path:
90 if direction == 'left':
91 current = current['left']
92 else: # direction == 'right'
93 current = current['right']
94
95 # Edge Case: Handle case where current node has no left child
96 if current['left'] is None:
97 return None
98
99 new_path = self.path.copy()
100 new_path.append(('left', current))
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 and return a new zipper.
106
107 Args:
108 tree: The new left subtree (or None to remove the left child)
109
110
111 Returns:
112 A new Zipper instance with the updated left child
113 """
114 new_tree = self._copy_tree(self.tree)
115 current = new_tree
116
117 for direction, parent in self.path:
118 if direction == 'left':
119 current = current['left']
120 else: # direction == 'right'
121 current = current['right']
122
123 current['left'] = tree
124 return Zipper(new_tree, self.path.copy())
18125
19126 def right(self) -> "Zipper | None":
20 pass
127 """
128 Move the focus to the right child of the current node.
129
130
131 Returns:
132 A new Zipper focused on the right child, or None if no right child exists
133 """
134 current = self.tree
135 for direction, parent in self.path:
136 if direction == 'left':
137 current = current['left']
138 else: # direction == 'right'
139 current = current['right']
140
141 # Edge Case: Handle case where current node has no right child
142 if current['right'] is None:
143 return None
144
145 new_path = self.path.copy()
146 new_path.append(('right', current))
147 return Zipper(self.tree, new_path)
21148
22149 def set_right(self, tree: dict | None) -> "Zipper":
23 pass
150 """
151 Set the right child of the focus node and return a new zipper.
152
153 Args:
154 tree: The new right subtree (or None to remove the right child)
155
156
157 Returns:
158 A new Zipper instance with the updated right child
159 """
160 new_tree = self._copy_tree(self.tree)
161 current = new_tree
162
163 for direction, parent in self.path:
164 if direction == 'left':
165 current = current['left']
166 else: # direction == 'right'
167 current = current['right']
168
169 current['right'] = tree
170 return Zipper(new_tree, self.path.copy())
24171
25172 def up(self) -> "Zipper | None":
26 pass
173 """
174 Move the focus to the parent of the current node.
175
176
177 Returns:
178 A new Zipper focused on the parent node, or None if already at root
179 """
180 # Edge Case: Handle case where we're already at the root (no parent)
181 if not self.path:
182 return None
183
184 new_path = self.path.copy()
185 new_path.pop()
186 return Zipper(self.tree, new_path)
27187
28188 def to_tree(self) -> dict:
29 pass
189 """
190 Get the complete tree from the zipper.
191
192
193 Returns:
194 The complete binary tree as a dict
195 """
196 return self.tree
197
198 def _copy_tree(self, tree: dict) -> dict:
199 """
200 Create a deep copy of a binary tree.
201
202 Args:
203 tree: The tree to copy
204
205
206 Returns:
207 A deep copy of the tree
208 """
209 if tree is None:
210 return None
211
212 return {
213 'value': tree['value'],
214 'left': self._copy_tree(tree['left']),
215 'right': self._copy_tree(tree['right'])
216 }
217 # Handled Edge Cases: None tree input, None value input, no left child, no right child, already at 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.