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

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

Към профила на Мартина Тонковска

Резултати

  • 3 точки от тестове
  • 0 бонус точки
  • 3 точки общо
  • 4 успешни тест(а)
  • 14 неуспешни тест(а)

Код

class File:
def __init__(self, name, content=''):
self.name = name
self.content = content
self.size = len(content) + 1
@property
def is_directory(self):
return False
def append(self, text):
self.content += text
def truncate(self, text):
self.content = ''
self.content = text
class Directory():
def __init__(self, name='/'):
self.name = name
self.directories = []
self.files = []
self.nodes = []
@property
def is_directory(self):
return True
@staticmethod
def __pr(d):
print("(Directory " + d.name + ": ")
print("Files: ", end="")
for f in d.files:
print(f.name, end=" ")
if len(d.directories) is 0:
print(")", end="")
else:
for sub in d.directories:
Directory.__pr(sub)
print(")", end="")
def get_contents(self):
for d in self.directories:
Directory.__pr(d)
class FileSystem(Directory):
def __init__(self, size):
super().__init__()
self.directories = [Directory('/')]
self.size = size
self.available_size = size - 1 # for the root dir
@staticmethod
def __get_n(dirs, path):
for d in dirs:
if path[0] == d.name and len(path) is not 1:
i = dirs.index(d)
return FileSystem.__get_n(dirs[i].directories, path[1:])
elif path[0] == d.name and len(path) is 1: # end of route reached, route is valid
return d
else:
raise NodeDoesNotExistError()
def get_node(self, path):
if path is '/':
return self.directories[0]
else:
p = path.split('/')
p[0] = '/'
prev_node = FileSystem.__get_n(self.directories, p[:-1]) # without the last dir or file
for n in prev_node.nodes:
if p[-1] == n.name:
return n
raise NodeDoesNotExistError()
def create(self, path, directory=False, content=''):
p = path.rsplit('/', 1) # split on first occurrence of '/' backwards
if p[0] is '':
node = self.directories[0]
else:
try:
node = self.get_node(p[0])
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError()
if directory is True:
if self.available_size is 1:
raise NotEnoughSpaceError()
else:
d = Directory(p[1])
if d in node.directories:
raise DestinationNodeExistsError()
else:
node.directories.append(d)
node.nodes.append(d)
self.available_size -= 1
else:
if self.available_size + 1 <= len(content):
raise NotEnoughSpaceError()
else:
f = File(p[1], content)
if f in node.files:
raise DestinationNodeExistsError()
else:
node.files.append(f)
node.nodes.append(f)
self.available_size -= len(content)
def remove(self, path, directory=False, force=True):
try:
node = self.get_node(path)
except DestinationNodeDoesNotExistError:
raise NodeDoesNotExistError()
if node.is_directory:
if directory is not True:
raise NonExplicitDirectoryDeletionError
else:
if directory is True:
if len(node.directories) > 0 and force is not True:
raise NonEmptyDirectoryDeletionError
else:
p = path.rsplit('/', 1)
parent_dir = self.get_node(p[0]) # path to file = p[0], filename = p[1]
dir_to_remove = self.get_node(path)
parent_dir.directories.remove(dir_to_remove)
parent_dir.nodes.remove(dir_to_remove)
self.available_size += 1
else: # not a directory, i.e. - file
p = path.rsplit('/')
if path.count('/') == 1: # i.e. - file is in the root directory
p[0] = '/'
parent_dir = self.get_node(p[0]) # path to file = p[0], filename = p[1]
file_to_remove = self.get_node(path)
parent_dir.files.remove(file_to_remove)
parent_dir.nodes.remove(file_to_remove)
self.available_size += file_to_remove.size
def move(self, source, destination):
try:
to_move = self.get_node(source)
except NodeDoesNotExistError:
raise SourceNodeDoesNotExistError()
try:
dest = self.get_node(destination)
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError()
except not dest.is_directory:
raise DestinationNotADirectoryError()
src = source.rsplit('/', 1)[1]
# check if node with the same name exists in directory
for node in dest.nodes:
if src == node.name:
raise DestinationNodeExistsError()
# delete node from source directory
if to_move.is_directory:
self.remove(source, True)
else:
self.remove(source)
if to_move.is_directory:
dest.directories.append(to_move)
dest.nodes.append(to_move)
else:
destination += '/' + src
self.create(destination, to_move.content)
def link(self, source, destination, symbolic=True):
pass
def mount(self, file_system, path):
pass
def unmount(self, path):
pass
class FileSystemError(Exception):
def __init__(self):
self.message = "Error"
def __str__(self):
return self.message
class NodeDoesNotExistError(FileSystemError):
def __init__(self):
super().__init__()
self.message = "{0} {1}".format("Node does not exist", self.message)
class SourceNodeDoesNotExistError(NodeDoesNotExistError, FileSystemError):
def __init__(self):
super().__init__()
self.message = "{0} {1}".format("Source", self.message)
class DestinationNodeDoesNotExistError(NodeDoesNotExistError, FileSystemError):
def __init__(self):
super().__init__()
self.message = "{0} {1}".format("Destination", self.message)
class NotEnoughSpaceError(FileSystemError):
def __init__(self):
super().__init__()
self.message = "Not Enough Space Error"
class DestinationNodeExistsError(FileSystemError):
def __init__(self):
super().__init__()
self.message = "Destination Node Exists Error"
class NonExplicitDirectoryDeletionError(FileSystemError):
def __init__(self):
super().__init__()
self.message = "Non Explicit Directory Deletion Error"
class NonEmptyDirectoryDeletionError(FileSystemError):
def __init__(self):
super().__init__()
self.message = "Non Empty Directory Deletion Error"
class DestinationNotADirectoryError(FileSystemError):
def __init__(self):
super().__init__()
self.message = "Destination Not A Directory Error"

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

..EEEEE.EEE.EEEEEE
======================================================================
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_not_to_a_directory (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_file (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 28.143s

FAILED (errors=14)

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

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

+class File:
+ def __init__(self, name, content=''):
+ self.name = name
+ self.content = content
+ self.size = len(content) + 1
+
+ @property
+ def is_directory(self):
+ return False
+
+ def append(self, text):
+ self.content += text
+
+ def truncate(self, text):
+ self.content = ''
+ self.content = text
+
+
+class Directory():
+ def __init__(self, name='/'):
+ self.name = name
+ self.directories = []
+ self.files = []
+ self.nodes = []
+
+ @property
+ def is_directory(self):
+ return True
+
+ @staticmethod
+ def __pr(d):
+ print("(Directory " + d.name + ": ")
+ print("Files: ", end="")
+ for f in d.files:
+ print(f.name, end=" ")
+ if len(d.directories) is 0:
+ print(")", end="")
+ else:
+ for sub in d.directories:
+ Directory.__pr(sub)
+ print(")", end="")
+
+ def get_contents(self):
+ for d in self.directories:
+ Directory.__pr(d)
+
+
+class FileSystem(Directory):
+ def __init__(self, size):
+ super().__init__()
+ self.directories = [Directory('/')]
+ self.size = size
+ self.available_size = size - 1 # for the root dir
+
+ @staticmethod
+ def __get_n(dirs, path):
+ for d in dirs:
+ if path[0] == d.name and len(path) is not 1:
+ i = dirs.index(d)
+ return FileSystem.__get_n(dirs[i].directories, path[1:])
+ elif path[0] == d.name and len(path) is 1: # end of route reached, route is valid
+ return d
+ else:
+ raise NodeDoesNotExistError()
+
+ def get_node(self, path):
+ if path is '/':
+ return self.directories[0]
+ else:
+ p = path.split('/')
+ p[0] = '/'
+ prev_node = FileSystem.__get_n(self.directories, p[:-1]) # without the last dir or file
+ for n in prev_node.nodes:
+ if p[-1] == n.name:
+ return n
+ raise NodeDoesNotExistError()
+
+ def create(self, path, directory=False, content=''):
+ p = path.rsplit('/', 1) # split on first occurrence of '/' backwards
+ if p[0] is '':
+ node = self.directories[0]
+ else:
+ try:
+ node = self.get_node(p[0])
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError()
+ if directory is True:
+ if self.available_size is 1:
+ raise NotEnoughSpaceError()
+ else:
+ d = Directory(p[1])
+ if d in node.directories:
+ raise DestinationNodeExistsError()
+ else:
+ node.directories.append(d)
+ node.nodes.append(d)
+ self.available_size -= 1
+ else:
+ if self.available_size + 1 <= len(content):
+ raise NotEnoughSpaceError()
+ else:
+ f = File(p[1], content)
+ if f in node.files:
+ raise DestinationNodeExistsError()
+ else:
+ node.files.append(f)
+ node.nodes.append(f)
+ self.available_size -= len(content)
+
+ def remove(self, path, directory=False, force=True):
+ try:
+ node = self.get_node(path)
+ except DestinationNodeDoesNotExistError:
+ raise NodeDoesNotExistError()
+ if node.is_directory:
+ if directory is not True:
+ raise NonExplicitDirectoryDeletionError
+ else:
+ if directory is True:
+ if len(node.directories) > 0 and force is not True:
+ raise NonEmptyDirectoryDeletionError
+ else:
+ p = path.rsplit('/', 1)
+ parent_dir = self.get_node(p[0]) # path to file = p[0], filename = p[1]
+ dir_to_remove = self.get_node(path)
+ parent_dir.directories.remove(dir_to_remove)
+ parent_dir.nodes.remove(dir_to_remove)
+ self.available_size += 1
+ else: # not a directory, i.e. - file
+ p = path.rsplit('/')
+ if path.count('/') == 1: # i.e. - file is in the root directory
+ p[0] = '/'
+ parent_dir = self.get_node(p[0]) # path to file = p[0], filename = p[1]
+ file_to_remove = self.get_node(path)
+ parent_dir.files.remove(file_to_remove)
+ parent_dir.nodes.remove(file_to_remove)
+ self.available_size += file_to_remove.size
+
+ def move(self, source, destination):
+ try:
+ to_move = self.get_node(source)
+ except NodeDoesNotExistError:
+ raise SourceNodeDoesNotExistError()
+ try:
+ dest = self.get_node(destination)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError()
+ except not dest.is_directory:
+ raise DestinationNotADirectoryError()
+ src = source.rsplit('/', 1)[1]
+ # check if node with the same name exists in directory
+ for node in dest.nodes:
+ if src == node.name:
+ raise DestinationNodeExistsError()
+ # delete node from source directory
+ if to_move.is_directory:
+ self.remove(source, True)
+ else:
+ self.remove(source)
+ if to_move.is_directory:
+ dest.directories.append(to_move)
+ dest.nodes.append(to_move)
+ else:
+ destination += '/' + src
+ self.create(destination, to_move.content)
+
+ def link(self, source, destination, symbolic=True):
+ pass
+
+ def mount(self, file_system, path):
+ pass
+
+ def unmount(self, path):
+ pass
+
+
+class FileSystemError(Exception):
+ def __init__(self):
+ self.message = "Error"
+
+ def __str__(self):
+ return self.message
+
+
+class NodeDoesNotExistError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "{0} {1}".format("Node does not exist", self.message)
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError, FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "{0} {1}".format("Source", self.message)
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError, FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "{0} {1}".format("Destination", self.message)
+
+
+class NotEnoughSpaceError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "Not Enough Space Error"
+
+
+class DestinationNodeExistsError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "Destination Node Exists Error"
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "Non Explicit Directory Deletion Error"
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "Non Empty Directory Deletion Error"
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ def __init__(self):
+ super().__init__()
+ self.message = "Destination Not A Directory Error"