Решение на In-memory файлова система от Валентина Жекова

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

Към профила на Валентина Жекова

Резултати

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

Код

class FileSystem:
def __init__(self, size_in_bytes):
self.root = FSDirectory('/')
if size_in_bytes > 0:
self.size = size_in_bytes
else:
raise NotEnoughSpaceError
self.available_size = self.size - 1
def get_node(self, path):
if path[0] is "/":
current = self.root
path_nodes = self.__get_path_names(path)
if path_nodes:
path_directories = path_nodes[:-1]
path_node = path_nodes[-1]
for name in path_directories:
sub_dirs = self.__get_nodes_names(current.directories)
if name in sub_dirs:
current = current.directories[sub_dirs.index(name)]
else:
raise NodeDoesNotExistError
nodes = self.__get_nodes_names(current.nodes)
if path_node in nodes:
result = current.nodes[nodes.index(path_node)]
if result in current.directories:
result.is_directory = True
else:
result.is_directory = False
else:
raise NodeDoesNotExistError
else:
result = self.root
result.is_directory = True
return result
else:
raise NodeDoesNotExistError
def create(self, path, directory=False, content=''):
try:
parent = self.__get_parent_node(path)
new_node_name = self.__get_path_names(path)[-1]
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError
if new_node_name not in self.__get_nodes_names(parent.nodes):
if directory:
if self.available_size >= 1:
self.available_size -= 1
new_node = FSDirectory(new_node_name)
parent.directories.append(new_node)
else:
raise NotEnoughSpaceError
else:
if self.available_size >= len(content) + 1:
self.available_size -= (len(content) + 1)
new_node = FSFile(new_node_name)
new_node.append(content)
parent.files.append(new_node)
else:
raise NotEnoughSpaceError
parent.nodes.append(new_node)
else:
raise DestinationNodeExistsError
def remove(self, path, directory=False, force=True):
target = self.get_node(path)
parent = self.__get_parent_node(path)
if not target.is_directory:
self.available_size += target.size
del parent.files[parent.files.index(target)]
del parent.nodes[parent.nodes.index(target)]
else:
if not directory:
raise NonExplicitDirectoryDeletionError
else:
if not target.nodes:
self.available_size += 1
del parent.directories[parent.directories.index(target)]
del parent.nodes[parent.nodes.index(target)]
elif not force:
raise NonEmptyDirectoryDeletionError
else:
for child in self.__get_children_paths(path):
self.remove(child, directory=True)
def move(self, source, destination):
try:
destination_node = self.get_node(destination)
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError
if not destination_node.is_directory:
raise DestinationNotADirectoryError
moved_name = self.__get_path_names[-1]
if moved_name in self.__get_nodes_names(destination_node.nodes):
raise DestinationNodeExistsError
source_node = self.get_node(source)
parent = self.__get_parent_node(source)
if not source_node.is_directory:
destination_node.files.append(source_node)
del parent.files[parent.files.index(source_node)]
else:
destination_node.directories.append(source_node)
del parent.directories[parent.directories.index(source_node)]
destination_node.nodes.append(source_node)
del parent.nodes[parent.nodes.index(source_node)]
def link(self, source, destination, symbolic=True):
try:
src = self.get_node(source)
if src.is_directory and not symbolic:
raise DirectoryHardLinkError
if symbolic: # LinkPathError to do yet
symbolic_link = self.create(destination)
symbolic_link.link_path = src
else:
if not src.is_directory:
hard_link = self.create(destination)
hard_link.content = src.content
hard_link.size += src.size
src.size = hard_link.size
except NodeDoesNotExistError:
if symbolic:
raise NodeDoesNotExistError
else:
raise SourceNodeDoesNotExistError
def mount(self, file_system, path):
try:
mount_point = self.get_node(path)
if mount_point.is_directory and mount_point.nodes:
raise MountPointNotEmptyError
if not mount_point.is_directory:
raise MountPointDoesNotExistError # or file error?
except NodeDoesNotExistError:
raise MountPointDoesNotExistError
mount_point.is_mount_point = True
mount_point_name = mount_point.name
mount_point = file_system.root
mount_point.name = mount_point_name
# not quite true fix it if there is enough time
# what about file_system.get_node('/')?
# also not working way:
# mount_point.directories.extend(file_system.root.directories)
# mount_point.files.extend(file_system.root.files)
# mount_point.nodes.extend(file_system.root.nodes)
def unmount(self, path):
try:
unmount_point = self.get_node(path)
if not unmount_point.is_mount_point:
raise NotAMountpointError
self.remove(path)
self.create(path)
except NodeDoesNotExistError:
raise NodeDoesNotExistError
def __get_path_names(self, path):
return [node for node in path.split('/') if node is not '']
def __get_nodes_names(self, nodes):
return [node.name for node in nodes]
def __get_parent_node(self, path):
split_index = path[::-1].index('/')
return self.get_node(path[:-split_index])
def __get_children_paths(self, path):
current = self.get_node(path)
return [path + '/' + child.name for child in current.nodes]
class FSDirectory:
def __init__(self, name):
self.name = name
self.directories = []
self.files = []
self.nodes = []
class FSFile:
def __init__(self, name):
self.name = name
self.content = ""
self.size = 1
def append(self, text):
self.content += text
self.size += len(text)
def truncate(self, text):
self.content = text
self.size = len(text) + 1
class FileSystemError(Exception):
def __init__(self):
self.message = "There is some file system error: "
class NodeDoesNotExistError(FileSystemError):
def __init__(self):
super().__init__()
self.message += "Node doesn't exist"
class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
def __init__(self):
super().__init__()
self.message += "at this destination"
class SourceNodeDoesNotExistError(NodeDoesNotExistError):
def __init__(self):
super().__init__()
self.message += "at this source"
class FileSystemMountError(FileSystemError):
def __init__(self):
super().__init__()
self.message += "Problem while mounting."
class MountPointNotEmptyError(FileSystemMountError):
def __init__(self):
super().__init__()
self.message += "Mount point should be empty."
class MountPointDoesNotExistError(FileSystemMountError):
def __init__(self):
super().__init__()
self.message += "Mount point should be created first."
class NotAMountpointError(FileSystemMountError):
def __init__(self):
super().__init__()
self.message = "Can't unmount. The directory isn't a mount point"
class LinkPathError(FileSystemError):
def __init__(self):
super().__init__()
self.message += "Source node doesn't exist"
class NotEnoughSpaceError(FileSystemError):
def __init__(self):
super().__init__()
self.message += "Not enough space to do the operation"
class DestinationNodeExistsError(FileSystemError):
def __init__(self):
super().__init__()
self.message += "There is already a node with that name"
class NonExplicitDirectoryDeletionError(FileSystemError):
def __init__(self):
super().__init__()
self.message += "Attempt to delete a directory; Assure directory=True"
class NonEmptyDirectoryDeletionError(FileSystemError):
def __init__(self):
super().__init__()
self.message += "Non empty directory to be deleted; Assure force=True"
class DestinationNotADirectoryError(FileSystemError):
def __init__(self):
super().__init__()
self.message += "Attempt to move; Destination isn't a directory"
class DirectoryHardLinkError(FileSystemError):
def __init__(self):
super().__init__()
self.message += "Can't make hard link to directory"

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

..EE..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_space_consumption (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_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 18.161s

FAILED (errors=9)

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

Валентина обнови решението на 30.04.2015 16:32 (преди над 9 години)

+class FileSystem:
+
+ def __init__(self, size_in_bytes):
+ self.root = FSDirectory('/')
+ if size_in_bytes > 0:
+ self.size = size_in_bytes
+ else:
+ raise NotEnoughSpaceError
+ self.available_size = self.size - 1
+
+ def get_node(self, path):
+ if path[0] is "/":
+ current = self.root
+ path_nodes = self.__get_path_names(path)
+ if path_nodes:
+ path_directories = path_nodes[:-1]
+ path_node = path_nodes[-1]
+ for name in path_directories:
+ sub_dirs = self.__get_nodes_names(current.directories)
+ if name in sub_dirs:
+ current = current.directories[sub_dirs.index(name)]
+ else:
+ raise NodeDoesNotExistError
+ nodes = self.__get_nodes_names(current.nodes)
+ if path_node in nodes:
+ result = current.nodes[nodes.index(path_node)]
+ if result in current.directories:
+ result.is_directory = True
+ else:
+ result.is_directory = False
+ else:
+ raise NodeDoesNotExistError
+ else:
+ result = self.root
+ result.is_directory = True
+ return result
+ else:
+ raise NodeDoesNotExistError
+
+ def create(self, path, directory=False, content=''):
+ try:
+ parent = self.__get_parent_node(path)
+ new_node_name = self.__get_path_names(path)[-1]
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+ if new_node_name not in self.__get_nodes_names(parent.nodes):
+ if directory:
+ if self.available_size >= 1:
+ self.available_size -= 1
+ new_node = FSDirectory(new_node_name)
+ parent.directories.append(new_node)
+ else:
+ raise NotEnoughSpaceError
+ else:
+ if self.available_size >= len(content) + 1:
+ self.available_size -= (len(content) + 1)
+ new_node = FSFile(new_node_name)
+ new_node.append(content)
+ parent.files.append(new_node)
+ else:
+ raise NotEnoughSpaceError
+ parent.nodes.append(new_node)
+ else:
+ raise DestinationNodeExistsError
+
+ def remove(self, path, directory=False, force=True):
+ target = self.get_node(path)
+ parent = self.__get_parent_node(path)
+ if not target.is_directory:
+ self.available_size += target.size
+ del parent.files[parent.files.index(target)]
+ del parent.nodes[parent.nodes.index(target)]
+ else:
+ if not directory:
+ raise NonExplicitDirectoryDeletionError
+ else:
+ if not target.nodes:
+ self.available_size += 1
+ del parent.directories[parent.directories.index(target)]
+ del parent.nodes[parent.nodes.index(target)]
+ elif not force:
+ raise NonEmptyDirectoryDeletionError
+ else:
+ for child in self.__get_children_paths(path):
+ self.remove(child, directory=True)
+
+ def move(self, source, destination):
+ try:
+ destination_node = self.get_node(destination)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+ if not destination_node.is_directory:
+ raise DestinationNotADirectoryError
+ moved_name = self.__get_path_names[-1]
+ if moved_name in self.__get_nodes_names(destination_node.nodes):
+ raise DestinationNodeExistsError
+ source_node = self.get_node(source)
+ parent = self.__get_parent_node(source)
+ if not source_node.is_directory:
+ destination_node.files.append(source_node)
+ del parent.files[parent.files.index(source_node)]
+ else:
+ destination_node.directories.append(source_node)
+ del parent.directories[parent.directories.index(source_node)]
+ destination_node.nodes.append(source_node)
+ del parent.nodes[parent.nodes.index(source_node)]
+
+ def link(self, source, destination, symbolic=True):
+ try:
+ src = self.get_node(source)
+ if src.is_directory and not symbolic:
+ raise DirectoryHardLinkError
+ if symbolic: # LinkPathError to do yet
+ symbolic_link = self.create(destination)
+ symbolic_link.link_path = src
+ else:
+ if not src.is_directory:
+ hard_link = self.create(destination)
+ hard_link.content = src.content
+ hard_link.size += src.size
+ src.size = hard_link.size
+ except NodeDoesNotExistError:
+ if symbolic:
+ raise NodeDoesNotExistError
+ else:
+ raise SourceNodeDoesNotExistError
+
+ def mount(self, file_system, path):
+ try:
+ mount_point = self.get_node(path)
+ if mount_point.is_directory and mount_point.nodes:
+ raise MountPointNotEmptyError
+ if not mount_point.is_directory:
+ raise MountPointDoesNotExistError # or file error?
+ except NodeDoesNotExistError:
+ raise MountPointDoesNotExistError
+
+ mount_point.is_mount_point = True
+ mount_point_name = mount_point.name
+ mount_point = file_system.root
+ mount_point.name = mount_point_name
+ # not quite true fix it if there is enough time
+ # what about file_system.get_node('/')?
+ # also not working way:
+ # mount_point.directories.extend(file_system.root.directories)
+ # mount_point.files.extend(file_system.root.files)
+ # mount_point.nodes.extend(file_system.root.nodes)
+
+ def unmount(self, path):
+ try:
+ unmount_point = self.get_node(path)
+ if not unmount_point.is_mount_point:
+ raise NotAMountpointError
+ self.remove(path)
+ self.create(path)
+ except NodeDoesNotExistError:
+ raise NodeDoesNotExistError
+
+ def __get_path_names(self, path):
+ return [node for node in path.split('/') if node is not '']
+
+ def __get_nodes_names(self, nodes):
+ return [node.name for node in nodes]
+
+ def __get_parent_node(self, path):
+ split_index = path[::-1].index('/')
+ return self.get_node(path[:-split_index])
+
+ def __get_children_paths(self, path):
+ current = self.get_node(path)
+ return [path + '/' + child.name for child in current.nodes]
+
+
+class FSDirectory:
+
+ def __init__(self, name):
+ self.name = name
+ self.directories = []
+ self.files = []
+ self.nodes = []
+
+
+class FSFile:
+
+ def __init__(self, name):
+ self.name = name
+ self.content = ""
+ self.size = 1
+
+ def append(self, text):
+ self.content += text
+ self.size += len(text)
+
+ def truncate(self, text):
+ self.content = text
+ self.size = len(text) + 1
+
+
+class FileSystemError(Exception):
+ def __init__(self):
+ self.message = "There is some file system error: "
+
+
+class NodeDoesNotExistError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Node doesn't exist"
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ def __init__(self):
+ super().__init__()
+ self.message += "at this destination"
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ def __init__(self):
+ super().__init__()
+ self.message += "at this source"
+
+
+class FileSystemMountError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Problem while mounting."
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Mount point should be empty."
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Mount point should be created first."
+
+
+class NotAMountpointError(FileSystemMountError):
+ def __init__(self):
+ super().__init__()
+ self.message = "Can't unmount. The directory isn't a mount point"
+
+
+class LinkPathError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Source node doesn't exist"
+
+
+class NotEnoughSpaceError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Not enough space to do the operation"
+
+
+class DestinationNodeExistsError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "There is already a node with that name"
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Attempt to delete a directory; Assure directory=True"
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Non empty directory to be deleted; Assure force=True"
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Attempt to move; Destination isn't a directory"
+
+
+class DirectoryHardLinkError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message += "Can't make hard link to directory"