Skip to content

Commit 050d39c

Browse files
committed
2 parents dcf88f8 + 7b78487 commit 050d39c

File tree

77 files changed

+562
-295
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+562
-295
lines changed

.pre-commit-config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ repos:
1616
- id: auto-walrus
1717

1818
- repo: https://github.com/charliermarsh/ruff-pre-commit
19-
rev: v0.0.269
19+
rev: v0.0.270
2020
hooks:
2121
- id: ruff
2222

DIRECTORY.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@
294294
* [Mergesort](divide_and_conquer/mergesort.py)
295295
* [Peak](divide_and_conquer/peak.py)
296296
* [Power](divide_and_conquer/power.py)
297+
* [Strassen Matrix Multiplication](divide_and_conquer/strassen_matrix_multiplication.py)
297298

298299
## Dynamic Programming
299300
* [Abbreviation](dynamic_programming/abbreviation.py)
@@ -549,6 +550,7 @@
549550
* [Dodecahedron](maths/dodecahedron.py)
550551
* [Double Factorial Iterative](maths/double_factorial_iterative.py)
551552
* [Double Factorial Recursive](maths/double_factorial_recursive.py)
553+
* [Dual Number Automatic Differentiation](maths/dual_number_automatic_differentiation.py)
552554
* [Entropy](maths/entropy.py)
553555
* [Euclidean Distance](maths/euclidean_distance.py)
554556
* [Euclidean Gcd](maths/euclidean_gcd.py)
@@ -576,8 +578,8 @@
576578
* [Hardy Ramanujanalgo](maths/hardy_ramanujanalgo.py)
577579
* [Hexagonal Number](maths/hexagonal_number.py)
578580
* [Integration By Simpson Approx](maths/integration_by_simpson_approx.py)
581+
* [Is Int Palindrome](maths/is_int_palindrome.py)
579582
* [Is Ip V4 Address Valid](maths/is_ip_v4_address_valid.py)
580-
* [Is Palindrome](maths/is_palindrome.py)
581583
* [Is Square Free](maths/is_square_free.py)
582584
* [Jaccard Similarity](maths/jaccard_similarity.py)
583585
* [Juggler Sequence](maths/juggler_sequence.py)
@@ -1155,7 +1157,6 @@
11551157
* [Indian Phone Validator](strings/indian_phone_validator.py)
11561158
* [Is Contains Unique Chars](strings/is_contains_unique_chars.py)
11571159
* [Is Isogram](strings/is_isogram.py)
1158-
* [Is Palindrome](strings/is_palindrome.py)
11591160
* [Is Pangram](strings/is_pangram.py)
11601161
* [Is Spain National Id](strings/is_spain_national_id.py)
11611162
* [Is Srilankan Phone Number](strings/is_srilankan_phone_number.py)
@@ -1199,7 +1200,6 @@
11991200
* [Daily Horoscope](web_programming/daily_horoscope.py)
12001201
* [Download Images From Google Query](web_programming/download_images_from_google_query.py)
12011202
* [Emails From Url](web_programming/emails_from_url.py)
1202-
* [Fetch Anime And Play](web_programming/fetch_anime_and_play.py)
12031203
* [Fetch Bbc News](web_programming/fetch_bbc_news.py)
12041204
* [Fetch Github Info](web_programming/fetch_github_info.py)
12051205
* [Fetch Jobs](web_programming/fetch_jobs.py)

arithmetic_analysis/bisection.py

+14-13
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,25 @@ def bisection(function: Callable[[float], float], a: float, b: float) -> float:
2323
end: float = b
2424
if function(a) == 0: # one of the a or b is a root for the function
2525
return a
26-
elif function(b) == 0:
26+
if function(b) == 0:
2727
return b
28-
elif (
28+
if (
2929
function(a) * function(b) > 0
3030
): # if none of these are root and they are both positive or negative,
3131
# then this algorithm can't find the root
3232
raise ValueError("could not find root in given interval.")
33-
else:
34-
mid: float = start + (end - start) / 2.0
35-
while abs(start - mid) > 10**-7: # until precisely equals to 10^-7
36-
if function(mid) == 0:
37-
return mid
38-
elif function(mid) * function(start) < 0:
39-
end = mid
40-
else:
41-
start = mid
42-
mid = start + (end - start) / 2.0
43-
return mid
33+
34+
mid: float = start + (end - start) / 2.0
35+
while abs(start - mid) > 10**-7: # until precisely equals to 10^-7
36+
if function(mid) == 0:
37+
return mid
38+
39+
if function(mid) * function(start) < 0:
40+
end = mid
41+
else:
42+
start = mid
43+
mid = start + (end - start) / 2.0
44+
return mid
4445

4546

4647
def f(x: float) -> float:

arithmetic_analysis/jacobi_iteration_method.py

+19-14
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ def jacobi_iteration_method(
4949
>>> constant = np.array([[2], [-6]])
5050
>>> init_val = [0.5, -0.5, -0.5]
5151
>>> iterations = 3
52-
>>> jacobi_iteration_method(coefficient, constant, init_val, iterations)
52+
>>> jacobi_iteration_method(
53+
... coefficient, constant, init_val, iterations
54+
... ) # doctest: +NORMALIZE_WHITESPACE
5355
Traceback (most recent call last):
5456
...
5557
ValueError: Coefficient and constant matrices dimensions must be nxn and nx1 but
@@ -59,7 +61,9 @@ def jacobi_iteration_method(
5961
>>> constant = np.array([[2], [-6], [-4]])
6062
>>> init_val = [0.5, -0.5]
6163
>>> iterations = 3
62-
>>> jacobi_iteration_method(coefficient, constant, init_val, iterations)
64+
>>> jacobi_iteration_method(
65+
... coefficient, constant, init_val, iterations
66+
... ) # doctest: +NORMALIZE_WHITESPACE
6367
Traceback (most recent call last):
6468
...
6569
ValueError: Number of initial values must be equal to number of rows in coefficient
@@ -79,24 +83,26 @@ def jacobi_iteration_method(
7983
rows2, cols2 = constant_matrix.shape
8084

8185
if rows1 != cols1:
82-
raise ValueError(
83-
f"Coefficient matrix dimensions must be nxn but received {rows1}x{cols1}"
84-
)
86+
msg = f"Coefficient matrix dimensions must be nxn but received {rows1}x{cols1}"
87+
raise ValueError(msg)
8588

8689
if cols2 != 1:
87-
raise ValueError(f"Constant matrix must be nx1 but received {rows2}x{cols2}")
90+
msg = f"Constant matrix must be nx1 but received {rows2}x{cols2}"
91+
raise ValueError(msg)
8892

8993
if rows1 != rows2:
90-
raise ValueError(
91-
f"""Coefficient and constant matrices dimensions must be nxn and nx1 but
92-
received {rows1}x{cols1} and {rows2}x{cols2}"""
94+
msg = (
95+
"Coefficient and constant matrices dimensions must be nxn and nx1 but "
96+
f"received {rows1}x{cols1} and {rows2}x{cols2}"
9397
)
98+
raise ValueError(msg)
9499

95100
if len(init_val) != rows1:
96-
raise ValueError(
97-
f"""Number of initial values must be equal to number of rows in coefficient
98-
matrix but received {len(init_val)} and {rows1}"""
101+
msg = (
102+
"Number of initial values must be equal to number of rows in coefficient "
103+
f"matrix but received {len(init_val)} and {rows1}"
99104
)
105+
raise ValueError(msg)
100106

101107
if iterations <= 0:
102108
raise ValueError("Iterations must be at least 1")
@@ -151,8 +157,7 @@ def strictly_diagonally_dominant(table: NDArray[float64]) -> bool:
151157
for j in range(0, cols - 1):
152158
if i == j:
153159
continue
154-
else:
155-
total += table[i][j]
160+
total += table[i][j]
156161

157162
if table[i][i] <= total:
158163
raise ValueError("Coefficient matrix is not strictly diagonally dominant")

arithmetic_analysis/lu_decomposition.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,11 @@ def lower_upper_decomposition(table: np.ndarray) -> tuple[np.ndarray, np.ndarray
8080
# Ensure that table is a square array
8181
rows, columns = np.shape(table)
8282
if rows != columns:
83-
raise ValueError(
84-
f"'table' has to be of square shaped array but got a "
83+
msg = (
84+
"'table' has to be of square shaped array but got a "
8585
f"{rows}x{columns} array:\n{table}"
8686
)
87+
raise ValueError(msg)
8788

8889
lower = np.zeros((rows, columns))
8990
upper = np.zeros((rows, columns))

arithmetic_analysis/newton_raphson.py

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from __future__ import annotations
66

77
from decimal import Decimal
8+
9+
# Importing to allow mathematical functions in func
810
from math import * # noqa: F403
911

1012
from sympy import diff

arithmetic_analysis/newton_raphson_new.py

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
# Newton's Method - https://en.wikipedia.org/wiki/Newton's_method
99

1010
from sympy import diff, lambdify, symbols
11-
from sympy.functions import * # noqa: F403
1211

1312

1413
def newton_raphson(

audio_filters/iir_filter.py

+8-6
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,18 @@ def set_coefficients(self, a_coeffs: list[float], b_coeffs: list[float]) -> None
5050
a_coeffs = [1.0, *a_coeffs]
5151

5252
if len(a_coeffs) != self.order + 1:
53-
raise ValueError(
54-
f"Expected a_coeffs to have {self.order + 1} elements for {self.order}"
55-
f"-order filter, got {len(a_coeffs)}"
53+
msg = (
54+
f"Expected a_coeffs to have {self.order + 1} elements "
55+
f"for {self.order}-order filter, got {len(a_coeffs)}"
5656
)
57+
raise ValueError(msg)
5758

5859
if len(b_coeffs) != self.order + 1:
59-
raise ValueError(
60-
f"Expected b_coeffs to have {self.order + 1} elements for {self.order}"
61-
f"-order filter, got {len(a_coeffs)}"
60+
msg = (
61+
f"Expected b_coeffs to have {self.order + 1} elements "
62+
f"for {self.order}-order filter, got {len(a_coeffs)}"
6263
)
64+
raise ValueError(msg)
6365

6466
self.a_coeffs = a_coeffs
6567
self.b_coeffs = b_coeffs

backtracking/knight_tour.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ def open_knight_tour(n: int) -> list[list[int]]:
9191
return board
9292
board[i][j] = 0
9393

94-
raise ValueError(f"Open Kight Tour cannot be performed on a board of size {n}")
94+
msg = f"Open Kight Tour cannot be performed on a board of size {n}"
95+
raise ValueError(msg)
9596

9697

9798
if __name__ == "__main__":

bit_manipulation/reverse_bits.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ def get_reverse_bit_string(number: int) -> str:
1414
TypeError: operation can not be conducted on a object of type str
1515
"""
1616
if not isinstance(number, int):
17-
raise TypeError(
17+
msg = (
1818
"operation can not be conducted on a object of type "
1919
f"{type(number).__name__}"
2020
)
21+
raise TypeError(msg)
2122
bit_string = ""
2223
for _ in range(0, 32):
2324
bit_string += str(number % 2)

ciphers/base64.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,8 @@ def base64_encode(data: bytes) -> bytes:
3434
"""
3535
# Make sure the supplied data is a bytes-like object
3636
if not isinstance(data, bytes):
37-
raise TypeError(
38-
f"a bytes-like object is required, not '{data.__class__.__name__}'"
39-
)
37+
msg = f"a bytes-like object is required, not '{data.__class__.__name__}'"
38+
raise TypeError(msg)
4039

4140
binary_stream = "".join(bin(byte)[2:].zfill(8) for byte in data)
4241

@@ -88,10 +87,11 @@ def base64_decode(encoded_data: str) -> bytes:
8887
"""
8988
# Make sure encoded_data is either a string or a bytes-like object
9089
if not isinstance(encoded_data, bytes) and not isinstance(encoded_data, str):
91-
raise TypeError(
92-
"argument should be a bytes-like object or ASCII string, not "
93-
f"'{encoded_data.__class__.__name__}'"
90+
msg = (
91+
"argument should be a bytes-like object or ASCII string, "
92+
f"not '{encoded_data.__class__.__name__}'"
9493
)
94+
raise TypeError(msg)
9595

9696
# In case encoded_data is a bytes-like object, make sure it contains only
9797
# ASCII characters so we convert it to a string object

ciphers/beaufort_cipher.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from string import ascii_uppercase
66

77
dict1 = {char: i for i, char in enumerate(ascii_uppercase)}
8-
dict2 = {i: char for i, char in enumerate(ascii_uppercase)}
8+
dict2 = dict(enumerate(ascii_uppercase))
99

1010

1111
# This function generates the key in

ciphers/cryptomath_module.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ def gcd(a: int, b: int) -> int:
66

77
def find_mod_inverse(a: int, m: int) -> int:
88
if gcd(a, m) != 1:
9-
raise ValueError(f"mod inverse of {a!r} and {m!r} does not exist")
9+
msg = f"mod inverse of {a!r} and {m!r} does not exist"
10+
raise ValueError(msg)
1011
u1, u2, u3 = 1, 0, a
1112
v1, v2, v3 = 0, 1, m
1213
while v3 != 0:

ciphers/enigma_machine2.py

+16-14
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,20 @@ def _validator(
8787
# Checks if there are 3 unique rotors
8888

8989
if (unique_rotsel := len(set(rotsel))) < 3:
90-
raise Exception(f"Please use 3 unique rotors (not {unique_rotsel})")
90+
msg = f"Please use 3 unique rotors (not {unique_rotsel})"
91+
raise Exception(msg)
9192

9293
# Checks if rotor positions are valid
9394
rotorpos1, rotorpos2, rotorpos3 = rotpos
9495
if not 0 < rotorpos1 <= len(abc):
95-
raise ValueError(
96-
"First rotor position is not within range of 1..26 (" f"{rotorpos1}"
97-
)
96+
msg = f"First rotor position is not within range of 1..26 ({rotorpos1}"
97+
raise ValueError(msg)
9898
if not 0 < rotorpos2 <= len(abc):
99-
raise ValueError(
100-
"Second rotor position is not within range of 1..26 (" f"{rotorpos2})"
101-
)
99+
msg = f"Second rotor position is not within range of 1..26 ({rotorpos2})"
100+
raise ValueError(msg)
102101
if not 0 < rotorpos3 <= len(abc):
103-
raise ValueError(
104-
"Third rotor position is not within range of 1..26 (" f"{rotorpos3})"
105-
)
102+
msg = f"Third rotor position is not within range of 1..26 ({rotorpos3})"
103+
raise ValueError(msg)
106104

107105
# Validates string and returns dict
108106
pbdict = _plugboard(pb)
@@ -130,9 +128,11 @@ def _plugboard(pbstring: str) -> dict[str, str]:
130128
# a) is type string
131129
# b) has even length (so pairs can be made)
132130
if not isinstance(pbstring, str):
133-
raise TypeError(f"Plugboard setting isn't type string ({type(pbstring)})")
131+
msg = f"Plugboard setting isn't type string ({type(pbstring)})"
132+
raise TypeError(msg)
134133
elif len(pbstring) % 2 != 0:
135-
raise Exception(f"Odd number of symbols ({len(pbstring)})")
134+
msg = f"Odd number of symbols ({len(pbstring)})"
135+
raise Exception(msg)
136136
elif pbstring == "":
137137
return {}
138138

@@ -142,9 +142,11 @@ def _plugboard(pbstring: str) -> dict[str, str]:
142142
tmppbl = set()
143143
for i in pbstring:
144144
if i not in abc:
145-
raise Exception(f"'{i}' not in list of symbols")
145+
msg = f"'{i}' not in list of symbols"
146+
raise Exception(msg)
146147
elif i in tmppbl:
147-
raise Exception(f"Duplicate symbol ({i})")
148+
msg = f"Duplicate symbol ({i})"
149+
raise Exception(msg)
148150
else:
149151
tmppbl.add(i)
150152
del tmppbl

ciphers/hill_cipher.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,11 @@ def check_determinant(self) -> None:
104104

105105
req_l = len(self.key_string)
106106
if greatest_common_divisor(det, len(self.key_string)) != 1:
107-
raise ValueError(
108-
f"determinant modular {req_l} of encryption key({det}) is not co prime "
109-
f"w.r.t {req_l}.\nTry another key."
107+
msg = (
108+
f"determinant modular {req_l} of encryption key({det}) "
109+
f"is not co prime w.r.t {req_l}.\nTry another key."
110110
)
111+
raise ValueError(msg)
111112

112113
def process_text(self, text: str) -> str:
113114
"""

conversions/astronomical_length_scale_conversion.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,17 @@ def length_conversion(value: float, from_type: str, to_type: str) -> float:
7777
to_sanitized = UNIT_SYMBOL.get(to_sanitized, to_sanitized)
7878

7979
if from_sanitized not in METRIC_CONVERSION:
80-
raise ValueError(
80+
msg = (
8181
f"Invalid 'from_type' value: {from_type!r}.\n"
8282
f"Conversion abbreviations are: {', '.join(METRIC_CONVERSION)}"
8383
)
84+
raise ValueError(msg)
8485
if to_sanitized not in METRIC_CONVERSION:
85-
raise ValueError(
86+
msg = (
8687
f"Invalid 'to_type' value: {to_type!r}.\n"
8788
f"Conversion abbreviations are: {', '.join(METRIC_CONVERSION)}"
8889
)
90+
raise ValueError(msg)
8991
from_exponent = METRIC_CONVERSION[from_sanitized]
9092
to_exponent = METRIC_CONVERSION[to_sanitized]
9193
exponent = 1

conversions/length_conversion.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,17 @@ def length_conversion(value: float, from_type: str, to_type: str) -> float:
104104
new_to = to_type.lower().rstrip("s")
105105
new_to = TYPE_CONVERSION.get(new_to, new_to)
106106
if new_from not in METRIC_CONVERSION:
107-
raise ValueError(
107+
msg = (
108108
f"Invalid 'from_type' value: {from_type!r}.\n"
109109
f"Conversion abbreviations are: {', '.join(METRIC_CONVERSION)}"
110110
)
111+
raise ValueError(msg)
111112
if new_to not in METRIC_CONVERSION:
112-
raise ValueError(
113+
msg = (
113114
f"Invalid 'to_type' value: {to_type!r}.\n"
114115
f"Conversion abbreviations are: {', '.join(METRIC_CONVERSION)}"
115116
)
117+
raise ValueError(msg)
116118
return value * METRIC_CONVERSION[new_from].from_ * METRIC_CONVERSION[new_to].to
117119

118120

0 commit comments

Comments
 (0)