From daa1c7529ac6491338adb81622d5041a4ba1f446 Mon Sep 17 00:00:00 2001 From: Caeden Perelli-Harris Date: Sun, 6 Nov 2022 14:54:44 +0000 Subject: [PATCH] Raise error not string (#7945) * ci: Add `B023` to `.flake8` ignores * refactor: Return `bool`/raise Exception * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * revert: Remove previous branch commit * Update data_structures/binary_tree/segment_tree_other.py Co-authored-by: Christian Clauss * feat: Apply `__repr__` changes * chore: Fix failing tests * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update data_structures/binary_tree/segment_tree_other.py Co-authored-by: Christian Clauss * test: Fix doctests * random.choice(population_score[:N_SELECTED])[0] * Update basic_string.py Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss --- boolean_algebra/quine_mc_cluskey.py | 11 +- ciphers/shuffled_shift_cipher.py | 2 +- computer_vision/harris_corner.py | 3 +- .../binary_tree/segment_tree_other.py | 121 +++++++++--------- data_structures/binary_tree/wavelet_tree.py | 6 +- .../linked_list/doubly_linked_list.py | 2 +- data_structures/queue/double_ended_queue.py | 2 +- graphs/breadth_first_search_shortest_path.py | 8 +- graphs/page_rank.py | 2 +- linear_algebra/src/polynom_for_points.py | 14 +- maths/monte_carlo_dice.py | 3 - matrix/cramers_rule_2x2.py | 16 ++- other/password.py | 38 +++--- strings/dna.py | 15 ++- 14 files changed, 123 insertions(+), 120 deletions(-) diff --git a/boolean_algebra/quine_mc_cluskey.py b/boolean_algebra/quine_mc_cluskey.py index 5bd7117bb..6788dfb28 100644 --- a/boolean_algebra/quine_mc_cluskey.py +++ b/boolean_algebra/quine_mc_cluskey.py @@ -1,15 +1,16 @@ from __future__ import annotations from collections.abc import Sequence +from typing import Literal -def compare_string(string1: str, string2: str) -> str: +def compare_string(string1: str, string2: str) -> str | Literal[False]: """ >>> compare_string('0010','0110') '0_10' >>> compare_string('0110','1101') - 'X' + False """ list1 = list(string1) list2 = list(string2) @@ -19,7 +20,7 @@ def compare_string(string1: str, string2: str) -> str: count += 1 list1[i] = "_" if count > 1: - return "X" + return False else: return "".join(list1) @@ -36,10 +37,10 @@ def check(binary: list[str]) -> list[str]: for i in range(len(binary)): for j in range(i + 1, len(binary)): k = compare_string(binary[i], binary[j]) - if k != "X": + if k is False: check1[i] = "*" check1[j] = "*" - temp.append(k) + temp.append("X") for i in range(len(binary)): if check1[i] == "$": pi.append(binary[i]) diff --git a/ciphers/shuffled_shift_cipher.py b/ciphers/shuffled_shift_cipher.py index 714acd4b1..08b2cab97 100644 --- a/ciphers/shuffled_shift_cipher.py +++ b/ciphers/shuffled_shift_cipher.py @@ -42,7 +42,7 @@ class ShuffledShiftCipher: """ :return: passcode of the cipher object """ - return "Passcode is: " + "".join(self.__passcode) + return "".join(self.__passcode) def __neg_pos(self, iterlist: list[int]) -> list[int]: """ diff --git a/computer_vision/harris_corner.py b/computer_vision/harris_corner.py index 7850085f8..c8905bb6a 100644 --- a/computer_vision/harris_corner.py +++ b/computer_vision/harris_corner.py @@ -22,8 +22,7 @@ class HarrisCorner: raise ValueError("invalid k value") def __str__(self) -> str: - - return f"Harris Corner detection with k : {self.k}" + return str(self.k) def detect(self, img_path: str) -> tuple[cv2.Mat, list[list[int]]]: diff --git a/data_structures/binary_tree/segment_tree_other.py b/data_structures/binary_tree/segment_tree_other.py index 90afd7ca8..cc77c4951 100644 --- a/data_structures/binary_tree/segment_tree_other.py +++ b/data_structures/binary_tree/segment_tree_other.py @@ -16,40 +16,36 @@ class SegmentTreeNode: self.left = left self.right = right - def __str__(self): - return f"val: {self.val}, start: {self.start}, end: {self.end}" + def __repr__(self): + return f"SegmentTreeNode(start={self.start}, end={self.end}, val={self.val})" class SegmentTree: """ >>> import operator >>> num_arr = SegmentTree([2, 1, 5, 3, 4], operator.add) - >>> for node in num_arr.traverse(): - ... print(node) - ... - val: 15, start: 0, end: 4 - val: 8, start: 0, end: 2 - val: 7, start: 3, end: 4 - val: 3, start: 0, end: 1 - val: 5, start: 2, end: 2 - val: 3, start: 3, end: 3 - val: 4, start: 4, end: 4 - val: 2, start: 0, end: 0 - val: 1, start: 1, end: 1 + >>> tuple(num_arr.traverse()) # doctest: +NORMALIZE_WHITESPACE + (SegmentTreeNode(start=0, end=4, val=15), + SegmentTreeNode(start=0, end=2, val=8), + SegmentTreeNode(start=3, end=4, val=7), + SegmentTreeNode(start=0, end=1, val=3), + SegmentTreeNode(start=2, end=2, val=5), + SegmentTreeNode(start=3, end=3, val=3), + SegmentTreeNode(start=4, end=4, val=4), + SegmentTreeNode(start=0, end=0, val=2), + SegmentTreeNode(start=1, end=1, val=1)) >>> >>> num_arr.update(1, 5) - >>> for node in num_arr.traverse(): - ... print(node) - ... - val: 19, start: 0, end: 4 - val: 12, start: 0, end: 2 - val: 7, start: 3, end: 4 - val: 7, start: 0, end: 1 - val: 5, start: 2, end: 2 - val: 3, start: 3, end: 3 - val: 4, start: 4, end: 4 - val: 2, start: 0, end: 0 - val: 5, start: 1, end: 1 + >>> tuple(num_arr.traverse()) # doctest: +NORMALIZE_WHITESPACE + (SegmentTreeNode(start=0, end=4, val=19), + SegmentTreeNode(start=0, end=2, val=12), + SegmentTreeNode(start=3, end=4, val=7), + SegmentTreeNode(start=0, end=1, val=7), + SegmentTreeNode(start=2, end=2, val=5), + SegmentTreeNode(start=3, end=3, val=3), + SegmentTreeNode(start=4, end=4, val=4), + SegmentTreeNode(start=0, end=0, val=2), + SegmentTreeNode(start=1, end=1, val=5)) >>> >>> num_arr.query_range(3, 4) 7 @@ -62,29 +58,29 @@ class SegmentTree: >>> for node in max_arr.traverse(): ... print(node) ... - val: 5, start: 0, end: 4 - val: 5, start: 0, end: 2 - val: 4, start: 3, end: 4 - val: 2, start: 0, end: 1 - val: 5, start: 2, end: 2 - val: 3, start: 3, end: 3 - val: 4, start: 4, end: 4 - val: 2, start: 0, end: 0 - val: 1, start: 1, end: 1 + SegmentTreeNode(start=0, end=4, val=5) + SegmentTreeNode(start=0, end=2, val=5) + SegmentTreeNode(start=3, end=4, val=4) + SegmentTreeNode(start=0, end=1, val=2) + SegmentTreeNode(start=2, end=2, val=5) + SegmentTreeNode(start=3, end=3, val=3) + SegmentTreeNode(start=4, end=4, val=4) + SegmentTreeNode(start=0, end=0, val=2) + SegmentTreeNode(start=1, end=1, val=1) >>> >>> max_arr.update(1, 5) >>> for node in max_arr.traverse(): ... print(node) ... - val: 5, start: 0, end: 4 - val: 5, start: 0, end: 2 - val: 4, start: 3, end: 4 - val: 5, start: 0, end: 1 - val: 5, start: 2, end: 2 - val: 3, start: 3, end: 3 - val: 4, start: 4, end: 4 - val: 2, start: 0, end: 0 - val: 5, start: 1, end: 1 + SegmentTreeNode(start=0, end=4, val=5) + SegmentTreeNode(start=0, end=2, val=5) + SegmentTreeNode(start=3, end=4, val=4) + SegmentTreeNode(start=0, end=1, val=5) + SegmentTreeNode(start=2, end=2, val=5) + SegmentTreeNode(start=3, end=3, val=3) + SegmentTreeNode(start=4, end=4, val=4) + SegmentTreeNode(start=0, end=0, val=2) + SegmentTreeNode(start=1, end=1, val=5) >>> >>> max_arr.query_range(3, 4) 4 @@ -97,29 +93,29 @@ class SegmentTree: >>> for node in min_arr.traverse(): ... print(node) ... - val: 1, start: 0, end: 4 - val: 1, start: 0, end: 2 - val: 3, start: 3, end: 4 - val: 1, start: 0, end: 1 - val: 5, start: 2, end: 2 - val: 3, start: 3, end: 3 - val: 4, start: 4, end: 4 - val: 2, start: 0, end: 0 - val: 1, start: 1, end: 1 + SegmentTreeNode(start=0, end=4, val=1) + SegmentTreeNode(start=0, end=2, val=1) + SegmentTreeNode(start=3, end=4, val=3) + SegmentTreeNode(start=0, end=1, val=1) + SegmentTreeNode(start=2, end=2, val=5) + SegmentTreeNode(start=3, end=3, val=3) + SegmentTreeNode(start=4, end=4, val=4) + SegmentTreeNode(start=0, end=0, val=2) + SegmentTreeNode(start=1, end=1, val=1) >>> >>> min_arr.update(1, 5) >>> for node in min_arr.traverse(): ... print(node) ... - val: 2, start: 0, end: 4 - val: 2, start: 0, end: 2 - val: 3, start: 3, end: 4 - val: 2, start: 0, end: 1 - val: 5, start: 2, end: 2 - val: 3, start: 3, end: 3 - val: 4, start: 4, end: 4 - val: 2, start: 0, end: 0 - val: 5, start: 1, end: 1 + SegmentTreeNode(start=0, end=4, val=2) + SegmentTreeNode(start=0, end=2, val=2) + SegmentTreeNode(start=3, end=4, val=3) + SegmentTreeNode(start=0, end=1, val=2) + SegmentTreeNode(start=2, end=2, val=5) + SegmentTreeNode(start=3, end=3, val=3) + SegmentTreeNode(start=4, end=4, val=4) + SegmentTreeNode(start=0, end=0, val=2) + SegmentTreeNode(start=1, end=1, val=5) >>> >>> min_arr.query_range(3, 4) 3 @@ -128,7 +124,6 @@ class SegmentTree: >>> min_arr.query_range(1, 3) 3 >>> - """ def __init__(self, collection: Sequence, function): diff --git a/data_structures/binary_tree/wavelet_tree.py b/data_structures/binary_tree/wavelet_tree.py index 8d7145189..041e140f5 100644 --- a/data_structures/binary_tree/wavelet_tree.py +++ b/data_structures/binary_tree/wavelet_tree.py @@ -24,11 +24,11 @@ class Node: """ >>> node = Node(length=27) >>> repr(node) - 'min_value: -1, max_value: -1' + 'Node(min_value=-1 max_value=-1)' >>> repr(node) == str(node) True """ - return f"min_value: {self.minn}, max_value: {self.maxx}" + return f"Node(min_value={self.minn} max_value={self.maxx})" def build_tree(arr: list[int]) -> Node | None: @@ -37,7 +37,7 @@ def build_tree(arr: list[int]) -> Node | None: of the constructed tree >>> build_tree(test_array) - min_value: 0, max_value: 9 + Node(min_value=0 max_value=9) """ root = Node(len(arr)) root.minn, root.maxx = min(arr), max(arr) diff --git a/data_structures/linked_list/doubly_linked_list.py b/data_structures/linked_list/doubly_linked_list.py index 90b6b6eb2..6c81493ff 100644 --- a/data_structures/linked_list/doubly_linked_list.py +++ b/data_structures/linked_list/doubly_linked_list.py @@ -159,7 +159,7 @@ class DoublyLinkedList: if current.next: current = current.next else: # We have reached the end an no value matches - return "No data matching given value" + raise ValueError("No data matching given value") if current == self.head: self.delete_head() diff --git a/data_structures/queue/double_ended_queue.py b/data_structures/queue/double_ended_queue.py index 11942db83..637b7f62f 100644 --- a/data_structures/queue/double_ended_queue.py +++ b/data_structures/queue/double_ended_queue.py @@ -425,7 +425,7 @@ class Deque: values_list.append(aux.val) aux = aux.next_node - return "[" + ", ".join(repr(val) for val in values_list) + "]" + return f"[{', '.join(repr(val) for val in values_list)}]" if __name__ == "__main__": diff --git a/graphs/breadth_first_search_shortest_path.py b/graphs/breadth_first_search_shortest_path.py index 697a8c634..cb21076f9 100644 --- a/graphs/breadth_first_search_shortest_path.py +++ b/graphs/breadth_first_search_shortest_path.py @@ -58,7 +58,9 @@ class Graph: Case 1 - No path is found. >>> g.shortest_path("Foo") - 'No path from vertex:G to vertex:Foo' + Traceback (most recent call last): + ... + ValueError: No path from vertex: G to vertex: Foo Case 2 - The path is found. >>> g.shortest_path("D") @@ -71,7 +73,9 @@ class Graph: target_vertex_parent = self.parent.get(target_vertex) if target_vertex_parent is None: - return f"No path from vertex:{self.source_vertex} to vertex:{target_vertex}" + raise ValueError( + f"No path from vertex: {self.source_vertex} to vertex: {target_vertex}" + ) return self.shortest_path(target_vertex_parent) + f"->{target_vertex}" diff --git a/graphs/page_rank.py b/graphs/page_rank.py index e1af35b34..b9e4c4a72 100644 --- a/graphs/page_rank.py +++ b/graphs/page_rank.py @@ -27,7 +27,7 @@ class Node: self.outbound.append(node) def __repr__(self): - return f"Node {self.name}: Inbound: {self.inbound} ; Outbound: {self.outbound}" + return f"" def page_rank(nodes, limit=3, d=0.85): diff --git a/linear_algebra/src/polynom_for_points.py b/linear_algebra/src/polynom_for_points.py index 1d702deb1..f5e3db0cb 100644 --- a/linear_algebra/src/polynom_for_points.py +++ b/linear_algebra/src/polynom_for_points.py @@ -4,9 +4,13 @@ def points_to_polynomial(coordinates: list[list[int]]) -> str: number of points you want to use >>> print(points_to_polynomial([])) - The program cannot work out a fitting polynomial. + Traceback (most recent call last): + ... + ValueError: The program cannot work out a fitting polynomial. >>> print(points_to_polynomial([[]])) - The program cannot work out a fitting polynomial. + Traceback (most recent call last): + ... + ValueError: The program cannot work out a fitting polynomial. >>> print(points_to_polynomial([[1, 0], [2, 0], [3, 0]])) f(x)=x^2*0.0+x^1*-0.0+x^0*0.0 >>> print(points_to_polynomial([[1, 1], [2, 1], [3, 1]])) @@ -25,17 +29,17 @@ def points_to_polynomial(coordinates: list[list[int]]) -> str: f(x)=x^2*5.0+x^1*-18.0+x^0*18.0 """ if len(coordinates) == 0 or not all(len(pair) == 2 for pair in coordinates): - return "The program cannot work out a fitting polynomial." + raise ValueError("The program cannot work out a fitting polynomial.") if len({tuple(pair) for pair in coordinates}) != len(coordinates): - return "The program cannot work out a fitting polynomial." + raise ValueError("The program cannot work out a fitting polynomial.") set_x = {x for x, _ in coordinates} if len(set_x) == 1: return f"x={coordinates[0][0]}" if len(set_x) != len(coordinates): - return "The program cannot work out a fitting polynomial." + raise ValueError("The program cannot work out a fitting polynomial.") x = len(coordinates) diff --git a/maths/monte_carlo_dice.py b/maths/monte_carlo_dice.py index c4150b88f..362f70b49 100644 --- a/maths/monte_carlo_dice.py +++ b/maths/monte_carlo_dice.py @@ -13,9 +13,6 @@ class Dice: def roll(self): return random.choice(self.sides) - def _str_(self): - return "Fair Dice" - def throw_dice(num_throws: int, num_dice: int = 2) -> list[float]: """ diff --git a/matrix/cramers_rule_2x2.py b/matrix/cramers_rule_2x2.py index a635d66fb..4f52dbe64 100644 --- a/matrix/cramers_rule_2x2.py +++ b/matrix/cramers_rule_2x2.py @@ -2,7 +2,7 @@ # https://en.wikipedia.org/wiki/Cramer%27s_rule -def cramers_rule_2x2(equation1: list[int], equation2: list[int]) -> str: +def cramers_rule_2x2(equation1: list[int], equation2: list[int]) -> tuple[float, float]: """ Solves the system of linear equation in 2 variables. :param: equation1: list of 3 numbers @@ -14,13 +14,13 @@ def cramers_rule_2x2(equation1: list[int], equation2: list[int]) -> str: determinant_y = [[a1, d1], [a2, d2]] >>> cramers_rule_2x2([2, 3, 0], [5, 1, 0]) - 'Trivial solution. (Consistent system) x = 0 and y = 0' + (0.0, 0.0) >>> cramers_rule_2x2([0, 4, 50], [2, 0, 26]) - 'Non-Trivial Solution (Consistent system) x = 13.0, y = 12.5' + (13.0, 12.5) >>> cramers_rule_2x2([11, 2, 30], [1, 0, 4]) - 'Non-Trivial Solution (Consistent system) x = 4.0, y = -7.0' + (4.0, -7.0) >>> cramers_rule_2x2([4, 7, 1], [1, 2, 0]) - 'Non-Trivial Solution (Consistent system) x = 2.0, y = -1.0' + (2.0, -1.0) >>> cramers_rule_2x2([1, 2, 3], [2, 4, 6]) Traceback (most recent call last): @@ -75,8 +75,10 @@ def cramers_rule_2x2(equation1: list[int], equation2: list[int]) -> str: raise ValueError("No solution. (Inconsistent system)") else: if determinant_x == determinant_y == 0: - return "Trivial solution. (Consistent system) x = 0 and y = 0" + # Trivial solution (Inconsistent system) + return (0.0, 0.0) else: x = determinant_x / determinant y = determinant_y / determinant - return f"Non-Trivial Solution (Consistent system) x = {x}, y = {y}" + # Non-Trivial Solution (Consistent system) + return (x, y) diff --git a/other/password.py b/other/password.py index 8f6833073..f463c7564 100644 --- a/other/password.py +++ b/other/password.py @@ -66,26 +66,23 @@ def random_characters(chars_incl, i): # This Will Check Whether A Given Password Is Strong Or Not # It Follows The Rule that Length Of Password Should Be At Least 8 Characters # And At Least 1 Lower, 1 Upper, 1 Number And 1 Special Character -def strong_password_detector(password: str, min_length: int = 8) -> str: +def is_strong_password(password: str, min_length: int = 8) -> bool: """ - >>> strong_password_detector('Hwea7$2!') - 'This is a strong Password' - - >>> strong_password_detector('Sh0r1') - 'Your Password must be at least 8 characters long' - - >>> strong_password_detector('Hello123') - 'Password should contain UPPERCASE, lowercase, numbers, special characters' - - >>> strong_password_detector('Hello1238udfhiaf038fajdvjjf!jaiuFhkqi1') - 'This is a strong Password' - - >>> strong_password_detector('0') - 'Your Password must be at least 8 characters long' + >>> is_strong_password('Hwea7$2!') + True + >>> is_strong_password('Sh0r1') + False + >>> is_strong_password('Hello123') + False + >>> is_strong_password('Hello1238udfhiaf038fajdvjjf!jaiuFhkqi1') + True + >>> is_strong_password('0') + False """ if len(password) < min_length: - return "Your Password must be at least 8 characters long" + # Your Password must be at least 8 characters long + return False upper = any(char in ascii_uppercase for char in password) lower = any(char in ascii_lowercase for char in password) @@ -93,13 +90,12 @@ def strong_password_detector(password: str, min_length: int = 8) -> str: spec_char = any(char in punctuation for char in password) if upper and lower and num and spec_char: - return "This is a strong Password" + return True else: - return ( - "Password should contain UPPERCASE, lowercase, " - "numbers, special characters" - ) + # Passwords should contain UPPERCASE, lowerase + # numbers, and special characters + return False def main(): diff --git a/strings/dna.py b/strings/dna.py index 46e271d68..c2b96110b 100644 --- a/strings/dna.py +++ b/strings/dna.py @@ -14,13 +14,18 @@ def dna(dna: str) -> str: >>> dna("CTGA") 'GACT' >>> dna("GFGG") - 'Invalid Strand' + Traceback (most recent call last): + ... + ValueError: Invalid Strand """ - r = len(re.findall("[ATCG]", dna)) != len(dna) - val = dna.translate(dna.maketrans("ATCG", "TAGC")) - return "Invalid Strand" if r else val + if len(re.findall("[ATCG]", dna)) != len(dna): + raise ValueError("Invalid Strand") + + return dna.translate(dna.maketrans("ATCG", "TAGC")) if __name__ == "__main__": - __import__("doctest").testmod() + import doctest + + doctest.testmod()