Skip to content

Commit 859aa3d

Browse files
committed
2 parents 148d4c9 + 5c276a8 commit 859aa3d

23 files changed

+426
-336
lines changed

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ repos:
1616
- id: auto-walrus
1717

1818
- repo: https://github.com/astral-sh/ruff-pre-commit
19-
rev: v0.0.282
19+
rev: v0.0.284
2020
hooks:
2121
- id: ruff
2222

@@ -33,7 +33,7 @@ repos:
3333
- tomli
3434

3535
- repo: https://github.com/tox-dev/pyproject-fmt
36-
rev: "0.13.0"
36+
rev: "0.13.1"
3737
hooks:
3838
- id: pyproject-fmt
3939

@@ -51,7 +51,7 @@ repos:
5151
- id: validate-pyproject
5252

5353
- repo: https://github.com/pre-commit/mirrors-mypy
54-
rev: v1.4.1
54+
rev: v1.5.0
5555
hooks:
5656
- id: mypy
5757
args:

DIRECTORY.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@
555555
* [Chudnovsky Algorithm](maths/chudnovsky_algorithm.py)
556556
* [Collatz Sequence](maths/collatz_sequence.py)
557557
* [Combinations](maths/combinations.py)
558+
* [Continued Fraction](maths/continued_fraction.py)
558559
* [Decimal Isolate](maths/decimal_isolate.py)
559560
* [Decimal To Fraction](maths/decimal_to_fraction.py)
560561
* [Dodecahedron](maths/dodecahedron.py)
@@ -573,9 +574,7 @@
573574
* [Fermat Little Theorem](maths/fermat_little_theorem.py)
574575
* [Fibonacci](maths/fibonacci.py)
575576
* [Find Max](maths/find_max.py)
576-
* [Find Max Recursion](maths/find_max_recursion.py)
577577
* [Find Min](maths/find_min.py)
578-
* [Find Min Recursion](maths/find_min_recursion.py)
579578
* [Floor](maths/floor.py)
580579
* [Gamma](maths/gamma.py)
581580
* [Gamma Recursive](maths/gamma_recursive.py)

boolean_algebra/quine_mc_cluskey.py

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,7 @@ def is_for_table(string1: str, string2: str, count: int) -> bool:
7474
"""
7575
list1 = list(string1)
7676
list2 = list(string2)
77-
count_n = 0
78-
for i in range(len(list1)):
79-
if list1[i] != list2[i]:
80-
count_n += 1
77+
count_n = sum(item1 != item2 for item1, item2 in zip(list1, list2))
8178
return count_n == count
8279

8380

@@ -92,40 +89,34 @@ def selection(chart: list[list[int]], prime_implicants: list[str]) -> list[str]:
9289
temp = []
9390
select = [0] * len(chart)
9491
for i in range(len(chart[0])):
95-
count = 0
96-
rem = -1
97-
for j in range(len(chart)):
98-
if chart[j][i] == 1:
99-
count += 1
100-
rem = j
92+
count = sum(row[i] == 1 for row in chart)
10193
if count == 1:
94+
rem = max(j for j, row in enumerate(chart) if row[i] == 1)
10295
select[rem] = 1
103-
for i in range(len(select)):
104-
if select[i] == 1:
105-
for j in range(len(chart[0])):
106-
if chart[i][j] == 1:
107-
for k in range(len(chart)):
108-
chart[k][j] = 0
109-
temp.append(prime_implicants[i])
96+
for i, item in enumerate(select):
97+
if item != 1:
98+
continue
99+
for j in range(len(chart[0])):
100+
if chart[i][j] != 1:
101+
continue
102+
for row in chart:
103+
row[j] = 0
104+
temp.append(prime_implicants[i])
110105
while True:
111-
max_n = 0
112-
rem = -1
113-
count_n = 0
114-
for i in range(len(chart)):
115-
count_n = chart[i].count(1)
116-
if count_n > max_n:
117-
max_n = count_n
118-
rem = i
106+
counts = [chart[i].count(1) for i in range(len(chart))]
107+
max_n = max(counts)
108+
rem = counts.index(max_n)
119109

120110
if max_n == 0:
121111
return temp
122112

123113
temp.append(prime_implicants[rem])
124114

125-
for i in range(len(chart[0])):
126-
if chart[rem][i] == 1:
127-
for j in range(len(chart)):
128-
chart[j][i] = 0
115+
for j in range(len(chart[0])):
116+
if chart[rem][j] != 1:
117+
continue
118+
for i in range(len(chart)):
119+
chart[i][j] = 0
129120

130121

131122
def prime_implicant_chart(

ciphers/rsa_key_generator.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
import random
33
import sys
44

5-
from . import cryptomath_module as cryptoMath # noqa: N812
6-
from . import rabin_miller as rabinMiller # noqa: N812
5+
from . import cryptomath_module, rabin_miller
76

87

98
def main() -> None:
@@ -13,20 +12,26 @@ def main() -> None:
1312

1413

1514
def generate_key(key_size: int) -> tuple[tuple[int, int], tuple[int, int]]:
16-
print("Generating prime p...")
17-
p = rabinMiller.generate_large_prime(key_size)
18-
print("Generating prime q...")
19-
q = rabinMiller.generate_large_prime(key_size)
15+
"""
16+
>>> random.seed(0) # for repeatability
17+
>>> public_key, private_key = generate_key(8)
18+
>>> public_key
19+
(26569, 239)
20+
>>> private_key
21+
(26569, 2855)
22+
"""
23+
p = rabin_miller.generate_large_prime(key_size)
24+
q = rabin_miller.generate_large_prime(key_size)
2025
n = p * q
2126

22-
print("Generating e that is relatively prime to (p - 1) * (q - 1)...")
27+
# Generate e that is relatively prime to (p - 1) * (q - 1)
2328
while True:
2429
e = random.randrange(2 ** (key_size - 1), 2 ** (key_size))
25-
if cryptoMath.gcd(e, (p - 1) * (q - 1)) == 1:
30+
if cryptomath_module.gcd(e, (p - 1) * (q - 1)) == 1:
2631
break
2732

28-
print("Calculating d that is mod inverse of e...")
29-
d = cryptoMath.find_mod_inverse(e, (p - 1) * (q - 1))
33+
# Calculate d that is mod inverse of e
34+
d = cryptomath_module.find_mod_inverse(e, (p - 1) * (q - 1))
3035

3136
public_key = (n, e)
3237
private_key = (n, d)

computer_vision/flip_augmentation.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ def main() -> None:
3232
letter_code = random_chars(32)
3333
file_name = paths[index].split(os.sep)[-1].rsplit(".", 1)[0]
3434
file_root = f"{OUTPUT_DIR}/{file_name}_FLIP_{letter_code}"
35-
cv2.imwrite(f"/{file_root}.jpg", image, [cv2.IMWRITE_JPEG_QUALITY, 85])
35+
cv2.imwrite(f"{file_root}.jpg", image, [cv2.IMWRITE_JPEG_QUALITY, 85])
3636
print(f"Success {index+1}/{len(new_images)} with {file_name}")
3737
annos_list = []
3838
for anno in new_annos[index]:
3939
obj = f"{anno[0]} {anno[1]} {anno[2]} {anno[3]} {anno[4]}"
4040
annos_list.append(obj)
41-
with open(f"/{file_root}.txt", "w") as outfile:
41+
with open(f"{file_root}.txt", "w") as outfile:
4242
outfile.write("\n".join(line for line in annos_list))
4343

4444

data_structures/binary_tree/binary_search_tree.py

Lines changed: 83 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,62 @@
1-
"""
1+
r"""
22
A binary search Tree
3+
4+
Example
5+
8
6+
/ \
7+
3 10
8+
/ \ \
9+
1 6 14
10+
/ \ /
11+
4 7 13
12+
13+
>>> t = BinarySearchTree()
14+
>>> t.insert(8, 3, 6, 1, 10, 14, 13, 4, 7)
15+
>>> print(" ".join(repr(i.value) for i in t.traversal_tree()))
16+
8 3 1 6 4 7 10 14 13
17+
>>> print(" ".join(repr(i.value) for i in t.traversal_tree(postorder)))
18+
1 4 7 6 3 13 14 10 8
19+
>>> t.remove(20)
20+
Traceback (most recent call last):
21+
...
22+
ValueError: Value 20 not found
23+
>>> BinarySearchTree().search(6)
24+
Traceback (most recent call last):
25+
...
26+
IndexError: Warning: Tree is empty! please use another.
27+
28+
Other example:
29+
30+
>>> testlist = (8, 3, 6, 1, 10, 14, 13, 4, 7)
31+
>>> t = BinarySearchTree()
32+
>>> for i in testlist:
33+
... t.insert(i)
34+
35+
Prints all the elements of the list in order traversal
36+
>>> print(t)
37+
{'8': ({'3': (1, {'6': (4, 7)})}, {'10': (None, {'14': (13, None)})})}
38+
39+
Test existence
40+
>>> t.search(6) is not None
41+
True
42+
>>> t.search(-1) is not None
43+
False
44+
45+
>>> t.search(6).is_right
46+
True
47+
>>> t.search(1).is_right
48+
False
49+
50+
>>> t.get_max().value
51+
14
52+
>>> t.get_min().value
53+
1
54+
>>> t.empty()
55+
False
56+
>>> for i in testlist:
57+
... t.remove(i)
58+
>>> t.empty()
59+
True
360
"""
461

562
from collections.abc import Iterable
@@ -20,6 +77,10 @@ def __repr__(self) -> str:
2077
return str(self.value)
2178
return pformat({f"{self.value}": (self.left, self.right)}, indent=1)
2279

80+
@property
81+
def is_right(self) -> bool:
82+
return self.parent is not None and self is self.parent.right
83+
2384

2485
class BinarySearchTree:
2586
def __init__(self, root: Node | None = None):
@@ -35,18 +96,13 @@ def __reassign_nodes(self, node: Node, new_children: Node | None) -> None:
3596
if new_children is not None: # reset its kids
3697
new_children.parent = node.parent
3798
if node.parent is not None: # reset its parent
38-
if self.is_right(node): # If it is the right children
99+
if node.is_right: # If it is the right child
39100
node.parent.right = new_children
40101
else:
41102
node.parent.left = new_children
42103
else:
43104
self.root = new_children
44105

45-
def is_right(self, node: Node) -> bool:
46-
if node.parent and node.parent.right:
47-
return node == node.parent.right
48-
return False
49-
50106
def empty(self) -> bool:
51107
return self.root is None
52108

@@ -119,22 +175,26 @@ def get_min(self, node: Node | None = None) -> Node | None:
119175
return node
120176

121177
def remove(self, value: int) -> None:
122-
node = self.search(value) # Look for the node with that label
123-
if node is not None:
124-
if node.left is None and node.right is None: # If it has no children
125-
self.__reassign_nodes(node, None)
126-
elif node.left is None: # Has only right children
127-
self.__reassign_nodes(node, node.right)
128-
elif node.right is None: # Has only left children
129-
self.__reassign_nodes(node, node.left)
130-
else:
131-
tmp_node = self.get_max(
132-
node.left
133-
) # Gets the max value of the left branch
134-
self.remove(tmp_node.value) # type: ignore
135-
node.value = (
136-
tmp_node.value # type: ignore
137-
) # Assigns the value to the node to delete and keep tree structure
178+
# Look for the node with that label
179+
node = self.search(value)
180+
if node is None:
181+
msg = f"Value {value} not found"
182+
raise ValueError(msg)
183+
184+
if node.left is None and node.right is None: # If it has no children
185+
self.__reassign_nodes(node, None)
186+
elif node.left is None: # Has only right children
187+
self.__reassign_nodes(node, node.right)
188+
elif node.right is None: # Has only left children
189+
self.__reassign_nodes(node, node.left)
190+
else:
191+
predecessor = self.get_max(
192+
node.left
193+
) # Gets the max value of the left branch
194+
self.remove(predecessor.value) # type: ignore
195+
node.value = (
196+
predecessor.value # type: ignore
197+
) # Assigns the value to the node to delete and keep tree structure
138198

139199
def preorder_traverse(self, node: Node | None) -> Iterable:
140200
if node is not None:
@@ -177,55 +237,6 @@ def postorder(curr_node: Node | None) -> list[Node]:
177237
return node_list
178238

179239

180-
def binary_search_tree() -> None:
181-
r"""
182-
Example
183-
8
184-
/ \
185-
3 10
186-
/ \ \
187-
1 6 14
188-
/ \ /
189-
4 7 13
190-
191-
>>> t = BinarySearchTree()
192-
>>> t.insert(8, 3, 6, 1, 10, 14, 13, 4, 7)
193-
>>> print(" ".join(repr(i.value) for i in t.traversal_tree()))
194-
8 3 1 6 4 7 10 14 13
195-
>>> print(" ".join(repr(i.value) for i in t.traversal_tree(postorder)))
196-
1 4 7 6 3 13 14 10 8
197-
>>> BinarySearchTree().search(6)
198-
Traceback (most recent call last):
199-
...
200-
IndexError: Warning: Tree is empty! please use another.
201-
"""
202-
testlist = (8, 3, 6, 1, 10, 14, 13, 4, 7)
203-
t = BinarySearchTree()
204-
for i in testlist:
205-
t.insert(i)
206-
207-
# Prints all the elements of the list in order traversal
208-
print(t)
209-
210-
if t.search(6) is not None:
211-
print("The value 6 exists")
212-
else:
213-
print("The value 6 doesn't exist")
214-
215-
if t.search(-1) is not None:
216-
print("The value -1 exists")
217-
else:
218-
print("The value -1 doesn't exist")
219-
220-
if not t.empty():
221-
print("Max Value: ", t.get_max().value) # type: ignore
222-
print("Min Value: ", t.get_min().value) # type: ignore
223-
224-
for i in testlist:
225-
t.remove(i)
226-
print(t)
227-
228-
229240
if __name__ == "__main__":
230241
import doctest
231242

digital_image_processing/morphological_operations/erosion_operation.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def rgb2gray(rgb: np.array) -> np.array:
2121
def gray2binary(gray: np.array) -> np.array:
2222
"""
2323
Return binary image from gray image
24+
2425
>>> gray2binary(np.array([[127, 255, 0]]))
2526
array([[False, True, False]])
2627
>>> gray2binary(np.array([[0]]))

digital_image_processing/rotation/rotation.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ def get_rotation(
1010
) -> np.ndarray:
1111
"""
1212
Get image rotation
13-
:param img: np.array
13+
:param img: np.ndarray
1414
:param pt1: 3x2 list
1515
:param pt2: 3x2 list
1616
:param rows: columns image shape
1717
:param cols: rows image shape
18-
:return: np.array
18+
:return: np.ndarray
1919
"""
2020
matrix = cv2.getAffineTransform(pt1, pt2)
2121
return cv2.warpAffine(img, matrix, (rows, cols))

0 commit comments

Comments
 (0)