A camera writes photos, videos and sidecar files onto its memory card in nested folders such as /DCIM/2025_06_01/IMG_0001.jpg. You're writing the little in-memory model the camera's menu uses.
Implement CameraCard() with:
save(path) -> None: store a file atpath, creating any missing parent folders. Saving to a path that already holds a file changes nothing (it is still one file).find(folder, ext) -> list[str]: the full paths of every file anywhere underfolder(at any depth) whose name ends with"." + ext, sorted.extis given without the dot and matching is case-sensitive. A folder that doesn't exist (or a path that is a file) gives[].remove(path) -> int: delete the file or the whole folder atpathand return how many files were deleted. Deleting a folder takes everything inside it. The folder that contained it stays, even if it is now empty. If nothing exists atpath, return0and change nothing.remove("/")empties the card (the root itself stays).
card = CameraCard()
card.save("/DCIM/day1/a.jpg")
card.save("/DCIM/day1/a.xmp")
card.save("/DCIM/day2/b.jpg")
card.save("/c.jpg")
card.find("/", "jpg") # ["/DCIM/day1/a.jpg", "/DCIM/day2/b.jpg", "/c.jpg"]
card.find("/DCIM/day1", "xmp") # ["/DCIM/day1/a.xmp"]
card.remove("/DCIM/day1") # 2
card.find("/DCIM", "jpg") # ["/DCIM/day2/b.jpg"]
card.remove("/DCIM/day1") # 0 (already gone)
Paths are absolute, have no trailing slash (except the root "/"), and names are non-empty. Nobody saves a file where a folder is, or inside a file. A name like "jpg" (no dot) does not end with ".jpg". Up to a few thousand operations.
Show hint
keep folders as nested dicts (name → dict for a subfolder, name → None for a file). find is a DFS that carries the path built so far; remove walks to the parent and deletes one key, counting the files in what it removes.