Решение на In-memory файлова система от Мартин Филипов

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

Към профила на Мартин Филипов

Резултати

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

Код

class FileSystemError(Exception):
pass
class NodeDoesNotExistError(FileSystemError):
pass
class FileSystemMountError(FileSystemError):
pass
class NotEnoughSpaceError(FileSystemError):
pass
class SourceNodeDoesNotExistError(NodeDoesNotExistError):
pass
class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
pass
class DestinationNotADirectoryError(FileSystemError):
pass # ???
class DestinationNodeExistsError(FileSystemError):
pass # ????
class MountPointDoesNotExistError(FileSystemMountError):
pass
class MountPointNotADirectoryError(FileSystemMountError):
pass
class MountPointNotEmptyError(FileSystemMountError):
pass
class FileSystemRemoveError(FileSystemError):
pass
class NonExplicitDirectoryDeletionError(FileSystemRemoveError):
pass
class NonEmptyDirectoryDeletionError(FileSystemRemoveError):
pass
class File:
def __init__(self, name, content=''):
self.is_directory = False
self.name = name
self.content = content
self.size = len(self.content) + 1
def append(self, text):
self.content += text
def truncate(self, text):
self.content = text
class Directory:
def __init__(self, name, size):
self.is_directory = True
self.name = name
self.size = size
self.empty = True
self.nodes = list()
@property
def files(self):
return [x for x in self.nodes if type(x) is File]
@property
def directories(self):
return [x for x in self.nodes if type(x) is Directory]
def add_node(self, node):
self.nodes.append(node)
self.size += node.size
self.empty = False
def remove_node(self, node):
if node in self.nodes:
self.size -= node.size
self.nodes.remove(node)
def contains(self, node_name):
return any(node_name == node.name for node in self.nodes)
def get_node_with_name(self, node_name):
for node in self.nodes:
if node.name == node_name:
return node
class FileSystem:
def __init__(self, size):
self.size = size
self.available_size = self.size - 1
self.root = Directory('/', 1)
def __is_valid_path(self, path):
splitted_path = path.split('/')
if path == '/':
return True
if splitted_path[0] != '' or not path:
return False
current_node = self.root
for index in range(1, len(splitted_path)):
if not current_node.is_directory:
return False
if not current_node.contains(splitted_path[index]):
return False
current_node = \
current_node.get_node_with_name(splitted_path[index])
return True
def __get_parent(self, path):
if path.count('/') == 1:
return '/'
else:
return path.rsplit('/', maxsplit=1)[0]
def get_node(self, path):
if not self.__is_valid_path(path):
raise NodeDoesNotExistError
current_node = self.root
splitted_path = path.split('/')
if path == '/':
return self.root
for index in range(1, len(splitted_path)):
current_node = \
current_node.get_node_with_name(splitted_path[index])
return current_node
def create(self, path, directory=False, content=''):
# sizes need fixes
space_amount_needed = len(content) + 1
if space_amount_needed > self.available_size:
raise NotEnoughSpaceError
self.available_size -= space_amount_needed
node_name = path.rsplit('/', maxsplit=1)[1]
if not self.__is_valid_path(self.__get_parent(path)):
raise DestinationNodeDoesNotExistError
if self.__is_valid_path(path):
raise DestinationNodeExistsError
if directory:
self.get_node(
self.__get_parent(path)).add_node(Directory(node_name, 1))
else:
if self.get_node(self.__get_parent(path)).is_directory:
self.get_node(self.__get_parent(path)).add_node(
File(node_name, content))
else:
raise NodeDoesNotExistError # ??
self.get_node(self.__get_parent(path)).size += space_amount_needed
def remove(self, path, directory=False, force=True):
# sizes need fixes
if not self.__is_valid_path(path):
raise NodeDoesNotExistError # ?
if self.get_node(path).is_directory and not directory:
raise NonExplicitDirectoryDeletionError
if directory and not self.get_node(path).empty and not force:
raise NonEmptyDirectoryDeletionError
self.available_size += self.get_node(path).size
self.get_node(self.__get_parent(path)).size -= self.get_node(path).size
self.get_node(self.__get_parent(path)).remove_node(
self.get_node(path))
def move(self, source, destination):
if not self.__is_valid_path(source):
raise SourceNodeDoesNotExistError
if not self.__is_valid_path(destination):
raise DestinationNodeDoesNotExistError
if not self.get_node(destination).is_directory:
raise DestinationNotADirectoryError
if self.get_node(destination).contains(
source.rsplit('/', maxsplit=1)[1]):
raise DestinationNodeExistsError
self.get_node(destination).add_node(self.get_node(source))
for node in self.get_node(self.__get_parent(source)).nodes:
self.get_node(self.__get_parent(source)).remove_node(node)
def ls(self, path):
if not self.__is_valid_path(path):
raise NodeDoesNotExistError
if not self.get_node(path).is_directory:
raise NotADirectoryError
node_list = list()
for node in self.get_node(path).nodes:
node_list.append(node.name)
return node_list
def mount(self, file_system, path):
pass
def unmount(self, path):
pass
def link(self, source, destination, symbolic=True):
pass

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

..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.162s

FAILED (errors=9)

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

Мартин обнови решението на 30.04.2015 16:49 (преди почти 9 години)

+class FileSystemError(Exception):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+ pass
+
+
+class FileSystemMountError(FileSystemError):
+ pass
+
+
+class NotEnoughSpaceError(FileSystemError):
+ pass
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ pass # ???
+
+
+class DestinationNodeExistsError(FileSystemError):
+ pass # ????
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ pass
+
+
+class FileSystemRemoveError(FileSystemError):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(FileSystemRemoveError):
+ pass
+
+
+class NonEmptyDirectoryDeletionError(FileSystemRemoveError):
+ pass
+
+
+class File:
+
+ def __init__(self, name, content=''):
+ self.is_directory = False
+ self.name = name
+ self.content = content
+ self.size = len(self.content) + 1
+
+ def append(self, text):
+ self.content += text
+
+ def truncate(self, text):
+ self.content = text
+
+
+class Directory:
+
+ def __init__(self, name, size):
+ self.is_directory = True
+ self.name = name
+ self.size = size
+ self.empty = True
+ self.nodes = list()
+
+ @property
+ def files(self):
+ return [x for x in self.nodes if type(x) is File]
+
+ @property
+ def directories(self):
+ return [x for x in self.nodes if type(x) is Directory]
+
+ def add_node(self, node):
+ self.nodes.append(node)
+ self.size += node.size
+ self.empty = False
+
+ def remove_node(self, node):
+ if node in self.nodes:
+ self.size -= node.size
+ self.nodes.remove(node)
+
+ def contains(self, node_name):
+ return any(node_name == node.name for node in self.nodes)
+
+ def get_node_with_name(self, node_name):
+ for node in self.nodes:
+ if node.name == node_name:
+ return node
+
+
+class FileSystem:
+
+ def __init__(self, size):
+ self.size = size
+ self.available_size = self.size - 1
+ self.root = Directory('/', 1)
+
+ def __is_valid_path(self, path):
+ splitted_path = path.split('/')
+ if path == '/':
+ return True
+ if splitted_path[0] != '' or not path:
+ return False
+ current_node = self.root
+ for index in range(1, len(splitted_path)):
+ if not current_node.is_directory:
+ return False
+ if not current_node.contains(splitted_path[index]):
+ return False
+ current_node = \
+ current_node.get_node_with_name(splitted_path[index])
+ return True
+
+ def __get_parent(self, path):
+ if path.count('/') == 1:
+ return '/'
+ else:
+ return path.rsplit('/', maxsplit=1)[0]
+
+ def get_node(self, path):
+ if not self.__is_valid_path(path):
+ raise NodeDoesNotExistError
+ current_node = self.root
+ splitted_path = path.split('/')
+ if path == '/':
+ return self.root
+ for index in range(1, len(splitted_path)):
+ current_node = \
+ current_node.get_node_with_name(splitted_path[index])
+ return current_node
+
+ def create(self, path, directory=False, content=''):
+ # sizes need fixes
+ space_amount_needed = len(content) + 1
+ if space_amount_needed > self.available_size:
+ raise NotEnoughSpaceError
+ self.available_size -= space_amount_needed
+ node_name = path.rsplit('/', maxsplit=1)[1]
+ if not self.__is_valid_path(self.__get_parent(path)):
+ raise DestinationNodeDoesNotExistError
+ if self.__is_valid_path(path):
+ raise DestinationNodeExistsError
+ if directory:
+ self.get_node(
+ self.__get_parent(path)).add_node(Directory(node_name, 1))
+ else:
+ if self.get_node(self.__get_parent(path)).is_directory:
+ self.get_node(self.__get_parent(path)).add_node(
+ File(node_name, content))
+ else:
+ raise NodeDoesNotExistError # ??
+ self.get_node(self.__get_parent(path)).size += space_amount_needed
+
+ def remove(self, path, directory=False, force=True):
+ # sizes need fixes
+ if not self.__is_valid_path(path):
+ raise NodeDoesNotExistError # ?
+ if self.get_node(path).is_directory and not directory:
+ raise NonExplicitDirectoryDeletionError
+ if directory and not self.get_node(path).empty and not force:
+ raise NonEmptyDirectoryDeletionError
+ self.available_size += self.get_node(path).size
+ self.get_node(self.__get_parent(path)).size -= self.get_node(path).size
+ self.get_node(self.__get_parent(path)).remove_node(
+ self.get_node(path))
+
+ def move(self, source, destination):
+ if not self.__is_valid_path(source):
+ raise SourceNodeDoesNotExistError
+ if not self.__is_valid_path(destination):
+ raise DestinationNodeDoesNotExistError
+ if not self.get_node(destination).is_directory:
+ raise DestinationNotADirectoryError
+ if self.get_node(destination).contains(
+ source.rsplit('/', maxsplit=1)[1]):
+ raise DestinationNodeExistsError
+
+ self.get_node(destination).add_node(self.get_node(source))
+ for node in self.get_node(self.__get_parent(source)).nodes:
+ self.get_node(self.__get_parent(source)).remove_node(node)
+
+ def ls(self, path):
+ if not self.__is_valid_path(path):
+ raise NodeDoesNotExistError
+ if not self.get_node(path).is_directory:
+ raise NotADirectoryError
+ node_list = list()
+ for node in self.get_node(path).nodes:
+ node_list.append(node.name)
+ return node_list
+
+ def mount(self, file_system, path):
+ pass
+
+ def unmount(self, path):
+ pass
+
+ def link(self, source, destination, symbolic=True):
+ pass