from __future__ import annotations import re from dataclasses import dataclass @dataclass class File: name: str size: int def __equals__(self, other): return self.name == other.name and self.size == other.size @dataclass class Folder: name: str parent: Folder | None children: list[Folder | File] def __equals__(self, other): return self.name == other.name and self.parent == other.parent @property def full_name(self): if self.parent is None: return "/" else: return self.parent.full_name + f"/{self.name}" @property def size(self): return sum(map(lambda x: x.size, self.children)) def __lt__(self, other): return self.size < other.size def pretty_print(folder: Folder, depth: int = 0) -> None: print("".join([" " for i in range(depth + 1)]), end="- ") print(f"{folder.name} (dir)") for object in folder.children: if type(object) is Folder: pretty_print(object, depth + 1) else: print("".join([" " for i in range(depth + 2)]), end="- ") print(f"{object.name} (file, size={object.size})") def parse(filename: str) -> Folder: filesystem = Folder(name="/", parent=None, children=[]) with open(filename) as f: f.readline() current = filesystem while line := f.readline()[:-1]: if line[0] == "$": if match := re.match(r"\$ cd (.+)", line): folder_name = match.group(1) if folder_name != "..": current = filter(lambda x: x.name == folder_name, current.children).__next__() else: current = current.parent else: if match := re.match(r"(\d+) ((?:\w|.)+)", line): fichier = File(name=match.group(2), size=int(match.group(1))) current.children.append(fichier) elif match := re.match(r"dir (\w+)", line): folder = Folder(name=match.group(1), parent=current, children=[]) current.children.append(folder) return filesystem