Решение на In-memory файлова система от Галина Димитрова

Обратно към всички решения

Към профила на Галина Димитрова

Резултати

  • 7 точки от тестове
  • 0 бонус точки
  • 7 точки общо
  • 10 успешни тест(а)
  • 8 неуспешни тест(а)

Код

# coding: utf-8
class FileSystemError(Exception):
pass
class NotEnoughSpaceError(FileSystemError):
pass
class FileSystemMountError(FileSystemError):
pass
class MountPointDoesNotExistError(FileSystemMountError):
pass
class MountPointNotADirectoryError(FileSystemMountError):
pass
class MountPointNotEmptyError(FileSystemMountError):
pass
class NotAMountpointError(FileSystemMountError):
pass
class NodeDoesNotExistError(FileSystemError):
pass
class SourceNodeDoesNotExistError(NodeDoesNotExistError):
pass
class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
pass
class DestinationNodeExistsError(NodeDoesNotExistError):
pass
class NonExplicitDirectoryDeletionError(NodeDoesNotExistError):
pass
class NonEmptyDirectoryDeletionError(NodeDoesNotExistError):
pass
class DestinationNotADirectoryError(NodeDoesNotExistError):
pass
class LinkPathError(FileSystemError):
pass
class SymbolicLink(object):
def __init__(self, path, link_path, fs_obj):
self.path = path
self.link_path = link_path
self.fs_obj = fs_obj
self.size = 1
self._content = None
@property
def content(self):
if self.link_path not in self.fs_obj.all_paths():
raise LinkPathError()
self._content = self.fs_obj.get_node(self.link_path).content
return self._content
class HardLink(object):
def __init__(self, path, content, fs_obj):
self.path = path
self.content = content
self.fs_obj = fs_obj
self.size = 1
@property
def files(self):
self._files = self.fs_obj.get_node(self.link_path).files
return self._files
@property
def directories(self):
self._directories = self.fs_obj.get_node(self.link_path).directories
return self._directories
@property
def nodes(self):
self._nodes = self.fs_obj.get_node(self.link_path).nodes
return self._nodes
class File(object):
def __init__(self, path, content=""):
self.path = path
self.is_directory = False
self.content = content
self.size = len(content) + 1
def __str__(self):
return self.content
def append(self, text):
self.content += text
def truncate(self, text):
self.content = text
self.size = len(content) + 1
class Directory(object):
def __init__(self, path, directories=[], files=[], links=[]):
self.path = path
self.is_directory = True
self.directories = directories
self.files = files
self.links = links
self.nodes = self.directories + self.files + self.links
self.size = 1
class FileSystem(object):
def __init__(self, system_size):
if system_size < 1:
raise NotEnoughSpaceError()
self.nodes = {}
self.nodes["/"] = Directory("/")
self.size = system_size
self.available_size = self.set_available_size()
def set_available_size(self):
system_size = self.size
used_size = 0
for node in self.nodes.values():
used_size += node.size
system_size -= used_size
return system_size
def all_paths(self):
return [obj.path for obj in self.nodes.values()]
def valid_path(self, path):
# removes multiple "/" from given path
valid = ""
for item in path.split("/"):
if item != "":
valid += "/" + item
if valid == "":
valid = "/"
return valid
def get_node(self, path):
path = self.valid_path(path)
if path in self.all_paths():
return self.nodes[path]
raise NodeDoesNotExistError()
def new_path(self, source, destination):
return destination + "/" + source.split("/")[-1]
def add_nodes_to_dir(self, path, is_dir):
b_dir = path.split("/")[:-1]
items = b_dir if b_dir != [""] else "/"
base_dir = "/".join(items)
if is_dir:
self.nodes[base_dir].directories.append(self.nodes[path])
self.nodes[base_dir].files.append(self.nodes[path])
def create(self, path, directory=False, content=''):
path = self.valid_path(path)
b_dir = path.split("/")[:-1]
items = b_dir if b_dir != [""] else "/"
base_dir = "/".join(items)
paths = self.all_paths()
if base_dir not in paths:
raise DestinationNodeDoesNotExistError()
elif self.available_size < (len(content) + 1):
raise NotEnoughSpaceError()
elif path in paths:
raise DestinationNodeExistsError()
else:
if directory:
self.nodes[path] = Directory(path)
self.add_nodes_to_dir(path, True)
self.available_size = self.set_available_size()
return self.nodes[path]
self.nodes[path] = File(path, content)
self.add_nodes_to_dir(path, False)
self.available_size = self.set_available_size()
return self.nodes[path]
def remove(self, path, directory=False, force=True):
path = self.valid_path(path)
obj = self.get_node(path)
if obj.is_directory and not directory:
raise NonExplicitDirectoryDeletionError()
elif obj.is_directory and obj.nodes != [] and not force:
raise NonEmptyDirectoryDeletionError()
else:
self.available_size += obj.size
self.nodes.pop(path)
def move(self, source, destination):
source = self.valid_path(source)
destination = self.valid_path(destination)
paths = self.all_paths()
dest_obj = self.get_node(destination)
if source not in paths:
raise SourceNodeDoesNotExistError()
elif destination not in paths:
raise DestinationNodeDoesNotExistError()
elif not dest_obj.is_directory:
raise DestinationNotADirectoryError()
elif self.new_path(source, destination) in dest_obj.nodes:
raise DestinationNodeExistsError()
else:
if self.nodes[source].is_directory:
self.create(self.new_path(source, destination), True)
else:
self.create(self.new_path(source, destination),
False, self.nodes[source].content)
self.nodes.pop(source)
def link(self, source, destination, symbolic=True):
source = self.valid_path(source)
destination = self.valid_path(destination)
if source not in self.all_paths() and symbolic:
raise NodeDoesNotExistError()
if self.get_node(source).is_directory and not symbolic:
raise DirectoryHardLinkError()
if source not in self.all_paths() and not symbolic:
raise SourceNodeDoesNotExistError()
else:
b_dir = destination.split("/")[:-1]
items = b_dir if b_dir != [""] else "/"
base_dir = "/".join(items)
if symbolic:
new_link = SymbolicLink(destination, source, self)
self.nodes[base_dir].links.append(new_link)
self.nodes[destination] = new_link
else:
new_link = HardLink(destination, source, self)
self.nodes[base_dir].links.append(new_link)
self.nodes[destination] = new_link
self.available_size -= new_link.size

Лог от изпълнението

..E.E.E.E....E.EEE
======================================================================
ERROR: test_hard_link_create (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_hard_link_to_directory (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_link_create (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_mounting (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_remove_empty_directory (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_remove_nonempty_directory (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_symlink_to_missing_file (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_valid_move (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

----------------------------------------------------------------------
Ran 18 tests in 16.167s

FAILED (errors=8)

История (2 версии и 0 коментара)

Галина обнови решението на 30.04.2015 00:00 (преди почти 9 години)

+class FileSystemError(Exception):
+ pass
+
+
+class FileSystemMountError(FileSystemError):
+ pass
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+ pass
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class LinkPathError(FileSystemError):
+ pass
+
+
+class File(object):
+ def __init__(self, path, content=""):
+ self.path = path
+ self.is_directory = False
+ self.content = content
+ self.size = len(content) + 1
+
+ def __str__(self):
+ return self.content
+
+ def append(self, text):
+ self.content += text
+
+ def truncate(self, text):
+ self.content = text
+ self.size = len(content) + 1
+
+
+class Directory(object):
+ def __init__(self, path, directories=[], files=[]):
+ self.path = path
+ self.is_directory = True
+ self.directories = directories
+ self.files = files
+ self.nodes = directories + files
+ self.size = 1
+
+
+class FileSystem(object):
+ def __init__(self, system_size):
+ if system_size < 1:
+ raise NotEnoughSpaceError()
+ self.nodes = {}
+ self.nodes["/"] = Directory("/")
+ self.size = system_size
+ self.available_size = self.set_available_size()
+
+ def set_available_size(self):
+ system_size = self.size
+ used_size = 0
+ for node in self.nodes.values():
+ used_size += node.size
+ system_size -= used_size
+ return system_size
+
+ def all_paths(self):
+ return [obj.path for obj in self.nodes.values()]
+
+ def valid_path(self, path):
+ valid = ""
+ for item in path.split("/"):
+ if item != "":
+ valid += "/" + item
+ if valid == "":
+ valid = "/"
+ return valid
+
+ def get_node(self, path):
+ path = self.valid_path(path)
+ if path in self.all_paths():
+ return self.nodes[path]
+ raise NodeDoesNotExistError()
+
+ def new_path(self, source, destination):
+ return destination + "/" + source.split("/")[-1]
+
+ def add_nodes_to_dir(self, path, is_dir):
+ b_dir = path.split("/")[:-1]
+ items = b_dir if b_dir != [""] else "/"
+ base_dir = "/".join(items)
+ if is_dir:
+ self.nodes[base_dir].directories.append(self.nodes[path])
+ self.nodes[base_dir].files.append(self.nodes[path])
+
+ def create(self, path, directory=False, content=''):
+ path = self.valid_path(path)
+ b_dir = path.split("/")[:-1]
+ items = b_dir if b_dir != [""] else "/"
+ base_dir = "/".join(items)
+ paths = self.all_paths()
+ if base_dir not in paths:
+ raise DestinationNodeDoesNotExistError
+ elif self.available_size < (len(content) + 1):
+ raise NotEnoughSpaceError()
+ elif path in paths:
+ raise DestinationNodeExistsError
+ else:
+ if directory:
+ self.nodes[path] = Directory(path)
+ self.add_nodes_to_dir(path, True)
+ self.available_size = self.set_available_size()
+ return self.nodes[path]
+ self.nodes[path] = File(path, content)
+ self.add_nodes_to_dir(path, False)
+ self.available_size = self.set_available_size()
+ return self.nodes[path]
+
+ def remove(self, path, directory=False, force=True):
+ path = self.valid_path(path)
+ obj = self.get_node(path)
+ if obj.is_directory and not directory:
+ raise NonExplicitDirectoryDeletionError()
+ elif obj.is_directory and obj.nodes != [] and not force:
+ raise NonEmptyDirectoryDeletionError()
+ else:
+ self.available_size += obj.size
+ self.nodes.pop(path)
+
+ def move(self, source, destination):
+ source = self.valid_path(source)
+ destination = self.valid_path(destination)
+
+ paths = self.all_paths()
+ dest_obj = self.get_node(destination)
+ if source not in paths:
+ raise SourceNodeDoesNotExistError()
+ elif destination not in paths:
+ raise DestinationNodeDoesNotExistError()
+ elif not dest_obj.is_directory:
+ raise DestinationNotADirectoryError()
+ elif self.new_path(source, destination) in dest_obj.nodes:
+ raise DestinationNodeExistsError()
+ else:
+ if self.nodes[source].is_directory:
+ self.create(self.new_path(source, destination), True)
+ else:
+ self.create(self.new_path(source, destination),
+ False,
+ self.nodes[source].content)
+ self.nodes.pop(source)
+
+ def link(self, source, destination, symbolic=True):
+ source = self.valid_path(source)
+ destination = self.valid_path(destination)
+ source_exists = source in self.all_paths()
+ is_dir = self.get_node(source).is_directory
+ if not source_exists and symbolic:
+ raise NodeDoesNotExistError()
+ if is_dir and not symbolic:
+ raise DirectoryHardLinkError()
+ if not source_exists and not symbolic and not is_dir:
+ raise SourceNodeDoesNotExistError()
+ else:
+ pass

Галина обнови решението на 30.04.2015 15:39 (преди почти 9 години)

+# coding: utf-8
+
+
class FileSystemError(Exception):
pass
+class NotEnoughSpaceError(FileSystemError):
+ pass
+
+
class FileSystemMountError(FileSystemError):
pass
class MountPointDoesNotExistError(FileSystemMountError):
pass
class MountPointNotADirectoryError(FileSystemMountError):
pass
class MountPointNotEmptyError(FileSystemMountError):
pass
+class NotAMountpointError(FileSystemMountError):
+ pass
+
+
class NodeDoesNotExistError(FileSystemError):
pass
class SourceNodeDoesNotExistError(NodeDoesNotExistError):
pass
class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
pass
+class DestinationNodeExistsError(NodeDoesNotExistError):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(NodeDoesNotExistError):
+ pass
+
+
+class NonEmptyDirectoryDeletionError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNotADirectoryError(NodeDoesNotExistError):
+ pass
+
+
class LinkPathError(FileSystemError):
pass
+class SymbolicLink(object):
+ def __init__(self, path, link_path, fs_obj):
+ self.path = path
+ self.link_path = link_path
+ self.fs_obj = fs_obj
+ self.size = 1
+ self._content = None
+
+ @property
+ def content(self):
+ if self.link_path not in self.fs_obj.all_paths():
+ raise LinkPathError()
+ self._content = self.fs_obj.get_node(self.link_path).content
+ return self._content
+
+
+class HardLink(object):
+ def __init__(self, path, content, fs_obj):
+ self.path = path
+ self.content = content
+ self.fs_obj = fs_obj
+ self.size = 1
+
+ @property
+ def files(self):
+ self._files = self.fs_obj.get_node(self.link_path).files
+ return self._files
+
+ @property
+ def directories(self):
+ self._directories = self.fs_obj.get_node(self.link_path).directories
+ return self._directories
+
+ @property
+ def nodes(self):
+ self._nodes = self.fs_obj.get_node(self.link_path).nodes
+ return self._nodes
+
+
class File(object):
def __init__(self, path, content=""):
self.path = path
self.is_directory = False
self.content = content
self.size = len(content) + 1
def __str__(self):
return self.content
def append(self, text):
self.content += text
def truncate(self, text):
self.content = text
self.size = len(content) + 1
class Directory(object):
- def __init__(self, path, directories=[], files=[]):
+ def __init__(self, path, directories=[], files=[], links=[]):
self.path = path
self.is_directory = True
self.directories = directories
self.files = files
- self.nodes = directories + files
+ self.links = links
+ self.nodes = self.directories + self.files + self.links
self.size = 1
class FileSystem(object):
def __init__(self, system_size):
if system_size < 1:
raise NotEnoughSpaceError()
self.nodes = {}
self.nodes["/"] = Directory("/")
self.size = system_size
self.available_size = self.set_available_size()
def set_available_size(self):
system_size = self.size
used_size = 0
for node in self.nodes.values():
used_size += node.size
system_size -= used_size
return system_size
def all_paths(self):
return [obj.path for obj in self.nodes.values()]
def valid_path(self, path):
+ # removes multiple "/" from given path
valid = ""
for item in path.split("/"):
if item != "":
valid += "/" + item
if valid == "":
valid = "/"
return valid
def get_node(self, path):
path = self.valid_path(path)
if path in self.all_paths():
return self.nodes[path]
raise NodeDoesNotExistError()
def new_path(self, source, destination):
return destination + "/" + source.split("/")[-1]
def add_nodes_to_dir(self, path, is_dir):
b_dir = path.split("/")[:-1]
items = b_dir if b_dir != [""] else "/"
base_dir = "/".join(items)
if is_dir:
self.nodes[base_dir].directories.append(self.nodes[path])
self.nodes[base_dir].files.append(self.nodes[path])
def create(self, path, directory=False, content=''):
path = self.valid_path(path)
b_dir = path.split("/")[:-1]
items = b_dir if b_dir != [""] else "/"
base_dir = "/".join(items)
paths = self.all_paths()
if base_dir not in paths:
- raise DestinationNodeDoesNotExistError
+ raise DestinationNodeDoesNotExistError()
elif self.available_size < (len(content) + 1):
raise NotEnoughSpaceError()
elif path in paths:
- raise DestinationNodeExistsError
+ raise DestinationNodeExistsError()
else:
if directory:
self.nodes[path] = Directory(path)
self.add_nodes_to_dir(path, True)
self.available_size = self.set_available_size()
return self.nodes[path]
self.nodes[path] = File(path, content)
self.add_nodes_to_dir(path, False)
self.available_size = self.set_available_size()
return self.nodes[path]
def remove(self, path, directory=False, force=True):
path = self.valid_path(path)
obj = self.get_node(path)
if obj.is_directory and not directory:
raise NonExplicitDirectoryDeletionError()
elif obj.is_directory and obj.nodes != [] and not force:
raise NonEmptyDirectoryDeletionError()
else:
self.available_size += obj.size
self.nodes.pop(path)
def move(self, source, destination):
source = self.valid_path(source)
destination = self.valid_path(destination)
-
paths = self.all_paths()
dest_obj = self.get_node(destination)
if source not in paths:
raise SourceNodeDoesNotExistError()
elif destination not in paths:
raise DestinationNodeDoesNotExistError()
elif not dest_obj.is_directory:
raise DestinationNotADirectoryError()
elif self.new_path(source, destination) in dest_obj.nodes:
raise DestinationNodeExistsError()
else:
if self.nodes[source].is_directory:
self.create(self.new_path(source, destination), True)
else:
self.create(self.new_path(source, destination),
- False,
- self.nodes[source].content)
+ False, self.nodes[source].content)
self.nodes.pop(source)
def link(self, source, destination, symbolic=True):
source = self.valid_path(source)
destination = self.valid_path(destination)
- source_exists = source in self.all_paths()
- is_dir = self.get_node(source).is_directory
- if not source_exists and symbolic:
+ if source not in self.all_paths() and symbolic:
raise NodeDoesNotExistError()
- if is_dir and not symbolic:
+ if self.get_node(source).is_directory and not symbolic:
raise DirectoryHardLinkError()
- if not source_exists and not symbolic and not is_dir:
+ if source not in self.all_paths() and not symbolic:
raise SourceNodeDoesNotExistError()
else:
- pass
+ b_dir = destination.split("/")[:-1]
+ items = b_dir if b_dir != [""] else "/"
+ base_dir = "/".join(items)
+
+ if symbolic:
+ new_link = SymbolicLink(destination, source, self)
+ self.nodes[base_dir].links.append(new_link)
+ self.nodes[destination] = new_link
+ else:
+ new_link = HardLink(destination, source, self)
+ self.nodes[base_dir].links.append(new_link)
+ self.nodes[destination] = new_link
+ self.available_size -= new_link.size