def move(self, path, new_parent_path): """ Move category from anywhere to anywhere in the tree. Category can only be moved 'under' a new parent. So it can't be moved on top of the root category. Makes sure that: Root category cannot be moved. Parameters: path(str,iterable,Path): path of the category to be moved. new_parent_path(str,iterable,Path): path of the new parent of the category to be moved. Returns: None Raises: RootMoveError """ path = Path(path) new_parent_path = Path(new_parent_path) category = self.get(path) if category.is_root(): raise RootMoveError() new_parent = self.get(new_parent_path) category.parent._remove_child(category) new_parent._add_child(category)
def path(self): """ Return the path from the root to the current category including the current one. """ if not self.parent: return Path([self.name]) return Path(self.parent.path) + Path([self.name])
def test_find(tree): found = tree._find(Path('food/fruits')) assert isinstance(found, Category) assert found.name == 'fruits' found = tree._find(Path('food/fruits/apple')) assert isinstance(found, Category) assert found.name == 'apple' found = tree._find(Path('food/fruits/apple/red')) assert isinstance(found, Category) assert found.name == 'red' found = tree._find(Path('fruits/apple')) assert found is None found = tree._find(Path('apple')) assert found is None found = tree._find(Path('apple/red')) assert found is None found = tree._find(Path('red')) assert found is None found = tree._find(Path('carrot')) assert found is None
def get(self, path): """ Get the category whose path is given as argument. Search can be performed anywhere in the tree (cf sample diagram): Valid searches: tree.get('food') -> food (itself) tree.get('fruits') -> fruits tree.get('apple') -> apple tree.get('fruits/apple') -> apple tree.get('food/fruits/apple') -> apple Invalid searches (return None): tree.get('food/apple') Parameters: path(str,iterable,Path): path of the category that is searched for Returns: found(Category,None): the found category or None """ found = None path = Path(path) start = self._find_start(path) if start: found = start._find(path) return found
def add(self, category, path=None): """ Add category under the given path. Parameters: category(Category): category to add under path path(str,iterable,Path): path under which the category is to be added Returns: None """ if not path: self._add_child(category) else: path = Path(path) parent = self.get(path) if not parent: raise CategoryDoesNotExistError(path) parent._add_child(category)
def delete(self, path): """ Remove the instance from parent's children. A category can be deleted anywhere in the tree. Makes sure that: Root category cannot be deleted. Parameters: path(str,iterable,Path): path of the category to be deleted. Returns: None Raises: RootDeleteError """ to_delete = self.get(Path(path)) if to_delete.is_root(): raise RootDeleteError() to_delete.parent._remove_child(to_delete)
def size(self, path=None): """ Return the number of all the categories under a given path including the root of the given tree. Parameters: path(str,iterable,Path): path of the category whose size should be returned Return: size(int): number of all categories under the current one Raises: CategoryDoesNotExistsError """ size = 1 if not path: category = self else: category = self.get(Path(path)) if not category: raise CategoryDoesNotExistError(path) for child in category.children: size = size + child.size() return size