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 <cclauss@me.com>

* 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 <cclauss@me.com>

* 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 <cclauss@me.com>
This commit is contained in:
Caeden Perelli-Harris 2022-11-06 14:54:44 +00:00 committed by GitHub
parent 51708530b6
commit daa1c7529a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 123 additions and 120 deletions

View File

@ -1,15 +1,16 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Sequence 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') >>> compare_string('0010','0110')
'0_10' '0_10'
>>> compare_string('0110','1101') >>> compare_string('0110','1101')
'X' False
""" """
list1 = list(string1) list1 = list(string1)
list2 = list(string2) list2 = list(string2)
@ -19,7 +20,7 @@ def compare_string(string1: str, string2: str) -> str:
count += 1 count += 1
list1[i] = "_" list1[i] = "_"
if count > 1: if count > 1:
return "X" return False
else: else:
return "".join(list1) return "".join(list1)
@ -36,10 +37,10 @@ def check(binary: list[str]) -> list[str]:
for i in range(len(binary)): for i in range(len(binary)):
for j in range(i + 1, len(binary)): for j in range(i + 1, len(binary)):
k = compare_string(binary[i], binary[j]) k = compare_string(binary[i], binary[j])
if k != "X": if k is False:
check1[i] = "*" check1[i] = "*"
check1[j] = "*" check1[j] = "*"
temp.append(k) temp.append("X")
for i in range(len(binary)): for i in range(len(binary)):
if check1[i] == "$": if check1[i] == "$":
pi.append(binary[i]) pi.append(binary[i])

View File

@ -42,7 +42,7 @@ class ShuffledShiftCipher:
""" """
:return: passcode of the cipher object :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]: def __neg_pos(self, iterlist: list[int]) -> list[int]:
""" """

View File

@ -22,8 +22,7 @@ class HarrisCorner:
raise ValueError("invalid k value") raise ValueError("invalid k value")
def __str__(self) -> str: def __str__(self) -> str:
return str(self.k)
return f"Harris Corner detection with k : {self.k}"
def detect(self, img_path: str) -> tuple[cv2.Mat, list[list[int]]]: def detect(self, img_path: str) -> tuple[cv2.Mat, list[list[int]]]:

View File

@ -16,40 +16,36 @@ class SegmentTreeNode:
self.left = left self.left = left
self.right = right self.right = right
def __str__(self): def __repr__(self):
return f"val: {self.val}, start: {self.start}, end: {self.end}" return f"SegmentTreeNode(start={self.start}, end={self.end}, val={self.val})"
class SegmentTree: class SegmentTree:
""" """
>>> import operator >>> import operator
>>> num_arr = SegmentTree([2, 1, 5, 3, 4], operator.add) >>> num_arr = SegmentTree([2, 1, 5, 3, 4], operator.add)
>>> for node in num_arr.traverse(): >>> tuple(num_arr.traverse()) # doctest: +NORMALIZE_WHITESPACE
... print(node) (SegmentTreeNode(start=0, end=4, val=15),
... SegmentTreeNode(start=0, end=2, val=8),
val: 15, start: 0, end: 4 SegmentTreeNode(start=3, end=4, val=7),
val: 8, start: 0, end: 2 SegmentTreeNode(start=0, end=1, val=3),
val: 7, start: 3, end: 4 SegmentTreeNode(start=2, end=2, val=5),
val: 3, start: 0, end: 1 SegmentTreeNode(start=3, end=3, val=3),
val: 5, start: 2, end: 2 SegmentTreeNode(start=4, end=4, val=4),
val: 3, start: 3, end: 3 SegmentTreeNode(start=0, end=0, val=2),
val: 4, start: 4, end: 4 SegmentTreeNode(start=1, end=1, val=1))
val: 2, start: 0, end: 0
val: 1, start: 1, end: 1
>>> >>>
>>> num_arr.update(1, 5) >>> num_arr.update(1, 5)
>>> for node in num_arr.traverse(): >>> tuple(num_arr.traverse()) # doctest: +NORMALIZE_WHITESPACE
... print(node) (SegmentTreeNode(start=0, end=4, val=19),
... SegmentTreeNode(start=0, end=2, val=12),
val: 19, start: 0, end: 4 SegmentTreeNode(start=3, end=4, val=7),
val: 12, start: 0, end: 2 SegmentTreeNode(start=0, end=1, val=7),
val: 7, start: 3, end: 4 SegmentTreeNode(start=2, end=2, val=5),
val: 7, start: 0, end: 1 SegmentTreeNode(start=3, end=3, val=3),
val: 5, start: 2, end: 2 SegmentTreeNode(start=4, end=4, val=4),
val: 3, start: 3, end: 3 SegmentTreeNode(start=0, end=0, val=2),
val: 4, start: 4, end: 4 SegmentTreeNode(start=1, end=1, val=5))
val: 2, start: 0, end: 0
val: 5, start: 1, end: 1
>>> >>>
>>> num_arr.query_range(3, 4) >>> num_arr.query_range(3, 4)
7 7
@ -62,29 +58,29 @@ class SegmentTree:
>>> for node in max_arr.traverse(): >>> for node in max_arr.traverse():
... print(node) ... print(node)
... ...
val: 5, start: 0, end: 4 SegmentTreeNode(start=0, end=4, val=5)
val: 5, start: 0, end: 2 SegmentTreeNode(start=0, end=2, val=5)
val: 4, start: 3, end: 4 SegmentTreeNode(start=3, end=4, val=4)
val: 2, start: 0, end: 1 SegmentTreeNode(start=0, end=1, val=2)
val: 5, start: 2, end: 2 SegmentTreeNode(start=2, end=2, val=5)
val: 3, start: 3, end: 3 SegmentTreeNode(start=3, end=3, val=3)
val: 4, start: 4, end: 4 SegmentTreeNode(start=4, end=4, val=4)
val: 2, start: 0, end: 0 SegmentTreeNode(start=0, end=0, val=2)
val: 1, start: 1, end: 1 SegmentTreeNode(start=1, end=1, val=1)
>>> >>>
>>> max_arr.update(1, 5) >>> max_arr.update(1, 5)
>>> for node in max_arr.traverse(): >>> for node in max_arr.traverse():
... print(node) ... print(node)
... ...
val: 5, start: 0, end: 4 SegmentTreeNode(start=0, end=4, val=5)
val: 5, start: 0, end: 2 SegmentTreeNode(start=0, end=2, val=5)
val: 4, start: 3, end: 4 SegmentTreeNode(start=3, end=4, val=4)
val: 5, start: 0, end: 1 SegmentTreeNode(start=0, end=1, val=5)
val: 5, start: 2, end: 2 SegmentTreeNode(start=2, end=2, val=5)
val: 3, start: 3, end: 3 SegmentTreeNode(start=3, end=3, val=3)
val: 4, start: 4, end: 4 SegmentTreeNode(start=4, end=4, val=4)
val: 2, start: 0, end: 0 SegmentTreeNode(start=0, end=0, val=2)
val: 5, start: 1, end: 1 SegmentTreeNode(start=1, end=1, val=5)
>>> >>>
>>> max_arr.query_range(3, 4) >>> max_arr.query_range(3, 4)
4 4
@ -97,29 +93,29 @@ class SegmentTree:
>>> for node in min_arr.traverse(): >>> for node in min_arr.traverse():
... print(node) ... print(node)
... ...
val: 1, start: 0, end: 4 SegmentTreeNode(start=0, end=4, val=1)
val: 1, start: 0, end: 2 SegmentTreeNode(start=0, end=2, val=1)
val: 3, start: 3, end: 4 SegmentTreeNode(start=3, end=4, val=3)
val: 1, start: 0, end: 1 SegmentTreeNode(start=0, end=1, val=1)
val: 5, start: 2, end: 2 SegmentTreeNode(start=2, end=2, val=5)
val: 3, start: 3, end: 3 SegmentTreeNode(start=3, end=3, val=3)
val: 4, start: 4, end: 4 SegmentTreeNode(start=4, end=4, val=4)
val: 2, start: 0, end: 0 SegmentTreeNode(start=0, end=0, val=2)
val: 1, start: 1, end: 1 SegmentTreeNode(start=1, end=1, val=1)
>>> >>>
>>> min_arr.update(1, 5) >>> min_arr.update(1, 5)
>>> for node in min_arr.traverse(): >>> for node in min_arr.traverse():
... print(node) ... print(node)
... ...
val: 2, start: 0, end: 4 SegmentTreeNode(start=0, end=4, val=2)
val: 2, start: 0, end: 2 SegmentTreeNode(start=0, end=2, val=2)
val: 3, start: 3, end: 4 SegmentTreeNode(start=3, end=4, val=3)
val: 2, start: 0, end: 1 SegmentTreeNode(start=0, end=1, val=2)
val: 5, start: 2, end: 2 SegmentTreeNode(start=2, end=2, val=5)
val: 3, start: 3, end: 3 SegmentTreeNode(start=3, end=3, val=3)
val: 4, start: 4, end: 4 SegmentTreeNode(start=4, end=4, val=4)
val: 2, start: 0, end: 0 SegmentTreeNode(start=0, end=0, val=2)
val: 5, start: 1, end: 1 SegmentTreeNode(start=1, end=1, val=5)
>>> >>>
>>> min_arr.query_range(3, 4) >>> min_arr.query_range(3, 4)
3 3
@ -128,7 +124,6 @@ class SegmentTree:
>>> min_arr.query_range(1, 3) >>> min_arr.query_range(1, 3)
3 3
>>> >>>
""" """
def __init__(self, collection: Sequence, function): def __init__(self, collection: Sequence, function):

View File

@ -24,11 +24,11 @@ class Node:
""" """
>>> node = Node(length=27) >>> node = Node(length=27)
>>> repr(node) >>> repr(node)
'min_value: -1, max_value: -1' 'Node(min_value=-1 max_value=-1)'
>>> repr(node) == str(node) >>> repr(node) == str(node)
True 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: def build_tree(arr: list[int]) -> Node | None:
@ -37,7 +37,7 @@ def build_tree(arr: list[int]) -> Node | None:
of the constructed tree of the constructed tree
>>> build_tree(test_array) >>> build_tree(test_array)
min_value: 0, max_value: 9 Node(min_value=0 max_value=9)
""" """
root = Node(len(arr)) root = Node(len(arr))
root.minn, root.maxx = min(arr), max(arr) root.minn, root.maxx = min(arr), max(arr)

View File

@ -159,7 +159,7 @@ class DoublyLinkedList:
if current.next: if current.next:
current = current.next current = current.next
else: # We have reached the end an no value matches 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: if current == self.head:
self.delete_head() self.delete_head()

View File

@ -425,7 +425,7 @@ class Deque:
values_list.append(aux.val) values_list.append(aux.val)
aux = aux.next_node 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__": if __name__ == "__main__":

View File

@ -58,7 +58,9 @@ class Graph:
Case 1 - No path is found. Case 1 - No path is found.
>>> g.shortest_path("Foo") >>> 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. Case 2 - The path is found.
>>> g.shortest_path("D") >>> g.shortest_path("D")
@ -71,7 +73,9 @@ class Graph:
target_vertex_parent = self.parent.get(target_vertex) target_vertex_parent = self.parent.get(target_vertex)
if target_vertex_parent is None: 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}" return self.shortest_path(target_vertex_parent) + f"->{target_vertex}"

View File

@ -27,7 +27,7 @@ class Node:
self.outbound.append(node) self.outbound.append(node)
def __repr__(self): def __repr__(self):
return f"Node {self.name}: Inbound: {self.inbound} ; Outbound: {self.outbound}" return f"<node={self.name} inbound={self.inbound} outbound={self.outbound}>"
def page_rank(nodes, limit=3, d=0.85): def page_rank(nodes, limit=3, d=0.85):

View File

@ -4,9 +4,13 @@ def points_to_polynomial(coordinates: list[list[int]]) -> str:
number of points you want to use number of points you want to use
>>> print(points_to_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([[]])) >>> 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]])) >>> print(points_to_polynomial([[1, 0], [2, 0], [3, 0]]))
f(x)=x^2*0.0+x^1*-0.0+x^0*0.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]])) >>> 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 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): 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): 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} set_x = {x for x, _ in coordinates}
if len(set_x) == 1: if len(set_x) == 1:
return f"x={coordinates[0][0]}" return f"x={coordinates[0][0]}"
if len(set_x) != len(coordinates): 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) x = len(coordinates)

View File

@ -13,9 +13,6 @@ class Dice:
def roll(self): def roll(self):
return random.choice(self.sides) return random.choice(self.sides)
def _str_(self):
return "Fair Dice"
def throw_dice(num_throws: int, num_dice: int = 2) -> list[float]: def throw_dice(num_throws: int, num_dice: int = 2) -> list[float]:
""" """

View File

@ -2,7 +2,7 @@
# https://en.wikipedia.org/wiki/Cramer%27s_rule # 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. Solves the system of linear equation in 2 variables.
:param: equation1: list of 3 numbers :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]] determinant_y = [[a1, d1], [a2, d2]]
>>> cramers_rule_2x2([2, 3, 0], [5, 1, 0]) >>> 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]) >>> 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]) >>> 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]) >>> 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]) >>> cramers_rule_2x2([1, 2, 3], [2, 4, 6])
Traceback (most recent call last): 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)") raise ValueError("No solution. (Inconsistent system)")
else: else:
if determinant_x == determinant_y == 0: 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: else:
x = determinant_x / determinant x = determinant_x / determinant
y = determinant_y / determinant y = determinant_y / determinant
return f"Non-Trivial Solution (Consistent system) x = {x}, y = {y}" # Non-Trivial Solution (Consistent system)
return (x, y)

View File

@ -66,26 +66,23 @@ def random_characters(chars_incl, i):
# This Will Check Whether A Given Password Is Strong Or Not # 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 # 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 # 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!') >>> is_strong_password('Hwea7$2!')
'This is a strong Password' True
>>> is_strong_password('Sh0r1')
>>> strong_password_detector('Sh0r1') False
'Your Password must be at least 8 characters long' >>> is_strong_password('Hello123')
False
>>> strong_password_detector('Hello123') >>> is_strong_password('Hello1238udfhiaf038fajdvjjf!jaiuFhkqi1')
'Password should contain UPPERCASE, lowercase, numbers, special characters' True
>>> is_strong_password('0')
>>> strong_password_detector('Hello1238udfhiaf038fajdvjjf!jaiuFhkqi1') False
'This is a strong Password'
>>> strong_password_detector('0')
'Your Password must be at least 8 characters long'
""" """
if len(password) < min_length: 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) upper = any(char in ascii_uppercase for char in password)
lower = any(char in ascii_lowercase 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) spec_char = any(char in punctuation for char in password)
if upper and lower and num and spec_char: if upper and lower and num and spec_char:
return "This is a strong Password" return True
else: else:
return ( # Passwords should contain UPPERCASE, lowerase
"Password should contain UPPERCASE, lowercase, " # numbers, and special characters
"numbers, special characters" return False
)
def main(): def main():

View File

@ -14,13 +14,18 @@ def dna(dna: str) -> str:
>>> dna("CTGA") >>> dna("CTGA")
'GACT' 'GACT'
>>> dna("GFGG") >>> dna("GFGG")
'Invalid Strand' Traceback (most recent call last):
...
ValueError: Invalid Strand
""" """
r = len(re.findall("[ATCG]", dna)) != len(dna) if len(re.findall("[ATCG]", dna)) != len(dna):
val = dna.translate(dna.maketrans("ATCG", "TAGC")) raise ValueError("Invalid Strand")
return "Invalid Strand" if r else val
return dna.translate(dna.maketrans("ATCG", "TAGC"))
if __name__ == "__main__": if __name__ == "__main__":
__import__("doctest").testmod() import doctest
doctest.testmod()