From 55844f59ae1f42063794367aa41628dc1df0f8c2 Mon Sep 17 00:00:00 2001 From: Isidro Arias Date: Wed, 26 Apr 2023 12:20:33 +0200 Subject: [PATCH 01/12] rsa key doctest --- ciphers/rsa_key_generator.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/ciphers/rsa_key_generator.py b/ciphers/rsa_key_generator.py index 2573ed01387b..3ee6c30c7c28 100644 --- a/ciphers/rsa_key_generator.py +++ b/ciphers/rsa_key_generator.py @@ -2,8 +2,8 @@ import random import sys -from . import cryptomath_module as cryptoMath # noqa: N812 -from . import rabin_miller as rabinMiller # noqa: N812 +import cryptomath_module +import rabin_miller def main() -> None: @@ -13,20 +13,26 @@ def main() -> None: def generate_key(key_size: int) -> tuple[tuple[int, int], tuple[int, int]]: - print("Generating prime p...") - p = rabinMiller.generate_large_prime(key_size) - print("Generating prime q...") - q = rabinMiller.generate_large_prime(key_size) + """ + >>> random.seed(0) # for repeatability + >>> public_key, private_key = generate_key(8) + >>> public_key + (46513, 197) + >>> private_key + (46513, 2573) + """ + p = rabin_miller.generate_large_prime(key_size) + q = rabin_miller.generate_large_prime(key_size) n = p * q - print("Generating e that is relatively prime to (p - 1) * (q - 1)...") + # Generate e that is relatively prime to (p - 1) * (q - 1) while True: e = random.randrange(2 ** (key_size - 1), 2 ** (key_size)) - if cryptoMath.gcd(e, (p - 1) * (q - 1)) == 1: + if cryptomath_module.gcd(e, (p - 1) * (q - 1)) == 1: break - print("Calculating d that is mod inverse of e...") - d = cryptoMath.find_mod_inverse(e, (p - 1) * (q - 1)) + # Calculate d that is mod inverse of e + d = cryptomath_module.find_mod_inverse(e, (p - 1) * (q - 1)) public_key = (n, e) private_key = (n, d) From 9294347a0f1412622b15c65879cca887d2af31bb Mon Sep 17 00:00:00 2001 From: Isidro Arias Date: Wed, 26 Apr 2023 12:36:28 +0200 Subject: [PATCH 02/12] move doctest to module docstring --- .../binary_tree/binary_search_tree.py | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index cd88cc10e697..88e3538db4fd 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -1,5 +1,25 @@ -""" +r""" A binary search Tree + +Example + 8 + / \ + 3 10 + / \ \ + 1 6 14 + / \ / + 4 7 13 + +>>> t = BinarySearchTree() +>>> t.insert(8, 3, 6, 1, 10, 14, 13, 4, 7) +>>> print(" ".join(repr(i.value) for i in t.traversal_tree())) +8 3 1 6 4 7 10 14 13 +>>> print(" ".join(repr(i.value) for i in t.traversal_tree(postorder))) +1 4 7 6 3 13 14 10 8 +>>> BinarySearchTree().search(6) +Traceback (most recent call last): + ... +IndexError: Warning: Tree is empty! please use another. """ from collections.abc import Iterable @@ -177,28 +197,7 @@ def postorder(curr_node: Node | None) -> list[Node]: return node_list -def binary_search_tree() -> None: - r""" - Example - 8 - / \ - 3 10 - / \ \ - 1 6 14 - / \ / - 4 7 13 - - >>> t = BinarySearchTree() - >>> t.insert(8, 3, 6, 1, 10, 14, 13, 4, 7) - >>> print(" ".join(repr(i.value) for i in t.traversal_tree())) - 8 3 1 6 4 7 10 14 13 - >>> print(" ".join(repr(i.value) for i in t.traversal_tree(postorder))) - 1 4 7 6 3 13 14 10 8 - >>> BinarySearchTree().search(6) - Traceback (most recent call last): - ... - IndexError: Warning: Tree is empty! please use another. - """ +def binary_search_tree_example() -> None: testlist = (8, 3, 6, 1, 10, 14, 13, 4, 7) t = BinarySearchTree() for i in testlist: @@ -230,3 +229,4 @@ def binary_search_tree() -> None: import doctest doctest.testmod(verbose=True) + binary_search_tree_example() From 8510e1fde6e24ddbdaa750fd4deb6f6e2192d912 Mon Sep 17 00:00:00 2001 From: Isidro Arias Date: Wed, 26 Apr 2023 12:51:26 +0200 Subject: [PATCH 03/12] all tests to doctest --- .../binary_tree/binary_search_tree.py | 57 +++++++++---------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index 88e3538db4fd..14666590b44f 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -20,6 +20,34 @@ Traceback (most recent call last): ... IndexError: Warning: Tree is empty! please use another. + +Other example: + +>>> testlist = (8, 3, 6, 1, 10, 14, 13, 4, 7) +>>> t = BinarySearchTree() +>>> for i in testlist: +... t.insert(i) + +Prints all the elements of the list in order traversal +>>> print(t) +{'8': ({'3': (1, {'6': (4, 7)})}, {'10': (None, {'14': (13, None)})})} + +Test existence +>>> t.search(6) is not None +True +>>> t.search(-1) is not None +False + +>>> t.get_max().value +14 +>>> t.get_min().value +1 +>>> t.empty() +False +>>> for i in testlist: +... t.remove(i) +>>> t.empty() +True """ from collections.abc import Iterable @@ -197,36 +225,7 @@ def postorder(curr_node: Node | None) -> list[Node]: return node_list -def binary_search_tree_example() -> None: - testlist = (8, 3, 6, 1, 10, 14, 13, 4, 7) - t = BinarySearchTree() - for i in testlist: - t.insert(i) - - # Prints all the elements of the list in order traversal - print(t) - - if t.search(6) is not None: - print("The value 6 exists") - else: - print("The value 6 doesn't exist") - - if t.search(-1) is not None: - print("The value -1 exists") - else: - print("The value -1 doesn't exist") - - if not t.empty(): - print("Max Value: ", t.get_max().value) # type: ignore - print("Min Value: ", t.get_min().value) # type: ignore - - for i in testlist: - t.remove(i) - print(t) - - if __name__ == "__main__": import doctest doctest.testmod(verbose=True) - binary_search_tree_example() From 07de23f04e3b4cc361ae2ff636b11f3e6d7f2ac9 Mon Sep 17 00:00:00 2001 From: Isidro Arias Date: Wed, 26 Apr 2023 12:52:49 +0200 Subject: [PATCH 04/12] moved is_right to property --- data_structures/binary_tree/binary_search_tree.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index 14666590b44f..6ed9af447d5b 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -68,6 +68,12 @@ def __repr__(self) -> str: return str(self.value) return pformat({f"{self.value}": (self.left, self.right)}, indent=1) + @property + def is_right(self) -> bool: + if self.parent and self.parent.right: + return self == self.parent.right + return False + class BinarySearchTree: def __init__(self, root: Node | None = None): @@ -83,18 +89,13 @@ def __reassign_nodes(self, node: Node, new_children: Node | None) -> None: if new_children is not None: # reset its kids new_children.parent = node.parent if node.parent is not None: # reset its parent - if self.is_right(node): # If it is the right children + if node.is_right: # If it is the right children node.parent.right = new_children else: node.parent.left = new_children else: self.root = None - def is_right(self, node: Node) -> bool: - if node.parent and node.parent.right: - return node == node.parent.right - return False - def empty(self) -> bool: return self.root is None From 9f5f4ffcd50cce6ec557402a525854ffadb7ffc5 Mon Sep 17 00:00:00 2001 From: Isidro Arias Date: Wed, 26 Apr 2023 12:56:36 +0200 Subject: [PATCH 05/12] is right test --- data_structures/binary_tree/binary_search_tree.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index 6ed9af447d5b..2babb48299dc 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -38,6 +38,11 @@ >>> t.search(-1) is not None False +>>> t.search(6).is_right +True +>>> t.search(1).is_right +False + >>> t.get_max().value 14 >>> t.get_min().value @@ -177,12 +182,12 @@ def remove(self, value: int) -> None: elif node.right is None: # Has only left children self.__reassign_nodes(node, node.left) else: - tmp_node = self.get_max( + predecessor = self.get_max( node.left ) # Gets the max value of the left branch - self.remove(tmp_node.value) # type: ignore + self.remove(predecessor.value) # type: ignore node.value = ( - tmp_node.value # type: ignore + predecessor.value # type: ignore ) # Assigns the value to the node to delete and keep tree structure def preorder_traverse(self, node: Node | None) -> Iterable: From 45c6818fa28e9c078ee10018cb4723fc3a14b400 Mon Sep 17 00:00:00 2001 From: Isidro Arias Date: Wed, 26 Apr 2023 13:10:09 +0200 Subject: [PATCH 06/12] fixed rsa doctest import --- ciphers/rsa_key_generator.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ciphers/rsa_key_generator.py b/ciphers/rsa_key_generator.py index 3ee6c30c7c28..eedc7336804a 100644 --- a/ciphers/rsa_key_generator.py +++ b/ciphers/rsa_key_generator.py @@ -2,8 +2,7 @@ import random import sys -import cryptomath_module -import rabin_miller +from . import cryptomath_module, rabin_miller def main() -> None: @@ -17,9 +16,9 @@ def generate_key(key_size: int) -> tuple[tuple[int, int], tuple[int, int]]: >>> random.seed(0) # for repeatability >>> public_key, private_key = generate_key(8) >>> public_key - (46513, 197) + (26569, 239) >>> private_key - (46513, 2573) + (26569, 2855) """ p = rabin_miller.generate_large_prime(key_size) q = rabin_miller.generate_large_prime(key_size) From 4a13d5d118191f40fc443ea6a5fd121fcff3b268 Mon Sep 17 00:00:00 2001 From: Isidro Arias Date: Sat, 3 Jun 2023 20:07:54 +0200 Subject: [PATCH 07/12] Test error when deleting non-existing element --- .../binary_tree/binary_search_tree.py | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index 2babb48299dc..1c29b38360d7 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -16,6 +16,10 @@ 8 3 1 6 4 7 10 14 13 >>> print(" ".join(repr(i.value) for i in t.traversal_tree(postorder))) 1 4 7 6 3 13 14 10 8 +>>> t.remove(20) +Traceback (most recent call last): + ... +ValueError: Value 20 not found >>> BinarySearchTree().search(6) Traceback (most recent call last): ... @@ -173,22 +177,25 @@ def get_min(self, node: Node | None = None) -> Node | None: return node def remove(self, value: int) -> None: - node = self.search(value) # Look for the node with that label - if node is not None: - if node.left is None and node.right is None: # If it has no children - self.__reassign_nodes(node, None) - elif node.left is None: # Has only right children - self.__reassign_nodes(node, node.right) - elif node.right is None: # Has only left children - self.__reassign_nodes(node, node.left) - else: - predecessor = self.get_max( - node.left - ) # Gets the max value of the left branch - self.remove(predecessor.value) # type: ignore - node.value = ( - predecessor.value # type: ignore - ) # Assigns the value to the node to delete and keep tree structure + # Look for the node with that label + node = self.search(value) + if node is None: + raise ValueError(f"Value {value} not found") + + if node.left is None and node.right is None: # If it has no children + self.__reassign_nodes(node, None) + elif node.left is None: # Has only right children + self.__reassign_nodes(node, node.right) + elif node.right is None: # Has only left children + self.__reassign_nodes(node, node.left) + else: + predecessor = self.get_max( + node.left + ) # Gets the max value of the left branch + self.remove(predecessor.value) # type: ignore + node.value = ( + predecessor.value # type: ignore + ) # Assigns the value to the node to delete and keep tree structure def preorder_traverse(self, node: Node | None) -> Iterable: if node is not None: From 2791958f9af478854528b4cfce5fb8ffd945134c Mon Sep 17 00:00:00 2001 From: Isidro Arias Date: Sat, 3 Jun 2023 20:21:23 +0200 Subject: [PATCH 08/12] fixing ruff EM102 --- data_structures/binary_tree/binary_search_tree.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index 1c29b38360d7..eca99e53f7cb 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -180,7 +180,8 @@ def remove(self, value: int) -> None: # Look for the node with that label node = self.search(value) if node is None: - raise ValueError(f"Value {value} not found") + msg = f"Value {value} not found" + raise ValueError(msg) if node.left is None and node.right is None: # If it has no children self.__reassign_nodes(node, None) From ba2efa21818069fb93fc05255a79e0d2f9846be1 Mon Sep 17 00:00:00 2001 From: isidroas Date: Mon, 14 Aug 2023 20:39:50 +0200 Subject: [PATCH 09/12] convert property 'is_right' to one-liner Also use 'is' instead of '==' Co-authored-by: Tianyi Zheng --- data_structures/binary_tree/binary_search_tree.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index eca99e53f7cb..ee6aeb482e7d 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -79,9 +79,7 @@ def __repr__(self) -> str: @property def is_right(self) -> bool: - if self.parent and self.parent.right: - return self == self.parent.right - return False + return self.parent and self is self.parent.right class BinarySearchTree: From 7973b7b265cdc3a9293a0dd35f9aeef4c65d5678 Mon Sep 17 00:00:00 2001 From: isidroas Date: Mon, 14 Aug 2023 20:42:09 +0200 Subject: [PATCH 10/12] child instead of children Co-authored-by: Tianyi Zheng --- data_structures/binary_tree/binary_search_tree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index ee6aeb482e7d..5193942e46eb 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -96,7 +96,7 @@ def __reassign_nodes(self, node: Node, new_children: Node | None) -> None: if new_children is not None: # reset its kids new_children.parent = node.parent if node.parent is not None: # reset its parent - if node.is_right: # If it is the right children + if node.is_right: # If it is the right child node.parent.right = new_children else: node.parent.left = new_children From f76fbace0238affb6611ade11b8ec450b7aadc5d Mon Sep 17 00:00:00 2001 From: Isidro Arias Date: Mon, 14 Aug 2023 20:53:22 +0200 Subject: [PATCH 11/12] remove type hint --- data_structures/binary_tree/binary_search_tree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index 5193942e46eb..c81dcddabf93 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -78,7 +78,7 @@ def __repr__(self) -> str: return pformat({f"{self.value}": (self.left, self.right)}, indent=1) @property - def is_right(self) -> bool: + def is_right(self): return self.parent and self is self.parent.right From 82126901987f81e5300d57ea962e4555b0628dfb Mon Sep 17 00:00:00 2001 From: Tianyi Zheng Date: Tue, 15 Aug 2023 16:00:34 -0700 Subject: [PATCH 12/12] Update data_structures/binary_tree/binary_search_tree.py --- data_structures/binary_tree/binary_search_tree.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index 61e36b99e566..a706d21e3bb2 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -78,8 +78,8 @@ def __repr__(self) -> str: return pformat({f"{self.value}": (self.left, self.right)}, indent=1) @property - def is_right(self): - return self.parent and self is self.parent.right + def is_right(self) -> bool: + return self.parent is not None and self is self.parent.right class BinarySearchTree: