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

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

Към профила на Красимир Атанасов

Резултати

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

Код

class FileSystemError(Exception):
pass
class NotEnoughSpaceError(FileSystemError):
pass
class NodeDoesNotExistError(FileSystemError):
pass
class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
pass
class SourceNodeDoesNotExistError(NodeDoesNotExistError):
pass
class DestinationNodeExistError(FileSystemError):
pass
class NonExplicitDirectoryDeletionError(FileSystemError):
pass
class NonEmptyDirectoryDeletionError(FileSystemError):
pass
class DestinationNotADirectoryError(FileSystemError):
pass
class File:
def __init__(self, content, path):
self.is_directory = False
self.content = content
self.size = len(self.content) + 1
self.path = path
def append(self, text):
self.content += text
self.size = len(self.content) + 1
def truncate(self, text):
self.content = text
self.size = len(self.content) + 1
def get_name(self):
if self.path == '/':
return ''
return self.path[self.path.rfind('/') + 1:]
class Directory:
def __init__(self, path):
self.is_directory = True
self.directories = []
self.files = []
self.nodes = []
self.path = path
def add_node(self, node):
if node.is_directory:
self.directories.append(node)
else:
self.files.append(node)
self.nodes.append(node)
def remove_node(self, node):
if node.is_directory:
self.directories.remove(node)
else:
self.files.remove(node)
self.nodes.remove(node)
def get_name(self):
if self.path == '/':
return ''
return self.path[self.path.rfind('/') + 1:]
class FileSystem:
def __init__(self, size):
self.size = size
self.available_size = size - 1
self.__nodes = {'/': Directory('/')}
def __str__(self):
s = ''
for k in self.__nodes.keys():
s += '{0}: {1}\n'.format(k, self.__nodes[k])
return s
def _get_parent_directory_path(self, path):
last_slash_index = path.rfind('/')
if last_slash_index == 0:
parent_directory_path = '/'
else:
parent_directory_path = path[:last_slash_index]
return parent_directory_path
def get_node(self, path):
if path not in self.__nodes:
raise NodeDoesNotExistError
return self.__nodes[path]
# Не очакваме случая: directory=True и len(content) > 0
def create(self, path, directory=False, content=''):
parent_directory_path = self._get_parent_directory_path(path)
if parent_directory_path not in self.__nodes or \
not self.__nodes.get(parent_directory_path).is_directory:
raise DestinationNodeDoesNotExistError
node_size = len(content) + 1
if node_size > self.available_size:
raise NotEnoughSpaceError
if path in self.__nodes:
raise DestinationNodeExistError
if directory:
n = Directory(path)
else:
n = File(content, path)
self.__nodes[path] = n
self.__nodes[parent_directory_path].add_node(n)
self.available_size -= node_size
def remove(self, path, directory=False, force=True):
if path not in self.__nodes:
raise NodeDoesNotExistError
current_node = self.__nodes[path]
if current_node.is_directory:
if directory is False:
raise NonExplicitDirectoryDeletionError
if len(current_node.nodes) > 0 and force is False:
raise NonEmptyDirectoryDeletionError
parent_directory_path = self._get_parent_directory_path(path)
parent_directory = self.get_node(parent_directory_path)
parent_directory.remove_node(current_node)
del self.__nodes[path]
for k in list(self.__nodes.keys()):
if k.startswith(path + '/'):
del self.__nodes[k]
def move(self, source, destination):
if source not in self.__nodes:
raise SourceNodeDoesNotExistError
if destination not in self.__nodes:
raise DestinationNodeDoesNotExistError
if not self.get_node(destination).is_directory:
raise DestinationNotADirectoryError
to_move = self.get_node(source)
if destination != '/':
destination += '/'
to_move_path = destination + str(to_move.get_name())
self.__nodes[to_move_path] = to_move
if to_move.is_directory:
for k in list(self.__nodes.keys()):
if k.startswith(source + '/'):
n = self.get_node(k)
n_path = to_move_path + k[len(source):]
self.__nodes[n_path] = n
del self.__nodes[k]
self.remove(source, directory=self.get_node(source).is_directory)

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

..EEEEE.E.E.EE.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_move_overwrite (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_overwrite (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 22.163s

FAILED (errors=11)

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

Красимир обнови решението на 30.04.2015 12:41 (преди почти 9 години)

+class FileSystemError(Exception):
+ pass
+
+
+class NotEnoughSpaceError(FileSystemError):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+ pass
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNodeExistError(FileSystemError):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ pass
+
+
+class File:
+ def __init__(self, content, path):
+ self.is_directory = False
+ self.content = content
+ self.size = len(self.content) + 1
+ self.path = path
+
+ def append(self, text):
+ self.content += text
+ self.size = len(self.content) + 1
+
+ def truncate(self, text):
+ self.content = text
+ self.size = len(self.content) + 1
+
+ def get_name(self):
+ if self.path == '/':
+ return ''
+ return self.path[self.path.rfind('/') + 1:]
+
+
+class Directory:
+ def __init__(self, path):
+ self.is_directory = True
+ self.directories = []
+ self.files = []
+ self.nodes = []
+ self.path = path
+
+ def add_node(self, node):
+ if node.is_directory:
+ self.directories.append(node)
+ else:
+ self.files.append(node)
+
+ self.nodes.append(node)
+
+ def remove_node(self, node):
+ if node.is_directory:
+ self.directories.remove(node)
+ else:
+ self.files.remove(node)
+
+ self.nodes.remove(node)
+
+ def get_name(self):
+ if self.path == '/':
+ return ''
+ return self.path[self.path.rfind('/') + 1:]
+
+
+class FileSystem:
+ def __init__(self, size):
+ self.size = size
+ self.available_size = size - 1
+
+ self.__nodes = {'/': Directory('/')}
+
+ def __str__(self):
+ s = ''
+ for k in self.__nodes.keys():
+ s += '{0}: {1}\n'.format(k, self.__nodes[k])
+ return s
+
+ def _get_parent_directory_path(self, path):
+ last_slash_index = path.rfind('/')
+ if last_slash_index == 0:
+ parent_directory_path = '/'
+ else:
+ parent_directory_path = path[:last_slash_index]
+
+ return parent_directory_path
+
+ def get_node(self, path):
+ if path not in self.__nodes:
+ raise NodeDoesNotExistError
+
+ return self.__nodes[path]
+
+ # Не очакваме случая: directory=True и len(content) > 0
+ def create(self, path, directory=False, content=''):
+ parent_directory_path = self._get_parent_directory_path(path)
+
+ if parent_directory_path not in self.__nodes or \
+ not self.__nodes.get(parent_directory_path).is_directory:
+ raise DestinationNodeDoesNotExistError
+
+ node_size = len(content) + 1
+
+ if node_size > self.available_size:
+ raise NotEnoughSpaceError
+ if path in self.__nodes:
+ raise DestinationNodeExistError
+
+ if directory:
+ n = Directory(path)
+ else:
+ n = File(content, path)
+
+ self.__nodes[path] = n
+ self.__nodes[parent_directory_path].add_node(n)
+ self.available_size -= node_size
+
+ def remove(self, path, directory=False, force=True):
+ if path not in self.__nodes:
+ raise NodeDoesNotExistError
+
+ current_node = self.__nodes[path]
+
+ if current_node.is_directory:
+ if directory is False:
+ raise NonExplicitDirectoryDeletionError
+ if len(current_node.nodes) > 0 and force is False:
+ raise NonEmptyDirectoryDeletionError
+
+ parent_directory_path = self._get_parent_directory_path(path)
+ parent_directory = self.get_node(parent_directory_path)
+ parent_directory.remove_node(current_node)
+ del self.__nodes[path]
+
+ for k in list(self.__nodes.keys()):
+ if k.startswith(path + '/'):
+ del self.__nodes[k]
+
+ def move(self, source, destination):
+ if source not in self.__nodes:
+ raise SourceNodeDoesNotExistError
+ if destination not in self.__nodes:
+ raise DestinationNodeDoesNotExistError
+ if not self.get_node(destination).is_directory:
+ raise DestinationNotADirectoryError
+
+ to_move = self.get_node(source)
+
+ if destination != '/':
+ destination += '/'
+ to_move_path = destination + str(to_move.get_name())
+
+ self.__nodes[to_move_path] = to_move
+
+ if to_move.is_directory:
+ for k in list(self.__nodes.keys()):
+ if k.startswith(source + '/'):
+ n = self.get_node(k)
+ n_path = to_move_path + k[len(source):]
+ self.__nodes[n_path] = n
+ del self.__nodes[k]
+ self.remove(source, directory=self.get_node(source).is_directory)