Add support for transparent nodes to depth first search python script.

This commit is contained in:
Tom Alexander
2026-06-27 18:02:50 -04:00
parent 25c0ccad0c
commit 4ea47a3459

View File

@@ -21,11 +21,15 @@ def main():
activity_tree.activities[9] = Activity(id=9, parent=8, text="I")
activity_tree.activities[10] = Activity(id=10, parent=9, text="J")
match_iter = MatchIter(activity_tree, lambda act: act.id in (2, 5, 10))
match_iter = MatchIter(
activity_tree,
lambda act: act.id in (2, 5, 10),
lambda act: act.id in (4,),
)
while (depth_and_node := match_iter.get_next()) is not None:
depth, matched, node = depth_and_node
print("\t".join((str(depth), str(matched), node.text)))
depth, matched, transparent, node = depth_and_node
print("\t".join((str(depth), str(matched), str(transparent), node.text)))
# while True:
# print("\n\n\nvvvvvvvvvv\n\n")
@@ -56,21 +60,27 @@ class MatchIter:
activity_tree: ActivityTree
stack: deque[StackEntry]
is_match: Callable[[Activity], bool]
is_transparent: Callable[[Activity], bool]
def __init__(
self, activity_tree: ActivityTree, is_match: Callable[[Activity], bool]
self,
activity_tree: ActivityTree,
is_match: Callable[[Activity], bool],
is_transparent: Callable[[Activity], bool],
) -> None:
self.activity_tree = activity_tree
self.stack = deque([StackEntry(0)])
self.is_match = is_match
self.is_transparent = is_transparent
def get_next(self) -> tuple[int, bool, Activity] | None:
def get_next(self) -> tuple[int, bool, bool, Activity] | None:
if (next_announce := self.get_next_announce()) is not None:
next_announce_depth, next_announce_entry = next_announce
next_announce_entry.announced = True
return (
next_announce_depth,
next_announce_entry.matched,
next_announce_entry.transparent,
self.activity_tree.activities[next_announce_entry.node_id],
)
@@ -91,6 +101,7 @@ class MatchIter:
parent.should_announce = True
stack_entry.visited = True
stack_entry.transparent = self.is_transparent(node)
children = [
c for c in self.activity_tree.activities.values() if c.parent == node.id
@@ -109,6 +120,7 @@ class MatchIter:
return (
next_announce_depth,
next_announce_entry.matched,
next_announce_entry.transparent,
self.activity_tree.activities[next_announce_entry.node_id],
)
@@ -121,7 +133,13 @@ class MatchIter:
def get_next_announce(self) -> tuple[int, StackEntry] | None:
for entry in self.stack:
if entry.should_announce and not entry.announced:
depth = len(list(self.walk_up_stack(entry)))
depth = len(
list(
entry
for entry in self.walk_up_stack(entry)
if not entry.transparent
)
)
return (depth, entry)
return None
@@ -146,10 +164,11 @@ class StackEntry:
should_announce: bool = False
visited: bool = False
matched: bool = False
transparent: bool = False
def text(self, activity_tree: ActivityTree) -> str:
node = activity_tree.activities[self.node_id]
return f"{node.text}\t{"annced" if self.announced else "-"}\t{"should" if self.should_announce else "-"}\t{"visited" if self.visited else "-"}\t{"matched" if self.matched else "-"}"
return f"{node.text}\t{"annced" if self.announced else "-"}\t{"should" if self.should_announce else "-"}\t{"visited" if self.visited else "-"}\t{"matched" if self.matched else "-"}\t{"trans" if self.transparent else "-"}"
if __name__ == "__main__":