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

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

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

Резултати

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

Код

class FileSystemError(Exception):
pass
class FileSystemMountError(FileSystemError):
pass
class NodeDoesNotExistError(FileSystemError):
pass
class SourceNodeDoesNotExistError(NodeDoesNotExistError):
pass
class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
pass
class MountPointDoesNotExistError(FileSystemMountError):
pass
class MountPointNotADirectoryError(FileSystemMountError):
pass
class MountPointNotEmptyError(FileSystemMountError):
pass
class NotAMountpointError(FileSystemMountError):
pass
class NotEnoughSpaceError(FileSystemError):
pass
class DestinationNodeExistsError(FileSystemError):
pass
# remove
class NonEmptyDirectoryDeletionError(FileSystemError):
pass
class NonExplicitDirectoryDeletionError(FileSystemError):
pass
# move
# pogore
class DestinationNotADirectoryError(FileSystemError):
pass
# za vrski
class LinkPathError(FileSystemError):
pass
class DirectoryHardLinkError(FileSystemError):
pass
class Content:
def __init__(self, content=''):
self.__content = content
@property
def content(self):
return self.__content
@content.setter
def content(self):
return self.__content
class File:
def __init__(self, name='', content=Content()):
self._content = content
self.name = name
def append(self, text):
self._content.content = self._content.content + text
def truncate(self, text):
self._content.content = text
def size(self):
return len(self._content.content) + 1
@property
def content(self):
return self._content.content
@property
def is_directory(self):
return False
class Linker:
def __init__(self, name='', link_path=None):
self.link_path = link_path
self.name = name
@property
def is_directory(self):
return False
@property
def content(self):
if not isinstance(self.link_path, File):
raise LinkPathError
return self.link_path.content
def append(self, text):
if not isinstance(self.link_path, File):
raise LinkPathError
self.link_path.append
def truncate(self, text):
if not isinstance(self.link_path, File):
raise LinkPathError
self.link_path.truncate(text)
def size(self):
if not isinstance(self.link_path, File):
raise LinkPathError
return self.link_path.size()
@property
def directories(self):
if not isinstance(self.link_path, Directory):
raise LinkPathError
return self.link_path.directories
@property
def files(self):
if not isinstance(self.link_path, Directory):
raise LinkPathError
return self.link_path.files
@property
def node(self):
if not isinstance(self.link_path, Directory):
raise LinkPathError
return self.link_path.node
class Directory:
def __init__(self, name='', path='/'):
self.name = name
self.path = path
self.directories = []
self.files = []
@property
def node(self):
return self.directories + self.files
@property
def is_directory(self):
return True
# /
# /root
# /root/home
# /root/home/spells
# /root/home/spells/mage.txt
# /root/home/spells/asshole.txt
# /root/shit
class FileSystem:
def __init__(self, size):
self.__system_size = size
self.__available_size = size - 1
self.__root = Directory()
@property
def root(self):
return self.__root
@property
def available_size(self):
return self.__available_size
@available_size.setter
def available_size(self, value):
self.__available_size = value
def set_ava(self, value):
self.__available_size = value
@property
def size(self):
return self.__system_size
def print_it(self, dir, path=''):
for element in dir.node:
if element.is_directory:
new_path = path + '/' + element.name
self.print_it(element, path=new_path)
else:
print(path + '/' + element.name)
if len(dir.node) == 0:
print(path)
def print_paths(self):
self.print_it(self.__root)
print('')
def get_node(self, path):
split_path = path.split('/')
if split_path[0] == split_path[1]:
return self.__root
current_directory = self.__root
for element in split_path[1:-1:1]:
next_directory = [directory
for directory
in current_directory.directories
if directory.name == element]
if len(next_directory) == 1:
current_directory = next_directory[0]
else:
raise NodeDoesNotExistError
result = [last_node
for last_node
in current_directory.node
if last_node.name == split_path[-1]]
if len(result) == 1:
return result[0]
else:
raise NodeDoesNotExistError
raise NodeDoesNotExistError
def __enough_space(self, directory=False, content=''):
directory_space = directory and self.available_size == 0
enough_size = self.available_size < len(content)+1
file_space = not directory and enough_size
if directory_space or file_space:
raise NotEnoughSpaceError
def __get_path(self, path):
if len(path.split('/')) <= 2:
return '/'
the_path = ''
for element in path.split('/')[1:-1:1]:
the_path = the_path + '/' + element
return the_path
def __get_name(self, path):
return path.split('/')[-1]
def create(self, path, directory=False, content=''):
self.__enough_space(directory, content)
if len(path.split('/')) > 2:
try:
location = self.get_node(self.__get_path(path))
except:
raise DestinationNodeDoesNotExistError
else:
location = self.__root
if not location.is_directory:
raise DestinationNodeDoesNotExistError
if directory:
name = self.__get_name(path)
item = Directory(name=name, path=path)
directories = list(filter(lambda x: x.name == name,
location.directories))
if len(directories) > 0:
raise DestinationNodeExistsError
else:
location.directories.append(item)
self.available_size -= 1
else:
file_content = Content(content)
file_name = self.__get_name(path)
item = File(name=file_name, content=file_content)
files = list(filter(lambda x: x.name == file_name,
location.files))
if len(files) > 0:
raise DestinationNodeExistsError
location.files.append(item)
self.available_size -= item.size()
def __calculate_size(self, directory):
return 1
def remove(self, path, directory=False, force=True):
location = self.get_node(self.__get_path(path))
name = self.__get_name(path)
item = [x for x in location.node if x.name == name][0]
if item.is_directory:
if len(item.node) > 0:
if not force:
raise NonEmptyDirectoryDeletionError
else:
if not directory:
raise NonExplicitDirectoryDeletionError
self.available_size += self.__calculate_size(item)
location.directories.remove(item)
# NOT NOT
else:
self.available_size -= item.size()
location.files.remove(item)
def move(self, source, destination):
try:
source_location = self.get_node(self.__get_path(source))
source_item = self.get_node(source)
except:
raise SourceNodeDoesNotExistError
try:
destination_item = self.get_node(destination)
except:
raise DestinationNodeDoesNotExistError
source_name = self.__get_name(source)
if not destination_item.is_directory:
raise DestinationNotADirectoryError
directories = map(lambda item: item.name, destination_item.node)
if source_name in list(directories):
raise DestinationNodeExistsError
if source_item.is_directory:
destination_item.directories.append(source_item)
source_location.directories.remove(source_item)
else:
destination_item.files.append(source_item)
source_location.files.remove(source_item)
def link(self, source, destination, symbolic=True):
try:
source_item = self.get_node(source)
except:
if symbolic:
raise NodeDoesNotExistError
else:
raise SourceNodeDoesNotExistError
try:
path = self.__get_path(destination)
destination_location = self.get_node(path)
destination_name = self.__get_name(destination)
except:
raise DestinationNodeDoesNotExistError
if source_item.is_directory and not symbolic:
raise DirectoryHardLinkError
if symbolic:
temp = Linker(name=destination_name, link_path=source_item)
if source_item.is_directory:
destination_location.directories.append(temp)
else:
destination_location.files.append(temp)
else:
content = source_item._content
temp = File(name=destination_name, content=content)
destination_location.files.append(temp)
self.available_size -= 1
def mount(self, file_system, path):
try:
destination = self.get_node(path)
except:
raise MountPointDoesNotExistError
if not destination.is_directory:
raise MountPointNotADirectoryError
if len(destination.node) > 0:
raise MountPointNotEmptyError
destination.directories = file_system.root.directories
destination.files = file_system.root.files
def unmount(self, path):
source = self.get_node(path)
source.directories = []
source.files = []

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

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

======================================================================
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_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 12.175s

FAILED (errors=6)

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

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

+class FileSystemError(Exception):
+ pass
+
+
+class FileSystemMountError(FileSystemError):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+ pass
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ pass
+
+
+class NotAMountpointError(FileSystemMountError):
+ pass
+
+
+class NotEnoughSpaceError(FileSystemError):
+ pass
+
+
+class DestinationNodeExistsError(FileSystemError):
+ pass
+
+
+# remove
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ pass
+
+
+# move
+# pogore
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ pass
+
+
+# za vrski
+
+
+class LinkPathError(FileSystemError):
+ pass
+
+
+class DirectoryHardLinkError(FileSystemError):
+ pass
+
+
+class Content:
+ def __init__(self, content=''):
+ self.__content = content
+
+ @property
+ def content(self):
+ return self.__content
+
+ @content.setter
+ def content(self):
+ return self.__content
+
+
+class File:
+ def __init__(self, name='', content=Content()):
+ self._content = content
+ self.name = name
+
+ def append(self, text):
+ self._content.content = self._content.content + text
+
+ def truncate(self, text):
+ self._content.content = text
+
+ def size(self):
+ return len(self._content.content) + 1
+
+ @property
+ def content(self):
+ return self._content.content
+
+ @property
+ def is_directory(self):
+ return False
+
+
+class Linker:
+ def __init__(self, name='', link_path=None):
+ self.link_path = link_path
+ self.name = name
+
+ @property
+ def is_directory(self):
+ return False
+
+ @property
+ def content(self):
+ if not isinstance(self.link_path, File):
+ raise LinkPathError
+ return self.link_path.content
+
+ def append(self, text):
+ if not isinstance(self.link_path, File):
+ raise LinkPathError
+ self.link_path.append
+
+ def truncate(self, text):
+ if not isinstance(self.link_path, File):
+ raise LinkPathError
+ self.link_path.truncate(text)
+
+ def size(self):
+ if not isinstance(self.link_path, File):
+ raise LinkPathError
+ return self.link_path.size()
+
+ @property
+ def directories(self):
+ if not isinstance(self.link_path, Directory):
+ raise LinkPathError
+ return self.link_path.directories
+
+ @property
+ def files(self):
+ if not isinstance(self.link_path, Directory):
+ raise LinkPathError
+ return self.link_path.files
+
+ @property
+ def node(self):
+ if not isinstance(self.link_path, Directory):
+ raise LinkPathError
+ return self.link_path.node
+
+
+class Directory:
+ def __init__(self, name='', path='/'):
+ self.name = name
+ self.path = path
+ self.directories = []
+ self.files = []
+
+ @property
+ def node(self):
+ return self.directories + self.files
+
+ @property
+ def is_directory(self):
+ return True
+
+# /
+# /root
+# /root/home
+# /root/home/spells
+# /root/home/spells/mage.txt
+# /root/home/spells/asshole.txt
+# /root/shit
+
+
+class FileSystem:
+ def __init__(self, size):
+ self.__system_size = size
+ self.__available_size = size - 1
+ self.__root = Directory()
+
+ @property
+ def root(self):
+ return self.__root
+
+ @property
+ def available_size(self):
+ return self.__available_size
+
+ @available_size.setter
+ def available_size(self, value):
+ self.__available_size = value
+
+ def set_ava(self, value):
+ self.__available_size = value
+
+ @property
+ def size(self):
+ return self.__system_size
+
+ def print_it(self, dir, path=''):
+ for element in dir.node:
+ if element.is_directory:
+ new_path = path + '/' + element.name
+ self.print_it(element, path=new_path)
+ else:
+ print(path + '/' + element.name)
+
+ if len(dir.node) == 0:
+ print(path)
+
+ def print_paths(self):
+ self.print_it(self.__root)
+ print('')
+
+ def get_node(self, path):
+ split_path = path.split('/')
+
+ if split_path[0] == split_path[1]:
+ return self.__root
+
+ current_directory = self.__root
+ for element in split_path[1:-1:1]:
+ next_directory = [directory
+ for directory
+ in current_directory.directories
+ if directory.name == element]
+
+ if len(next_directory) == 1:
+ current_directory = next_directory[0]
+ else:
+ raise NodeDoesNotExistError
+
+ result = [last_node
+ for last_node
+ in current_directory.node
+ if last_node.name == split_path[-1]]
+
+ if len(result) == 1:
+ return result[0]
+ else:
+ raise NodeDoesNotExistError
+
+ raise NodeDoesNotExistError
+
+ def __enough_space(self, directory=False, content=''):
+ directory_space = directory and self.available_size == 0
+ enough_size = self.available_size < len(content)+1
+ file_space = not directory and enough_size
+ if directory_space or file_space:
+ raise NotEnoughSpaceError
+
+ def __get_path(self, path):
+ if len(path.split('/')) <= 2:
+ return '/'
+ the_path = ''
+ for element in path.split('/')[1:-1:1]:
+ the_path = the_path + '/' + element
+ return the_path
+
+ def __get_name(self, path):
+ return path.split('/')[-1]
+
+ def create(self, path, directory=False, content=''):
+ self.__enough_space(directory, content)
+ if len(path.split('/')) > 2:
+ try:
+ location = self.get_node(self.__get_path(path))
+ except:
+ raise DestinationNodeDoesNotExistError
+ else:
+ location = self.__root
+
+ if not location.is_directory:
+ raise DestinationNodeDoesNotExistError
+
+ if directory:
+ name = self.__get_name(path)
+ item = Directory(name=name, path=path)
+ directories = list(filter(lambda x: x.name == name,
+ location.directories))
+ if len(directories) > 0:
+ raise DestinationNodeExistsError
+ else:
+ location.directories.append(item)
+ self.available_size -= 1
+ else:
+ file_content = Content(content)
+ file_name = self.__get_name(path)
+ item = File(name=file_name, content=file_content)
+ files = list(filter(lambda x: x.name == file_name,
+ location.files))
+ if len(files) > 0:
+ raise DestinationNodeExistsError
+
+ location.files.append(item)
+ self.available_size -= item.size()
+
+ def __calculate_size(self, directory):
+ return 1
+
+ def remove(self, path, directory=False, force=True):
+ location = self.get_node(self.__get_path(path))
+ name = self.__get_name(path)
+ item = [x for x in location.node if x.name == name][0]
+
+ if item.is_directory:
+ if len(item.node) > 0:
+ if not force:
+ raise NonEmptyDirectoryDeletionError
+ else:
+ if not directory:
+ raise NonExplicitDirectoryDeletionError
+ self.available_size += self.__calculate_size(item)
+ location.directories.remove(item)
+ # NOT NOT
+ else:
+ self.available_size -= item.size()
+ location.files.remove(item)
+
+ def move(self, source, destination):
+ try:
+ source_location = self.get_node(self.__get_path(source))
+ source_item = self.get_node(source)
+ except:
+ raise SourceNodeDoesNotExistError
+
+ try:
+ destination_item = self.get_node(destination)
+ except:
+ raise DestinationNodeDoesNotExistError
+
+ source_name = self.__get_name(source)
+
+ if not destination_item.is_directory:
+ raise DestinationNotADirectoryError
+ directories = map(lambda item: item.name, destination_item.node)
+ if source_name in list(directories):
+ raise DestinationNodeExistsError
+
+ if source_item.is_directory:
+ destination_item.directories.append(source_item)
+ source_location.directories.remove(source_item)
+ else:
+ destination_item.files.append(source_item)
+ source_location.files.remove(source_item)
+
+ def link(self, source, destination, symbolic=True):
+ try:
+ source_item = self.get_node(source)
+ except:
+ if symbolic:
+ raise NodeDoesNotExistError
+ else:
+ raise SourceNodeDoesNotExistError
+
+ try:
+ path = self.__get_path(destination)
+ destination_location = self.get_node(path)
+ destination_name = self.__get_name(destination)
+ except:
+ raise DestinationNodeDoesNotExistError
+
+ if source_item.is_directory and not symbolic:
+ raise DirectoryHardLinkError
+
+ if symbolic:
+ temp = Linker(name=destination_name, link_path=source_item)
+ if source_item.is_directory:
+ destination_location.directories.append(temp)
+ else:
+ destination_location.files.append(temp)
+ else:
+ content = source_item._content
+ temp = File(name=destination_name, content=content)
+ destination_location.files.append(temp)
+ self.available_size -= 1
+
+ def mount(self, file_system, path):
+ try:
+ destination = self.get_node(path)
+ except:
+ raise MountPointDoesNotExistError
+
+ if not destination.is_directory:
+ raise MountPointNotADirectoryError
+
+ if len(destination.node) > 0:
+ raise MountPointNotEmptyError
+
+ destination.directories = file_system.root.directories
+ destination.files = file_system.root.files
+
+ def unmount(self, path):
+ source = self.get_node(path)
+
+ source.directories = []
+ source.files = []