72 lines
2.2 KiB
Python
72 lines
2.2 KiB
Python
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
|