Решение на In-memory файлова система от Цветан Коев

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

Към профила на Цветан Коев

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 9 успешни тест(а)
  • 9 неуспешни тест(а)

Код

class FileSystemError(Exception):
pass
class NodeDoesNotExistError(FileSystemError):
pass
class SourceNodeDoesNotExistError(NodeDoesNotExistError, FileSystemError):
pass
class DestinationNodeDoesNotExistError(NodeDoesNotExistError, FileSystemError):
pass
class FileSystemMountError(FileSystemError):
pass
class MountPointDoesNotExistError(FileSystemMountError, FileSystemError):
pass
class MountPointNotADirectoryError(FileSystemMountError, FileSystemError):
pass
class MountPointNotEmptyError(FileSystemMountError, FileSystemError):
pass
class NotAMountpointError(FileSystemMountError, FileSystemError):
pass
class NotEnoughSpaceError(FileSystemError):
pass
class NonExplicitDirectoryDeletionError(FileSystemError):
pass
class NonEmptyDirectoryDeletionError(FileSystemError):
pass
class DestinationNotADirectoryError(FileSystemError):
pass
class DestinationNodeExistsError(FileSystemError):
pass
class File:
def __init__(self, name, content):
self.content = content
self.is_directory = False
self.name = name
self.size = len(content) + 1
def append(self, text):
self.content += text
self.size += len(text)
def truncate(self, text):
self.content = text
self.size = len(text)
def remove(self, filesystem):
filesystem.available_size += self.size
class Directory:
def __init__(self, name):
self.directories = []
self.files = []
self.nodes = []
self.name = name
self.is_directory = True
self.is_root = False
def add_file(self, file_to_add):
self.files.append(file_to_add)
self.nodes.append(file_to_add)
def add_directory(self, directory):
self.directories.append(directory)
self.nodes.append(directory)
def remove(self, filesystem):
filesystem.available_size += 1
for node in self.nodes:
node.remove(filesystem)
class FileSystem:
def __init__(self, size):
self.size = size
self.available_size = size - 1
self.root = Directory("")
self.root.is_root = True
def get_node(self, path):
if path == "":
return self.root
path = path.split('/')
if path[1] == "":
return self.root
current_dir = self.root
for directory in path[1:-1]:
is_directory_found = False
for dirr in current_dir.directories:
if directory == dirr.name:
is_directory_found = True
current_dir = dirr
if not is_directory_found:
raise NodeDoesNotExistError
for node in current_dir.nodes:
if node.name == path[-1]:
return node
raise NodeDoesNotExistError
def create(self, path, directory=False, content=''):
if self.available_size - len(content) - 1 < 0:
raise NotEnoughSpaceError
path, node_name = path.rsplit('/', 1)
if path == '':
father_node = self.root
else:
try:
father_node = self.get_node(path)
except (NodeDoesNotExistError):
raise DestinationNodeDoesNotExistError
if father_node.is_directory is False:
raise DestinationNodeDoesNotExistError
for node in father_node.nodes:
if node.name == node_name:
raise DestinationNodeExistsError
self.available_size = self.available_size - len(content) - 1
if directory:
new_directory = Directory(node_name)
father_node.add_directory(new_directory)
else:
new_file = File(node_name, content)
father_node.add_file(new_file)
def remove(self, path, directory=False, force=True):
path, node_name = path.rsplit('/', 1)
if path == '':
father_node = self.root
else:
try:
father_node = self.get_node(path)
except (NodeDoesNotExistError):
raise NodeDoesNotExistError
node_to_delete = None
for node in father_node.nodes:
if node.name == node_name:
node_to_delete = node
if node_to_delete is None:
raise NodeDoesNotExistError
if node_to_delete.is_directory and directory is False:
raise NonExplicitDirectoryDeletionError
if (node_to_delete.is_directory and len(node_to_delete.nodes) > 0
and force is False):
raise NonEmptyDirectoryDeletionError
if node_to_delete.is_directory:
node_to_delete.remove(self)
father_node.nodes.remove(node_to_delete)
father_node.directories.remove(node_to_delete)
else:
node_to_delete.remove(self)
father_node.nodes.remove(node_to_delete)
father_node.files.remove(node_to_delete)
def mount(self, file_system, path):
try:
mount_node = self.get_node(path)
except (NodeDoesNotExistError):
raise MountPointDoesNotExistError
if mount_node.is_directory is False:
raise MountPointNotEmptyError
if len(mount_node.nodes) > 0:
raise MountPointNotEmptyError
father_node = self.get_node(path.rsplit('/', 1)[0])
father_node.nodes.remove(mount_node)
father_node.directories.remove(mount_node)
file_system.root.name = mount_node.name
father_node.nodes.append(file_system.root)
father_node.directories.append(file_system.root)
def unmount(self, path):
try:
unmount_node = self.get_node(path)
except (NodeDoesNotExistError):
raise NodeDoesNotExistError
if unmount_node.is_root is False:
raise NotAMountpointError
father_node = self.get_node(path.rsplit('/', 1)[0])
father_node.nodes.remove(unmount_node)
father_node.directories.remove(unmount_node)
regular_directory = Directory(unmount_node.name)
father_node.nodes.append(regular_directory)
father_node.directories.append(regular_directory)
def move(self, source, destination):
try:
source_node = self.get_node(source)
except (NodeDoesNotExistError):
raise SourceNodeDoesNotExistError
try:
destination_node = self.get_node(destination)
except (NodeDoesNotExistError):
raise DestinationNodeDoesNotExistError
if destination_node.is_directory is False:
raise DestinationNotADirectoryError
for node in destination_node.nodes:
if node.name == source_node.name:
raise DestinationNodeExistsError
father_node = self.get_node(source.rsplit('/', 1)[0])
father_node.nodes.remove(source_node)
destination_node.nodes.append(source_node)
if source_node.is_directory:
father_node.directories.remove(source_node)
destination_node.directories.append(source_node)
else:
father_node.files.remove(source_node)
destination_node.files.append(source_node)

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

..EEEEE.E....E.EE.
======================================================================
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_space_consumption (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_hard_link_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_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

----------------------------------------------------------------------
Ran 18 tests in 18.171s

FAILED (errors=9)

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

Цветан обнови решението на 30.04.2015 02:01 (преди над 9 години)

+class FileSystemError(Exception):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+ pass
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError, FileSystemError):
+ pass
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError, FileSystemError):
+ pass
+
+
+class FileSystemMountError(FileSystemError):
+ pass
+
+
+class MountPointDoesNotExistError(FileSystemMountError, FileSystemError):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError, FileSystemError):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError, FileSystemError):
+ pass
+
+
+class NotAMountpointError(FileSystemMountError, FileSystemError):
+ pass
+
+
+class NotEnoughSpaceError(FileSystemError):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ pass
+
+
+class DestinationNodeExistsError(FileSystemError):
+ pass
+
+
+class File:
+
+ def __init__(self, name, content):
+ self.content = content
+ self.is_directory = False
+ self.name = name
+ self.size = len(content) + 1
+
+ def append(self, text):
+ self.content += text
+ self.size += len(text)
+
+ def truncate(self, text):
+ self.content = text
+ self.size = len(text)
+
+ def remove(self, filesystem):
+ filesystem.available_size += self.size
+
+
+class Directory:
+
+ def __init__(self, name):
+ self.directories = []
+ self.files = []
+ self.nodes = []
+ self.name = name
+ self.is_directory = True
+ self.is_root = False
+
+ def add_file(self, file_to_add):
+ self.files.append(file_to_add)
+ self.nodes.append(file_to_add)
+
+ def add_directory(self, directory):
+ self.directories.append(directory)
+ self.nodes.append(directory)
+
+ def remove(self, filesystem):
+ filesystem.available_size += 1
+ for node in self.nodes:
+ node.remove(filesystem)
+
+
+class FileSystem:
+
+ def __init__(self, size):
+ self.size = size
+ self.available_size = size - 1
+ self.root = Directory("")
+ self.root.is_root = True
+
+ def get_node(self, path):
+ if path == "":
+ return self.root
+ path = path.split('/')
+ if path[1] == "":
+ return self.root
+ current_dir = self.root
+ for directory in path[1:-1]:
+ is_directory_found = False
+ for dirr in current_dir.directories:
+ if directory == dirr.name:
+ is_directory_found = True
+ current_dir = dirr
+ if not is_directory_found:
+ raise NodeDoesNotExistError
+ for node in current_dir.nodes:
+ if node.name == path[-1]:
+ return node
+ raise NodeDoesNotExistError
+
+ def create(self, path, directory=False, content=''):
+ if self.available_size - len(content) - 1 < 0:
+ raise NotEnoughSpaceError
+ path, node_name = path.rsplit('/', 1)
+
+ if path == '':
+ father_node = self.root
+ else:
+ try:
+ father_node = self.get_node(path)
+ except (NodeDoesNotExistError):
+ raise DestinationNodeDoesNotExistError
+ if father_node.is_directory is False:
+ raise DestinationNodeDoesNotExistError
+ for node in father_node.nodes:
+ if node.name == node_name:
+ raise DestinationNodeExistsError
+
+ self.available_size = self.available_size - len(content) - 1
+ if directory:
+ new_directory = Directory(node_name)
+ father_node.add_directory(new_directory)
+ else:
+ new_file = File(node_name, content)
+ father_node.add_file(new_file)
+
+ def remove(self, path, directory=False, force=True):
+ path, node_name = path.rsplit('/', 1)
+
+ if path == '':
+ father_node = self.root
+ else:
+ try:
+ father_node = self.get_node(path)
+ except (NodeDoesNotExistError):
+ raise NodeDoesNotExistError
+ node_to_delete = None
+ for node in father_node.nodes:
+ if node.name == node_name:
+ node_to_delete = node
+ if node_to_delete is None:
+ raise NodeDoesNotExistError
+
+ if node_to_delete.is_directory and directory is False:
+ raise NonExplicitDirectoryDeletionError
+ if (node_to_delete.is_directory and len(node_to_delete.nodes) > 0
+ and force is False):
+ raise NonEmptyDirectoryDeletionError
+
+ if node_to_delete.is_directory:
+ node_to_delete.remove(self)
+ father_node.nodes.remove(node_to_delete)
+ father_node.directories.remove(node_to_delete)
+ else:
+ node_to_delete.remove(self)
+ father_node.nodes.remove(node_to_delete)
+ father_node.files.remove(node_to_delete)
+
+ def mount(self, file_system, path):
+ try:
+ mount_node = self.get_node(path)
+ except (NodeDoesNotExistError):
+ raise MountPointDoesNotExistError
+
+ if mount_node.is_directory is False:
+ raise MountPointNotEmptyError
+ if len(mount_node.nodes) > 0:
+ raise MountPointNotEmptyError
+
+ father_node = self.get_node(path.rsplit('/', 1)[0])
+ father_node.nodes.remove(mount_node)
+ father_node.directories.remove(mount_node)
+ file_system.root.name = mount_node.name
+ father_node.nodes.append(file_system.root)
+ father_node.directories.append(file_system.root)
+
+ def unmount(self, path):
+ try:
+ unmount_node = self.get_node(path)
+ except (NodeDoesNotExistError):
+ raise NodeDoesNotExistError
+
+ if unmount_node.is_root is False:
+ raise NotAMountpointError
+
+ father_node = self.get_node(path.rsplit('/', 1)[0])
+ father_node.nodes.remove(unmount_node)
+ father_node.directories.remove(unmount_node)
+ regular_directory = Directory(unmount_node.name)
+ father_node.nodes.append(regular_directory)
+ father_node.directories.append(regular_directory)
+
+ def move(self, source, destination):
+ try:
+ source_node = self.get_node(source)
+ except (NodeDoesNotExistError):
+ raise SourceNodeDoesNotExistError
+
+ try:
+ destination_node = self.get_node(destination)
+ except (NodeDoesNotExistError):
+ raise DestinationNodeDoesNotExistError
+
+ if destination_node.is_directory is False:
+ raise DestinationNotADirectoryError
+ for node in destination_node.nodes:
+ if node.name == source_node.name:
+ raise DestinationNodeExistsError
+
+ father_node = self.get_node(source.rsplit('/', 1)[0])
+ father_node.nodes.remove(source_node)
+ destination_node.nodes.append(source_node)
+ if source_node.is_directory:
+ father_node.directories.remove(source_node)
+ destination_node.directories.append(source_node)
+ else:
+ father_node.files.remove(source_node)
+ destination_node.files.append(source_node)