Implement an In-Memory File System
ShopifySoftware Engineer · OnsiteLast updated
Implement an in-memory file system with absolute and relative path resolution, sorted listing, directory changes, creation, and removal. Enforce deterministic error codes, atomic validation, recursive deletion rules, and protection for the current directory and its ancestors.
Implement an In-Memory File System
The source reports an in-memory file-system exercise but not its exact error serialization or current-directory removal policy. The error codes, driver, and busy-directory rule below are deterministic practice assumptions.
Implement:
class FileSystemError(Exception):
code: str
class FileSystem:
def ls(self, path: str = ".") -> list[str]: ...
def cd(self, path: str) -> None: ...
def add(self, path: str, is_directory: bool) -> None: ...
def remove(self, path: str, recursive: bool = False) -> None: ...
def run_file_system(operations: list[list[object]]) -> list[object]:
...
The file system starts with an empty root / and current working directory /. Directories contain named children; files contain no data.
Paths and Successful Results
- Support absolute and relative paths, repeated
/,.,.., and trailing separators. Traversal above root stays at root. An empty path string is invalid. ls(path)returns sorted child names for a directory and[basename]for a file.cd(path)changes the working directory only when the resolved target is a directory and returnsNone.add(path, is_directory)creates exactly one file or directory. The resolved parent must already be a directory, and the target must not exist. Success returnsNone.remove(path, recursive=False)removes a file or empty directory. A nonempty directory requiresrecursive=True. Success returnsNone.
Resolve the complete path before mutating anything. A file may be the final target of ls or remove, but no operation may traverse through a file.
Deterministic Errors
Class methods raise FileSystemError with exactly one of these codes:
"invalid_path": the path is not a nonempty string."not_found": a required component or target is absent."not_directory": traversal would continue through a file, orcdtargets a file."already_exists":addresolves to an existing node."root":removetargets/."busy":removetargets the current working directory or any of its ancestors, even withrecursive=True."directory_not_empty": a non-busy, non-root directory has children andrecursive=False.
For remove, resolve first, then apply error precedence root, busy, and directory_not_empty. Resolution errors occur before those checks. Every failed class operation is atomic: the tree and current working directory remain unchanged.
The driver uses these commands:
["LS"]or["LS", path]["CD", path]["ADD", path, is_directory]["REMOVE", path]or["REMOVE", path, recursive]
It returns one result per operation. On a successful command, append the method's result. On FileSystemError, append ["ERROR", code] and continue. A malformed command, unknown command, or non-Boolean flag appends ["ERROR", "invalid_operation"] without calling a class method.
Performance and Tests
Aim for time proportional to normalized path components plus returned output, except that recursive deletion is proportional to the removed subtree. Test above-root traversal, repeated separators, traversal through files, duplicate adds, failed cd, removing root, removing the current directory and each ancestor, recursive removal of an unrelated subtree, failure atomicity, and error precedence.
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.