diff --git a/.gitignore b/.gitignore index b9c502b..6f5f4b8 100644 --- a/.gitignore +++ b/.gitignore @@ -87,4 +87,4 @@ ENV/ # Rope project settings .ropeproject -.idea* +.idea/ diff --git a/.travis.yml b/.travis.yml index 64bf0c1..6ce19b6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,8 @@ matrix: dist: xenial sudo: true install: - - pip install flake8 mock + - pip install flake8 + - pip install mock - pip install pytest==3.5.1 - pip install pytest-cov==2.5.1 - pip install python-coveralls==2.9.1 diff --git a/README.rst b/README.rst index 81e3c41..f5f0f37 100644 --- a/README.rst +++ b/README.rst @@ -50,7 +50,7 @@ Announcements Requirements ============ -- Python 2.7, 3.4, 3.5, 3.6, 3.7, 3.8 +- Python 2.7+ or 3.4+ Installation ============ diff --git a/binarytree/__init__.py b/binarytree/__init__.py index d60ce0a..2681f80 100644 --- a/binarytree/__init__.py +++ b/binarytree/__init__.py @@ -1,6 +1,6 @@ from __future__ import absolute_import, unicode_literals, division -__all__ = ['Node', 'tree', 'bst', 'heap', 'build'] +__all__ = ['Node', 'tree', 'bst', 'heap', 'build', 'get_parent'] import heapq import random @@ -26,7 +26,7 @@ def _is_balanced(root): """Return the tree height + 1 if balanced, -1 otherwise. :param root: Root node of the binary tree. - :type root: binarytree.Node | None + :type root: binarytree.Node :return: Height if the binary tree is balanced, -1 otherwise. :rtype: int """ @@ -45,7 +45,7 @@ def _is_bst(root, min_value=float('-inf'), max_value=float('inf')): """Check if the binary tree is a BST (binary search tree). :param root: Root node of the binary tree. - :type root: binarytree.Node | None + :type root: binarytree.Node :param min_value: Minimum node value seen. :type min_value: int | float :param max_value: Maximum node value seen. @@ -66,7 +66,7 @@ def _is_symmetric(root): """Check if the binary tree is symmetric. :param root: Root node of the binary tree. - :type root: binarytree.Node | None + :type root: binarytree.Node :return: True if the binary tree is symmetric, False otherwise. :rtype: bool """ @@ -168,7 +168,7 @@ def _build_tree_string(root, curr_index, index=False, delimiter='-'): call then combines its left and right sub-boxes to build a larger box etc. :param root: Root node of the binary tree. - :type root: binarytree.Node | None + :type root: binarytree.Node :param curr_index: Level-order_ index of the current node (root node is 0). :type curr_index: int :param index: If set to True, include the level-order_ node indexes using @@ -247,7 +247,7 @@ def _get_tree_properties(root): """Inspect the binary tree and return its properties (e.g. height). :param root: Root node of the binary tree. - :rtype: binarytree.Node + :type root: binarytree.Node :return: Binary tree properties. :rtype: dict """ @@ -321,54 +321,54 @@ def _get_tree_properties(root): } -def get_parent_node(root, node): - """Search from the binary tree and return the parent node for require node. +def get_parent(root, child): + """Search the binary tree and return the parent of given child. :param root: Root node of the binary tree. + :type: binarytree.Node + :param child: Child node. :rtype: binarytree.Node - :param node: Require node you want to get its parent node. - :rtype: binarytree.Node - :return: The parent node of require node. + :return: Parent node, or None if missing. :rtype: binarytree.Node **Example**: - .. doctest:: + .. doctest:: - >>> from binarytree import Node, get_parent_node - >>> root = Node(0) - >>> root.left = Node(1) - >>> root.right = Node(2) - >>> root.left.left = Node(3) - >>> print (root) - >>> 0 - / \ - 1 2 - / - 3 - >>> print (get_parent_node(root, root.left.left)) - >>> 1 - / - 3 + >>> from binarytree import Node, get_parent + >>> + >>> root = Node(1) + >>> root.left = Node(2) + >>> root.right = Node(3) + >>> root.left.right = Node(4) + >>> + >>> print(root) + + __1 + / \\ + 2 3 + \\ + 4 + + >>> print(get_parent(root, root.left.right)) + + 2 + \\ + 4 + """ - if node is None: + if child is None: return None - node_stack = [] - while True: - if root is not None: - node_stack.append(root) - if root.left is node: - return root - else: - root = root.left - elif len(node_stack) > 0: - root = node_stack.pop() - if root.right is node: - return root + + stack = [root] + while stack: + node = stack.pop() + if node: + if node.left is child or node.right is child: + return node else: - root = root.right - else: - break + stack.append(node.left) + stack.append(node.right) return None @@ -383,9 +383,9 @@ class Node(object): :param value: Node value (must be a number). :type value: int | float | numbers.Number :param left: Left child node (default: None). - :type left: binarytree.Node | None + :type left: binarytree.Node :param right: Right child node (default: None). - :type right: binarytree.Node | None + :type right: binarytree.Node :raise binarytree.exceptions.NodeTypeError: If left or right child node is not an instance of :class:`binarytree.Node`. :raise binarytree.exceptions.NodeValueError: If node value is not a number diff --git a/binarytree/version.py b/binarytree/version.py index af142cb..4bb10cb 100644 --- a/binarytree/version.py +++ b/binarytree/version.py @@ -1 +1 @@ -__version__ = '5.0.0' # pragma: no cover +__version__ = '5.0.1' # pragma: no cover diff --git a/docs/index.rst b/docs/index.rst index ae518ec..3396e1b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -11,7 +11,7 @@ algorithms. Heaps and BSTs (binary search trees) are also supported. Requirements ============ -- Python 2.7, 3.5, 3.6, 3.7, 3.8 +- Python 2.7+ or 3.4+ Installation ============ diff --git a/docs/specs.rst b/docs/specs.rst index c697c04..8235bb0 100644 --- a/docs/specs.rst +++ b/docs/specs.rst @@ -9,6 +9,7 @@ functions: * :func:`binarytree.tree` * :func:`binarytree.bst` * :func:`binarytree.heap` +* :func:`binarytree.get_parent` Class: binarytree.Node ====================== @@ -38,3 +39,8 @@ Function: binarytree.heap ========================= .. autofunction:: binarytree.heap + +Function: binarytree.get_parent +=============================== + +.. autofunction:: binarytree.get_parent diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..54e4496 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,4 @@ +[pytest] +python_files = tests.py test_*.py *_tests.py +addopts = -vv -p no:warnings --cov=binarytree +norecursedirs = venv htmlcov build dist .idea .git diff --git a/tests/test_tree.py b/tests/test_tree.py index 81408f2..23e7756 100644 --- a/tests/test_tree.py +++ b/tests/test_tree.py @@ -6,7 +6,7 @@ import pytest from binarytree import Node, build, tree, bst, heap -from binarytree import get_parent_node +from binarytree import get_parent from binarytree.exceptions import ( NodeValueError, NodeIndexError, @@ -887,18 +887,18 @@ def test_heap_float_values(): assert root.size == root_copy.size -@pytest.mark.order14 -def test_get_parent_node(): +def test_get_parent(): root = Node(0) root.left = Node(1) root.right = Node(2) root.left.left = Node(3) root.right.right = Node(4) - assert get_parent_node(root, root.left.left) == root.left - assert get_parent_node(root, root.left) == root - assert get_parent_node(root, root) is None - assert get_parent_node(root, root.right.right) == root.right - assert get_parent_node(root, root.right) == root - assert get_parent_node(root, Node(5)) is None - assert get_parent_node(None, root.left) is None - assert get_parent_node(root, None) is None + + assert get_parent(root, root.left.left) == root.left + assert get_parent(root, root.left) == root + assert get_parent(root, root) is None + assert get_parent(root, root.right.right) == root.right + assert get_parent(root, root.right) == root + assert get_parent(root, Node(5)) is None + assert get_parent(None, root.left) is None + assert get_parent(root, None) is None