Created
August 9, 2024 18:36
-
-
Save jaraco/a37365872703163393b44793cda34ad2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import Iterable | |
def unique(items): | |
return list(dict.fromkeys(items)) | |
class Tree: | |
def __init__(self, paths, at=""): | |
self.paths = tuple(paths) | |
self.at = at | |
@property | |
def name(self): | |
rest, sep, name = self.at.rpartition("/") | |
return name | |
@property | |
def children(self): | |
return unique( | |
Tree(self.paths, "/".join((self.at, self._child_name(path))).lstrip("/")) | |
for path in self.paths | |
if self._child_name(path) | |
) | |
def __hash__(self): | |
return hash(tuple(vars(self).values())) | |
def __eq__(self, other): | |
return vars(self) == vars(other) | |
def _child_name(self, path): | |
path = path.strip("/") | |
name, sep, rest = path.removeprefix(self.at).strip("/").partition("/") | |
return self._is_subpath(path) and name | |
def _is_subpath(self, path): | |
""" | |
Is path a subpath of self.at | |
""" | |
return ( | |
not self.at | |
or len(self.at) <= len(path) | |
and all( | |
left == right | |
for left, right in zip(path.split("/"), self.at.split("/")) | |
) | |
) | |
def __repr__(self): | |
return f"Tree(at={self.at!r})" | |
def generate_tree(paths: list[str]) -> None: | |
""" | |
Don't support non-root elements without a leading slash. (a/b) | |
""" | |
paths.sort() | |
render_level(Tree(paths).children) | |
def render_level(trees: Iterable[Tree], level=0): | |
for item in trees: | |
print(" " * level, f"-- {item.name}", sep="") | |
render_level(item.children, level=level + 1) | |
inputs = [ | |
"/a/b", | |
"/a/b/c", | |
"/a/b/c1.jpg", | |
"/d/e/", | |
"p1.png", | |
"p2.png", | |
"/a/b/fff", | |
"/b/a", | |
] | |
__name__ == "__main__" and generate_tree(inputs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment