From aefe913a7ced85093379a2c73dc579d312837b72 Mon Sep 17 00:00:00 2001 From: kanthuc Date: Sat, 8 Aug 2020 15:37:09 -0700 Subject: [PATCH 01/10] adding static type checking to basic_binary_tree.py --- .../binary_tree/basic_binary_tree.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/data_structures/binary_tree/basic_binary_tree.py b/data_structures/binary_tree/basic_binary_tree.py index 9b6e25d5ec56..e0f0c932b6a1 100644 --- a/data_structures/binary_tree/basic_binary_tree.py +++ b/data_structures/binary_tree/basic_binary_tree.py @@ -4,13 +4,13 @@ class Node: and left, right pointers. """ - def __init__(self, data): - self.data = data - self.left = None - self.right = None + def __init__(self, data: int): + self.data: int = data + self.left: Node = None + self.right: Node = None -def display(tree): # In Order traversal of the tree +def display(tree: Node): # In Order traversal of the tree if tree is None: return @@ -27,13 +27,13 @@ def display(tree): # In Order traversal of the tree def depth_of_tree( - tree, -): # This is the recursive function to find the depth of binary tree. + tree: Node, +) -> int: # This is the recursive function to find the depth of binary tree. if tree is None: return 0 else: - depth_l_tree = depth_of_tree(tree.left) - depth_r_tree = depth_of_tree(tree.right) + depth_l_tree: int = depth_of_tree(tree.left) + depth_r_tree: int = depth_of_tree(tree.right) if depth_l_tree > depth_r_tree: return 1 + depth_l_tree else: @@ -41,8 +41,8 @@ def depth_of_tree( def is_full_binary_tree( - tree, -): # This function returns that is it full binary tree or not? + tree: Node, +) -> bool: # This function returns that is it full binary tree or not? if tree is None: return True if (tree.left is None) and (tree.right is None): @@ -54,7 +54,7 @@ def is_full_binary_tree( def main(): # Main function for testing. - tree = Node(1) + tree: Node = Node(1) tree.left = Node(2) tree.right = Node(3) tree.left.left = Node(4) From e6766473a2ad8bd9325cc8ae76befce459e551d5 Mon Sep 17 00:00:00 2001 From: kanthuc Date: Sun, 9 Aug 2020 14:40:51 -0700 Subject: [PATCH 02/10] Add static type checking to functions with None return type --- data_structures/binary_tree/basic_binary_tree.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data_structures/binary_tree/basic_binary_tree.py b/data_structures/binary_tree/basic_binary_tree.py index e0f0c932b6a1..9ac91e6ee928 100644 --- a/data_structures/binary_tree/basic_binary_tree.py +++ b/data_structures/binary_tree/basic_binary_tree.py @@ -4,13 +4,13 @@ class Node: and left, right pointers. """ - def __init__(self, data: int): + def __init__(self, data: int) -> None: self.data: int = data self.left: Node = None self.right: Node = None -def display(tree: Node): # In Order traversal of the tree +def display(tree: Node) -> None: # In Order traversal of the tree if tree is None: return @@ -53,7 +53,7 @@ def is_full_binary_tree( return False -def main(): # Main function for testing. +def main() -> None: # Main function for testing. tree: Node = Node(1) tree.left = Node(2) tree.right = Node(3) From 6310890c3636921c11114889098f12212ee79ef4 Mon Sep 17 00:00:00 2001 From: kanthuc Date: Mon, 10 Aug 2020 14:13:45 -0700 Subject: [PATCH 03/10] Applying code review comments --- .../binary_tree/basic_binary_tree.py | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/data_structures/binary_tree/basic_binary_tree.py b/data_structures/binary_tree/basic_binary_tree.py index 9ac91e6ee928..5914962c4752 100644 --- a/data_structures/binary_tree/basic_binary_tree.py +++ b/data_structures/binary_tree/basic_binary_tree.py @@ -5,9 +5,9 @@ class Node: """ def __init__(self, data: int) -> None: - self.data: int = data - self.left: Node = None - self.right: Node = None + self.data = data + self.left: Optional[Node] = None + self.right: Optional[Node] = None def display(tree: Node) -> None: # In Order traversal of the tree @@ -26,23 +26,27 @@ def display(tree: Node) -> None: # In Order traversal of the tree return -def depth_of_tree( - tree: Node, -) -> int: # This is the recursive function to find the depth of binary tree. +def depth_of_tree(tree: Node,) -> int: + """ + Recursive function that finds the depth of a binary tree. + """ + if tree is None: return 0 else: - depth_l_tree: int = depth_of_tree(tree.left) - depth_r_tree: int = depth_of_tree(tree.right) + depth_l_tree = depth_of_tree(tree.left) + depth_r_tree = depth_of_tree(tree.right) if depth_l_tree > depth_r_tree: return 1 + depth_l_tree else: return 1 + depth_r_tree -def is_full_binary_tree( - tree: Node, -) -> bool: # This function returns that is it full binary tree or not? +def is_full_binary_tree(tree: Node,) -> bool: + """ + Returns True if this is a full binary tree + """ + if tree is None: return True if (tree.left is None) and (tree.right is None): @@ -54,7 +58,7 @@ def is_full_binary_tree( def main() -> None: # Main function for testing. - tree: Node = Node(1) + tree = Node(1) tree.left = Node(2) tree.right = Node(3) tree.left.left = Node(4) From 04391803f3a8188adedf487fe36d0ce7f03a1335 Mon Sep 17 00:00:00 2001 From: kanthuc Date: Mon, 10 Aug 2020 21:59:23 -0700 Subject: [PATCH 04/10] Added missing import statement --- data_structures/binary_tree/basic_binary_tree.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data_structures/binary_tree/basic_binary_tree.py b/data_structures/binary_tree/basic_binary_tree.py index 5914962c4752..91961ef2c649 100644 --- a/data_structures/binary_tree/basic_binary_tree.py +++ b/data_structures/binary_tree/basic_binary_tree.py @@ -1,3 +1,5 @@ +from typing import Optional + class Node: """ This is the Class Node with a constructor that contains data variable to type data From 5005cbcf0d1926e9d241d5fb229c3126070df5f0 Mon Sep 17 00:00:00 2001 From: kanthuc Date: Mon, 10 Aug 2020 22:11:07 -0700 Subject: [PATCH 05/10] fix spaciing --- data_structures/binary_tree/basic_binary_tree.py | 1 + 1 file changed, 1 insertion(+) diff --git a/data_structures/binary_tree/basic_binary_tree.py b/data_structures/binary_tree/basic_binary_tree.py index 91961ef2c649..c9b4aa495287 100644 --- a/data_structures/binary_tree/basic_binary_tree.py +++ b/data_structures/binary_tree/basic_binary_tree.py @@ -1,5 +1,6 @@ from typing import Optional + class Node: """ This is the Class Node with a constructor that contains data variable to type data From 039cdb3f9087b34e5b5d1a78a939c63047f2f6ea Mon Sep 17 00:00:00 2001 From: kanthuc Date: Tue, 11 Aug 2020 13:29:41 -0700 Subject: [PATCH 06/10] "cleaned up depth_of_tree" --- data_structures/binary_tree/basic_binary_tree.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/data_structures/binary_tree/basic_binary_tree.py b/data_structures/binary_tree/basic_binary_tree.py index c9b4aa495287..5472d0506833 100644 --- a/data_structures/binary_tree/basic_binary_tree.py +++ b/data_structures/binary_tree/basic_binary_tree.py @@ -34,15 +34,7 @@ def depth_of_tree(tree: Node,) -> int: Recursive function that finds the depth of a binary tree. """ - if tree is None: - return 0 - else: - depth_l_tree = depth_of_tree(tree.left) - depth_r_tree = depth_of_tree(tree.right) - if depth_l_tree > depth_r_tree: - return 1 + depth_l_tree - else: - return 1 + depth_r_tree + return 1 + max(depth_of_tree(tree.left), depth_of_tree(tree.right)) if tree else 0 def is_full_binary_tree(tree: Node,) -> bool: From f1c86afa018476b1c44296ccc59ea2cbc181382b Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Tue, 11 Aug 2020 23:30:28 +0200 Subject: [PATCH 07/10] Add doctests and then streamline display() and is_full_binary_tree() --- .../binary_tree/basic_binary_tree.py | 77 +++++++++++++------ 1 file changed, 52 insertions(+), 25 deletions(-) diff --git a/data_structures/binary_tree/basic_binary_tree.py b/data_structures/binary_tree/basic_binary_tree.py index 5472d0506833..5553056750ea 100644 --- a/data_structures/binary_tree/basic_binary_tree.py +++ b/data_structures/binary_tree/basic_binary_tree.py @@ -3,53 +3,80 @@ class Node: """ - This is the Class Node with a constructor that contains data variable to type data - and left, right pointers. + A Node has data variable and pointers to Nodes to its left and right. """ - def __init__(self, data: int) -> None: self.data = data self.left: Optional[Node] = None self.right: Optional[Node] = None -def display(tree: Node) -> None: # In Order traversal of the tree - - if tree is None: - return - - if tree.left is not None: +def display(tree: Optional[Node]) -> None: # In Order traversal of the tree + """ + >>> root = Node(1) + >>> root.left = Node(0) + >>> root.right = Node(2) + >>> display(root) + 0 + 1 + 2 + >>> display(root.right) + 2 + """ + if tree: display(tree.left) - - print(tree.data) - - if tree.right is not None: + print(tree.data) display(tree.right) - return - -def depth_of_tree(tree: Node,) -> int: +def depth_of_tree(tree: Optional[Node]) -> int: """ - Recursive function that finds the depth of a binary tree. + Recursive function that returns the depth of a binary tree. + + >>> root = Node(0) + >>> depth_of_tree(root) + 1 + >>> root.left = Node(0) + >>> depth_of_tree(root) + 2 + >>> root.right = Node(0) + >>> depth_of_tree(root) + 2 + >>> root.left.right = Node(0) + >>> depth_of_tree(root) + 3 + >>> depth_of_tree(root.left) + 2 """ - return 1 + max(depth_of_tree(tree.left), depth_of_tree(tree.right)) if tree else 0 -def is_full_binary_tree(tree: Node,) -> bool: +def is_full_binary_tree(tree: Node) -> bool: """ Returns True if this is a full binary tree - """ - if tree is None: - return True - if (tree.left is None) and (tree.right is None): + >>> root = Node(0) + >>> is_full_binary_tree(root) + True + >>> root.left = Node(0) + >>> is_full_binary_tree(root) + False + >>> root.right = Node(0) + >>> is_full_binary_tree(root) + True + >>> root.left.left = Node(0) + >>> is_full_binary_tree(root) + False + >>> root.right.right = Node(0) + >>> is_full_binary_tree(root) + False + """ + if not tree: return True - if (tree.left is not None) and (tree.right is not None): + if tree.left and tree.right: return is_full_binary_tree(tree.left) and is_full_binary_tree(tree.right) else: - return False + return not tree.left and not tree.right def main() -> None: # Main function for testing. From 052f40846082782ae76f677e0078a4d9e24295db Mon Sep 17 00:00:00 2001 From: kanthuc Date: Wed, 12 Aug 2020 21:49:03 -0700 Subject: [PATCH 08/10] added static typing to lazy_segment_tree.py --- .../binary_tree/lazy_segment_tree.py | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/data_structures/binary_tree/lazy_segment_tree.py b/data_structures/binary_tree/lazy_segment_tree.py index 461996b87c26..566b7f7513b8 100644 --- a/data_structures/binary_tree/lazy_segment_tree.py +++ b/data_structures/binary_tree/lazy_segment_tree.py @@ -2,21 +2,23 @@ class SegmentTree: - def __init__(self, N): + def __init__(self, N: int) -> None: self.N = N - self.st = [ + self.st: List[int] = [ 0 for i in range(0, 4 * N) ] # approximate the overall size of segment tree with array N - self.lazy = [0 for i in range(0, 4 * N)] # create array to store lazy update - self.flag = [0 for i in range(0, 4 * N)] # flag for lazy update + self.lazy: List[int] = [ + 0 for i in range(0, 4 * N) + ] # create array to store lazy update + self.flag: List[int] = [0 for i in range(0, 4 * N)] # flag for lazy update - def left(self, idx): + def left(self, idx: int) -> int: return idx * 2 - def right(self, idx): + def right(self, idx: int) -> int: return idx * 2 + 1 - def build(self, idx, l, r, A): # noqa: E741 + def build(self, idx: int, l: int, r: int, A: List[int]) -> None: # noqa: E741 if l == r: # noqa: E741 self.st[idx] = A[l - 1] else: @@ -27,7 +29,9 @@ def build(self, idx, l, r, A): # noqa: E741 # update with O(lg N) (Normal segment tree without lazy update will take O(Nlg N) # for each update) - def update(self, idx, l, r, a, b, val): # noqa: E741 + def update( + self, idx: int, l: int, r: int, a: int, b: int, val: int + ) -> bool: # noqa: E741 """ update(1, 1, N, a, b, v) for update val v to [a,b] """ @@ -57,7 +61,7 @@ def update(self, idx, l, r, a, b, val): # noqa: E741 return True # query with O(lg N) - def query(self, idx, l, r, a, b): # noqa: E741 + def query(self, idx: int, l: int, r: int, a: int, b: int) -> int: # noqa: E741 """ query(1, 1, N, a, b) for query max of [a,b] """ @@ -78,7 +82,7 @@ def query(self, idx, l, r, a, b): # noqa: E741 q2 = self.query(self.right(idx), mid + 1, r, a, b) return max(q1, q2) - def showData(self): + def showData(self) -> None: showList = [] for i in range(1, N + 1): showList += [self.query(1, 1, self.N, i, i)] From 8682782a070264ea8eb0408e583015f383c22889 Mon Sep 17 00:00:00 2001 From: kanthuc Date: Mon, 17 Aug 2020 18:40:56 -0700 Subject: [PATCH 09/10] added missing import statement --- data_structures/binary_tree/lazy_segment_tree.py | 1 + 1 file changed, 1 insertion(+) diff --git a/data_structures/binary_tree/lazy_segment_tree.py b/data_structures/binary_tree/lazy_segment_tree.py index 566b7f7513b8..2f4790382ead 100644 --- a/data_structures/binary_tree/lazy_segment_tree.py +++ b/data_structures/binary_tree/lazy_segment_tree.py @@ -1,4 +1,5 @@ import math +from typing import List class SegmentTree: From 15b1f622592e35f691875bc2e5b32592a229f704 Mon Sep 17 00:00:00 2001 From: kanthuc Date: Mon, 17 Aug 2020 19:21:02 -0700 Subject: [PATCH 10/10] modified variable names for left and right elements --- .../binary_tree/lazy_segment_tree.py | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/data_structures/binary_tree/lazy_segment_tree.py b/data_structures/binary_tree/lazy_segment_tree.py index 2f4790382ead..e247249bf232 100644 --- a/data_structures/binary_tree/lazy_segment_tree.py +++ b/data_structures/binary_tree/lazy_segment_tree.py @@ -19,68 +19,72 @@ def left(self, idx: int) -> int: def right(self, idx: int) -> int: return idx * 2 + 1 - def build(self, idx: int, l: int, r: int, A: List[int]) -> None: # noqa: E741 - if l == r: # noqa: E741 - self.st[idx] = A[l - 1] + def build( + self, idx: int, left_element: int, right_element: int, A: List[int] + ) -> None: + if left_element == right_element: + self.st[idx] = A[left_element - 1] else: - mid = (l + r) // 2 - self.build(self.left(idx), l, mid, A) - self.build(self.right(idx), mid + 1, r, A) + mid = (left_element + right_element) // 2 + self.build(self.left(idx), left_element, mid, A) + self.build(self.right(idx), mid + 1, right_element, A) self.st[idx] = max(self.st[self.left(idx)], self.st[self.right(idx)]) # update with O(lg N) (Normal segment tree without lazy update will take O(Nlg N) # for each update) def update( - self, idx: int, l: int, r: int, a: int, b: int, val: int - ) -> bool: # noqa: E741 + self, idx: int, left_element: int, right_element: int, a: int, b: int, val: int + ) -> bool: """ update(1, 1, N, a, b, v) for update val v to [a,b] """ if self.flag[idx] is True: self.st[idx] = self.lazy[idx] self.flag[idx] = False - if l != r: # noqa: E741 + if left_element != right_element: self.lazy[self.left(idx)] = self.lazy[idx] self.lazy[self.right(idx)] = self.lazy[idx] self.flag[self.left(idx)] = True self.flag[self.right(idx)] = True - if r < a or l > b: + if right_element < a or left_element > b: return True - if l >= a and r <= b: # noqa: E741 + if left_element >= a and right_element <= b: self.st[idx] = val - if l != r: # noqa: E741 + if left_element != right_element: self.lazy[self.left(idx)] = val self.lazy[self.right(idx)] = val self.flag[self.left(idx)] = True self.flag[self.right(idx)] = True return True - mid = (l + r) // 2 - self.update(self.left(idx), l, mid, a, b, val) - self.update(self.right(idx), mid + 1, r, a, b, val) + mid = (left_element + right_element) // 2 + self.update(self.left(idx), left_element, mid, a, b, val) + self.update(self.right(idx), mid + 1, right_element, a, b, val) self.st[idx] = max(self.st[self.left(idx)], self.st[self.right(idx)]) return True # query with O(lg N) - def query(self, idx: int, l: int, r: int, a: int, b: int) -> int: # noqa: E741 + def query( + self, idx: int, left_element: int, right_element: int, a: int, b: int + ) -> int: """ query(1, 1, N, a, b) for query max of [a,b] """ if self.flag[idx] is True: self.st[idx] = self.lazy[idx] self.flag[idx] = False - if l != r: # noqa: E741 + if left_element != right_element: self.lazy[self.left(idx)] = self.lazy[idx] self.lazy[self.right(idx)] = self.lazy[idx] self.flag[self.left(idx)] = True self.flag[self.right(idx)] = True - if r < a or l > b: + if right_element < a or left_element > b: return -math.inf - if l >= a and r <= b: # noqa: E741 + if left_element >= a and right_element <= b: return self.st[idx] - mid = (l + r) // 2 - q1 = self.query(self.left(idx), l, mid, a, b) - q2 = self.query(self.right(idx), mid + 1, r, a, b) + mid = (left_element + right_element) // 2 + q1 = self.query(self.left(idx), left_element, mid, a, b) + q2 = self.query(self.right(idx), mid + 1, right_element, a, b) return max(q1, q2) def showData(self) -> None: