Een directory doorzoeken¶
Opdracht: Een directory doorzoeken
De gegeven code uit het werkcollege:
documents = {
"naam": "documenten",
"bestanden": {"verslag.docx": 120, "rooster.pdf": 300},
"directories": [
{
"naam": "projecten",
"bestanden": {"plan.docx": 40, "logo.png": 500},
"directories": [
{
"naam": "archief",
"bestanden": {"notulen.docx": 25, "setup.exe": 900},
"directories": [],
},
],
},
{
"naam": "foto's",
"bestanden": {"strand.jpg": 2000, "berg.jpg": 1800},
"directories": [],
},
{"naam": "leeg", "bestanden": {}, "directories": []},
],
}
EMPTY = {"naam": "leeg", "bestanden": {}, "directories": []}
PROJECTS = documents["directories"][0]
Stap 1: count_files(d)¶
def count_files(d):
"""Geeft het aantal bestanden in d en in al zijn subdirectories."""
n = len(d["bestanden"])
for sub in d["directories"]:
n = n + count_files(sub)
return n
assert count_files(documents) == 8
assert count_files(PROJECTS) == 4
assert count_files(EMPTY) == 0
Stap 2: total_size(d)¶
def total_size(d):
"""Geeft de totale grootte van de bestanden in d en al zijn subdirectories."""
return sum(d["bestanden"].values()) + sum(
[total_size(sub) for sub in d["directories"]]
)
assert total_size(documents) == 5685
assert total_size(PROJECTS) == 1465
assert total_size(EMPTY) == 0
Stap 3: safe_name(name)¶
Het basisgeval is de lege naam, en die is veilig. De recursie stopt eerder zodra er een verkeerd teken staat.
from string import ascii_letters, digits
SAFE_CHARS = ascii_letters + digits + "._-"
def safe_name(name):
"""Geeft True als name alleen letters, cijfers, punten, _ en - bevat."""
if name == "":
return True
elif name[-1] not in SAFE_CHARS:
return False
else:
return safe_name(name[:-1])
assert safe_name("verslag.docx") == True
assert safe_name("data_2024-01.csv") == True
assert safe_name("foto's") == False
assert safe_name("mijn cv.pdf") == False
assert safe_name("") == True
assert safe_name("café.txt") == False
Stap 4: unsafe_names(d)¶
def unsafe_names(d):
"""Geeft de namen in d en zijn subdirectories die niet veilig zijn."""
result = [name for name in d["bestanden"] if not safe_name(name)]
for sub in d["directories"]:
if not safe_name(sub["naam"]):
result = result + [sub["naam"]]
result = result + unsafe_names(sub)
return result
WORK = {
"naam": "mijn werk",
"bestanden": {"cv.pdf": 10, "brief 1.docx": 5},
"directories": [
{"naam": "oude versies", "bestanden": {"a:b.txt": 1}, "directories": []},
],
}
assert unsafe_names(documents) == ["foto's"]
assert unsafe_names(WORK) == ["brief 1.docx", "oude versies", "a:b.txt"]
assert unsafe_names(EMPTY) == []
Stap 5: depth(d)¶
def depth(d):
"""Geeft het aantal niveaus van d: 1 voor een directory zonder subdirectories."""
deepest = 0
for sub in d["directories"]:
sub_depth = depth(sub)
if sub_depth > deepest:
deepest = sub_depth
return 1 + deepest
assert depth(documents) == 3
assert depth(PROJECTS) == 2
assert depth(EMPTY) == 1