Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feature for searching upper layer parent node #24

Merged
merged 1 commit into from May 22, 2020
Merged

Add feature for searching upper layer parent node #24

merged 1 commit into from May 22, 2020

Conversation

DechinPhy
Copy link
Contributor

This is a new feature implemented.

  1. flake8 passed with nothing return.
  2. unit test passed with 100% coverage.

@joowani joowani force-pushed the dev branch 3 times, most recently from 628e909 to 1d384dd Compare May 20, 2020 20:43
Copy link
Owner

@joowani joowani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. The concept of using wtree seems very hacky. So I suggest exposing your new API as a public, importable function get_parent(root, node). The function itself could be simplified greatly (see comments).

Also, please squash all the commits into one, and change the commit messsage to something like "Add get_parent function".

Thanks!

node_height = node.height
if root_height == node_height:
return None
node_level_list = root.levels[root_height - node_height]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Node.levels here is unnecessary and inefficient. You could search for parent using BFS instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will try this but I think BFS maybe also not the most efficient way. If you agree with this, I can add BFS as the first stage searching algorithm and later update it if I found a more efficient way.

start_index = node_index // 2
for pnode in parent_level_list[start_index:]:
try:
if pnode.left.value == node.value or\
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if there are multiple nodes with same values? Best way to check for object equality is using Python's is keyword.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's ok to use is keyword and I will modify it. In my cases all nodes are with different values so I didn't consider about this.

@@ -314,6 +315,38 @@ def _get_tree_properties(root):
}


def _get_parent_node(root, node):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using wtree (which feels very hacky to be honest), I suggest providing the functionality as a public function with signature get_parent(root, node).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about add the property up or I used upper for the Node object? Still using the function get_parent(root, node).

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it can work cleanly as a property since you need access to the root and because we should not be mutating objects. I think a public function might be the only way.

self._root = tree

@property
def upper(self):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just call this parent?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because when you call left you mean go to the left node and right to the right one. I just want to be the same style with these properties. eg. You can call up or upper to go to the upper node.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The most common convention is "parent". I've never seen the term "upper node" used in context of binary trees so it may confuse the users.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 12455b3 on DechinPhy:master into 1d384dd on joowani:dev.

@coveralls
Copy link

coveralls commented May 21, 2020

Coverage Status

Coverage remained the same at 100.0% when pulling 7c1e41a on DechinPhy:master into 1d384dd on joowani:dev.

Copy link
Contributor Author

@DechinPhy DechinPhy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joowani Thank you for your advice! According to what we talked about, the only change I commit is adding a function get_parent_node and correspond unittests. The rebase stuff can be done after review.

@@ -315,7 +314,7 @@ def _get_tree_properties(root):
}


def _get_parent_node(root, node):
def get_parent_node(root, node):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The properties in Node class is removed and the function get_parent_node has been changed into a public function

binarytree/__init__.py Show resolved Hide resolved
@@ -1064,57 +1082,6 @@ def size(self):
"""
return _get_tree_properties(self)['size']

@property
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wtree and upper property removed.

@@ -31,7 +31,3 @@ class NodeValueError(BinaryTreeError):

class TreeHeightError(BinaryTreeError):
"""Tree height was invalid."""


class WtreeUnsetError(BinaryTreeError):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we do not need a Wtree, the Error class should also be removed.

tests/test_tree.py Show resolved Hide resolved
Copy link
Contributor Author

@DechinPhy DechinPhy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

git rebase works done.

Copy link
Owner

@joowani joowani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @DechinPhy,

Looking good. Just a few minor fixes and I think it will be ready for merging. Please squash the commit again. Thanks.

/
3
"""
if root is node or root is None or node is None:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this if statement necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if just make it clear what will be the return when situations happens. I deleted this in new push.



@pytest.mark.order14
def test_get_parent_node():
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are missing some test cases (e.g. when root is None).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test case root is None and node is None cases are added.

if root is node or root is None or node is None:
return None
node_stack = []
while True:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this solution 👍

Copy link
Contributor Author

@DechinPhy DechinPhy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for you advice again :)

/
3
"""
if node is None:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

node == None case remained and necessary.

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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both test case of None node input is added.

Copy link
Owner

@joowani joowani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything looks good. Thanks for your contribution!

@joowani joowani merged commit 821f433 into joowani:dev May 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants