Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3f094fe

Browse files
cclaussgithub-actions
and
github-actions
authoredOct 11, 2023
Ruff pandas vet (TheAlgorithms#10281)
* Python linting: Add ruff rules for Pandas-vet and Pytest-style * updating DIRECTORY.md --------- Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
1 parent d5323db commit 3f094fe

28 files changed

+260
-241
lines changed
 

‎.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ repos:
5151
- id: validate-pyproject
5252

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

‎DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@
532532
* [Logistic Regression](machine_learning/logistic_regression.py)
533533
* Loss Functions
534534
* [Binary Cross Entropy](machine_learning/loss_functions/binary_cross_entropy.py)
535+
* [Categorical Cross Entropy](machine_learning/loss_functions/categorical_cross_entropy.py)
535536
* [Huber Loss](machine_learning/loss_functions/huber_loss.py)
536537
* [Mean Squared Error](machine_learning/loss_functions/mean_squared_error.py)
537538
* [Mfcc](machine_learning/mfcc.py)

‎blockchain/diophantine_equation.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
8383
(1, -2, 3)
8484
8585
"""
86-
assert a >= 0 and b >= 0
86+
assert a >= 0
87+
assert b >= 0
8788

8889
if b == 0:
8990
d, x, y = a, 1, 0
@@ -92,7 +93,8 @@ def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
9293
x = q
9394
y = p - q * (a // b)
9495

95-
assert a % d == 0 and b % d == 0
96+
assert a % d == 0
97+
assert b % d == 0
9698
assert d == a * x + b * y
9799

98100
return (d, x, y)

‎ciphers/xor_cipher.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ def encrypt(self, content: str, key: int) -> list[str]:
3838
"""
3939

4040
# precondition
41-
assert isinstance(key, int) and isinstance(content, str)
41+
assert isinstance(key, int)
42+
assert isinstance(content, str)
4243

4344
key = key or self.__key or 1
4445

@@ -56,7 +57,8 @@ def decrypt(self, content: str, key: int) -> list[str]:
5657
"""
5758

5859
# precondition
59-
assert isinstance(key, int) and isinstance(content, list)
60+
assert isinstance(key, int)
61+
assert isinstance(content, list)
6062

6163
key = key or self.__key or 1
6264

@@ -74,7 +76,8 @@ def encrypt_string(self, content: str, key: int = 0) -> str:
7476
"""
7577

7678
# precondition
77-
assert isinstance(key, int) and isinstance(content, str)
79+
assert isinstance(key, int)
80+
assert isinstance(content, str)
7881

7982
key = key or self.__key or 1
8083

@@ -99,7 +102,8 @@ def decrypt_string(self, content: str, key: int = 0) -> str:
99102
"""
100103

101104
# precondition
102-
assert isinstance(key, int) and isinstance(content, str)
105+
assert isinstance(key, int)
106+
assert isinstance(content, str)
103107

104108
key = key or self.__key or 1
105109

@@ -125,7 +129,8 @@ def encrypt_file(self, file: str, key: int = 0) -> bool:
125129
"""
126130

127131
# precondition
128-
assert isinstance(file, str) and isinstance(key, int)
132+
assert isinstance(file, str)
133+
assert isinstance(key, int)
129134

130135
try:
131136
with open(file) as fin, open("encrypt.out", "w+") as fout:
@@ -148,7 +153,8 @@ def decrypt_file(self, file: str, key: int) -> bool:
148153
"""
149154

150155
# precondition
151-
assert isinstance(file, str) and isinstance(key, int)
156+
assert isinstance(file, str)
157+
assert isinstance(key, int)
152158

153159
try:
154160
with open(file) as fin, open("decrypt.out", "w+") as fout:

‎conversions/decimal_to_hexadecimal.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ def decimal_to_hexadecimal(decimal: float) -> str:
5757
>>> decimal_to_hexadecimal(-256) == hex(-256)
5858
True
5959
"""
60-
assert type(decimal) in (int, float) and decimal == int(decimal)
60+
assert isinstance(decimal, (int, float))
61+
assert decimal == int(decimal)
6162
decimal = int(decimal)
6263
hexadecimal = ""
6364
negative = False

‎data_structures/binary_tree/binary_search_tree_recursive.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import unittest
1313
from collections.abc import Iterator
1414

15+
import pytest
16+
1517

1618
class Node:
1719
def __init__(self, label: int, parent: Node | None) -> None:
@@ -78,7 +80,7 @@ def _put(self, node: Node | None, label: int, parent: Node | None = None) -> Nod
7880
node.right = self._put(node.right, label, node)
7981
else:
8082
msg = f"Node with label {label} already exists"
81-
raise Exception(msg)
83+
raise ValueError(msg)
8284

8385
return node
8486

@@ -95,14 +97,14 @@ def search(self, label: int) -> Node:
9597
>>> node = t.search(3)
9698
Traceback (most recent call last):
9799
...
98-
Exception: Node with label 3 does not exist
100+
ValueError: Node with label 3 does not exist
99101
"""
100102
return self._search(self.root, label)
101103

102104
def _search(self, node: Node | None, label: int) -> Node:
103105
if node is None:
104106
msg = f"Node with label {label} does not exist"
105-
raise Exception(msg)
107+
raise ValueError(msg)
106108
else:
107109
if label < node.label:
108110
node = self._search(node.left, label)
@@ -124,7 +126,7 @@ def remove(self, label: int) -> None:
124126
>>> t.remove(3)
125127
Traceback (most recent call last):
126128
...
127-
Exception: Node with label 3 does not exist
129+
ValueError: Node with label 3 does not exist
128130
"""
129131
node = self.search(label)
130132
if node.right and node.left:
@@ -179,7 +181,7 @@ def exists(self, label: int) -> bool:
179181
try:
180182
self.search(label)
181183
return True
182-
except Exception:
184+
except ValueError:
183185
return False
184186

185187
def get_max_label(self) -> int:
@@ -190,15 +192,15 @@ def get_max_label(self) -> int:
190192
>>> t.get_max_label()
191193
Traceback (most recent call last):
192194
...
193-
Exception: Binary search tree is empty
195+
ValueError: Binary search tree is empty
194196
195197
>>> t.put(8)
196198
>>> t.put(10)
197199
>>> t.get_max_label()
198200
10
199201
"""
200202
if self.root is None:
201-
raise Exception("Binary search tree is empty")
203+
raise ValueError("Binary search tree is empty")
202204

203205
node = self.root
204206
while node.right is not None:
@@ -214,15 +216,15 @@ def get_min_label(self) -> int:
214216
>>> t.get_min_label()
215217
Traceback (most recent call last):
216218
...
217-
Exception: Binary search tree is empty
219+
ValueError: Binary search tree is empty
218220
219221
>>> t.put(8)
220222
>>> t.put(10)
221223
>>> t.get_min_label()
222224
8
223225
"""
224226
if self.root is None:
225-
raise Exception("Binary search tree is empty")
227+
raise ValueError("Binary search tree is empty")
226228

227229
node = self.root
228230
while node.left is not None:
@@ -359,7 +361,7 @@ def test_put(self) -> None:
359361
assert t.root.left.left.parent == t.root.left
360362
assert t.root.left.left.label == 1
361363

362-
with self.assertRaises(Exception): # noqa: B017
364+
with pytest.raises(ValueError):
363365
t.put(1)
364366

365367
def test_search(self) -> None:
@@ -371,7 +373,7 @@ def test_search(self) -> None:
371373
node = t.search(13)
372374
assert node.label == 13
373375

374-
with self.assertRaises(Exception): # noqa: B017
376+
with pytest.raises(ValueError):
375377
t.search(2)
376378

377379
def test_remove(self) -> None:
@@ -517,7 +519,7 @@ def test_get_max_label(self) -> None:
517519
assert t.get_max_label() == 14
518520

519521
t.empty()
520-
with self.assertRaises(Exception): # noqa: B017
522+
with pytest.raises(ValueError):
521523
t.get_max_label()
522524

523525
def test_get_min_label(self) -> None:
@@ -526,7 +528,7 @@ def test_get_min_label(self) -> None:
526528
assert t.get_min_label() == 1
527529

528530
t.empty()
529-
with self.assertRaises(Exception): # noqa: B017
531+
with pytest.raises(ValueError):
530532
t.get_min_label()
531533

532534
def test_inorder_traversal(self) -> None:

‎data_structures/hashing/tests/test_hash_map.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,14 @@ def _run_operation(obj, fun, *args):
6565

6666
@pytest.mark.parametrize(
6767
"operations",
68-
(
68+
[
6969
pytest.param(_add_items, id="add items"),
7070
pytest.param(_overwrite_items, id="overwrite items"),
7171
pytest.param(_delete_items, id="delete items"),
7272
pytest.param(_access_absent_items, id="access absent items"),
7373
pytest.param(_add_with_resize_up, id="add with resize up"),
7474
pytest.param(_add_with_resize_down, id="add with resize down"),
75-
),
75+
],
7676
)
7777
def test_hash_map_is_the_same_as_dict(operations):
7878
my = HashMap(initial_block_size=4)

‎data_structures/linked_list/circular_linked_list.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ def delete_nth(self, index: int = 0) -> Any:
124124
if not 0 <= index < len(self):
125125
raise IndexError("list index out of range.")
126126

127-
assert self.head is not None and self.tail is not None
127+
assert self.head is not None
128+
assert self.tail is not None
128129
delete_node: Node = self.head
129130
if self.head == self.tail: # Just one node
130131
self.head = self.tail = None
@@ -137,7 +138,8 @@ def delete_nth(self, index: int = 0) -> Any:
137138
for _ in range(index - 1):
138139
assert temp is not None
139140
temp = temp.next
140-
assert temp is not None and temp.next is not None
141+
assert temp is not None
142+
assert temp.next is not None
141143
delete_node = temp.next
142144
temp.next = temp.next.next
143145
if index == len(self) - 1: # Delete at tail

‎digital_image_processing/test_digital_image_processing.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ def test_median_filter():
7373

7474
def test_sobel_filter():
7575
grad, theta = sob.sobel_filter(gray)
76-
assert grad.any() and theta.any()
76+
assert grad.any()
77+
assert theta.any()
7778

7879

7980
def test_sepia():

‎graphs/graph_adjacency_list.py

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
from pprint import pformat
2323
from typing import Generic, TypeVar
2424

25+
import pytest
26+
2527
T = TypeVar("T")
2628

2729

@@ -185,42 +187,42 @@ def __assert_graph_edge_exists_check(
185187
directed_graph: GraphAdjacencyList,
186188
edge: list[int],
187189
) -> None:
188-
self.assertTrue(undirected_graph.contains_edge(edge[0], edge[1]))
189-
self.assertTrue(undirected_graph.contains_edge(edge[1], edge[0]))
190-
self.assertTrue(directed_graph.contains_edge(edge[0], edge[1]))
190+
assert undirected_graph.contains_edge(edge[0], edge[1])
191+
assert undirected_graph.contains_edge(edge[1], edge[0])
192+
assert directed_graph.contains_edge(edge[0], edge[1])
191193

192194
def __assert_graph_edge_does_not_exist_check(
193195
self,
194196
undirected_graph: GraphAdjacencyList,
195197
directed_graph: GraphAdjacencyList,
196198
edge: list[int],
197199
) -> None:
198-
self.assertFalse(undirected_graph.contains_edge(edge[0], edge[1]))
199-
self.assertFalse(undirected_graph.contains_edge(edge[1], edge[0]))
200-
self.assertFalse(directed_graph.contains_edge(edge[0], edge[1]))
200+
assert not undirected_graph.contains_edge(edge[0], edge[1])
201+
assert not undirected_graph.contains_edge(edge[1], edge[0])
202+
assert not directed_graph.contains_edge(edge[0], edge[1])
201203

202204
def __assert_graph_vertex_exists_check(
203205
self,
204206
undirected_graph: GraphAdjacencyList,
205207
directed_graph: GraphAdjacencyList,
206208
vertex: int,
207209
) -> None:
208-
self.assertTrue(undirected_graph.contains_vertex(vertex))
209-
self.assertTrue(directed_graph.contains_vertex(vertex))
210+
assert undirected_graph.contains_vertex(vertex)
211+
assert directed_graph.contains_vertex(vertex)
210212

211213
def __assert_graph_vertex_does_not_exist_check(
212214
self,
213215
undirected_graph: GraphAdjacencyList,
214216
directed_graph: GraphAdjacencyList,
215217
vertex: int,
216218
) -> None:
217-
self.assertFalse(undirected_graph.contains_vertex(vertex))
218-
self.assertFalse(directed_graph.contains_vertex(vertex))
219+
assert not undirected_graph.contains_vertex(vertex)
220+
assert not directed_graph.contains_vertex(vertex)
219221

220222
def __generate_random_edges(
221223
self, vertices: list[int], edge_pick_count: int
222224
) -> list[list[int]]:
223-
self.assertTrue(edge_pick_count <= len(vertices))
225+
assert edge_pick_count <= len(vertices)
224226

225227
random_source_vertices: list[int] = random.sample(
226228
vertices[0 : int(len(vertices) / 2)], edge_pick_count
@@ -281,8 +283,8 @@ def test_init_check(self) -> None:
281283
self.__assert_graph_edge_exists_check(
282284
undirected_graph, directed_graph, edge
283285
)
284-
self.assertFalse(undirected_graph.directed)
285-
self.assertTrue(directed_graph.directed)
286+
assert not undirected_graph.directed
287+
assert directed_graph.directed
286288

287289
def test_contains_vertex(self) -> None:
288290
random_vertices: list[int] = random.sample(range(101), 20)
@@ -297,12 +299,8 @@ def test_contains_vertex(self) -> None:
297299

298300
# Test contains_vertex
299301
for num in range(101):
300-
self.assertEqual(
301-
num in random_vertices, undirected_graph.contains_vertex(num)
302-
)
303-
self.assertEqual(
304-
num in random_vertices, directed_graph.contains_vertex(num)
305-
)
302+
assert (num in random_vertices) == undirected_graph.contains_vertex(num)
303+
assert (num in random_vertices) == directed_graph.contains_vertex(num)
306304

307305
def test_add_vertices(self) -> None:
308306
random_vertices: list[int] = random.sample(range(101), 20)
@@ -507,9 +505,9 @@ def test_add_vertex_exception_check(self) -> None:
507505
) = self.__generate_graphs(20, 0, 100, 4)
508506

509507
for vertex in random_vertices:
510-
with self.assertRaises(ValueError):
508+
with pytest.raises(ValueError):
511509
undirected_graph.add_vertex(vertex)
512-
with self.assertRaises(ValueError):
510+
with pytest.raises(ValueError):
513511
directed_graph.add_vertex(vertex)
514512

515513
def test_remove_vertex_exception_check(self) -> None:
@@ -522,9 +520,9 @@ def test_remove_vertex_exception_check(self) -> None:
522520

523521
for i in range(101):
524522
if i not in random_vertices:
525-
with self.assertRaises(ValueError):
523+
with pytest.raises(ValueError):
526524
undirected_graph.remove_vertex(i)
527-
with self.assertRaises(ValueError):
525+
with pytest.raises(ValueError):
528526
directed_graph.remove_vertex(i)
529527

530528
def test_add_edge_exception_check(self) -> None:
@@ -536,9 +534,9 @@ def test_add_edge_exception_check(self) -> None:
536534
) = self.__generate_graphs(20, 0, 100, 4)
537535

538536
for edge in random_edges:
539-
with self.assertRaises(ValueError):
537+
with pytest.raises(ValueError):
540538
undirected_graph.add_edge(edge[0], edge[1])
541-
with self.assertRaises(ValueError):
539+
with pytest.raises(ValueError):
542540
directed_graph.add_edge(edge[0], edge[1])
543541

544542
def test_remove_edge_exception_check(self) -> None:
@@ -560,9 +558,9 @@ def test_remove_edge_exception_check(self) -> None:
560558
more_random_edges.append(edge)
561559

562560
for edge in more_random_edges:
563-
with self.assertRaises(ValueError):
561+
with pytest.raises(ValueError):
564562
undirected_graph.remove_edge(edge[0], edge[1])
565-
with self.assertRaises(ValueError):
563+
with pytest.raises(ValueError):
566564
directed_graph.remove_edge(edge[0], edge[1])
567565

568566
def test_contains_edge_exception_check(self) -> None:
@@ -574,14 +572,14 @@ def test_contains_edge_exception_check(self) -> None:
574572
) = self.__generate_graphs(20, 0, 100, 4)
575573

576574
for vertex in random_vertices:
577-
with self.assertRaises(ValueError):
575+
with pytest.raises(ValueError):
578576
undirected_graph.contains_edge(vertex, 102)
579-
with self.assertRaises(ValueError):
577+
with pytest.raises(ValueError):
580578
directed_graph.contains_edge(vertex, 102)
581579

582-
with self.assertRaises(ValueError):
580+
with pytest.raises(ValueError):
583581
undirected_graph.contains_edge(103, 102)
584-
with self.assertRaises(ValueError):
582+
with pytest.raises(ValueError):
585583
directed_graph.contains_edge(103, 102)
586584

587585

‎graphs/graph_adjacency_matrix.py

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
from pprint import pformat
2323
from typing import Generic, TypeVar
2424

25+
import pytest
26+
2527
T = TypeVar("T")
2628

2729

@@ -203,42 +205,42 @@ def __assert_graph_edge_exists_check(
203205
directed_graph: GraphAdjacencyMatrix,
204206
edge: list[int],
205207
) -> None:
206-
self.assertTrue(undirected_graph.contains_edge(edge[0], edge[1]))
207-
self.assertTrue(undirected_graph.contains_edge(edge[1], edge[0]))
208-
self.assertTrue(directed_graph.contains_edge(edge[0], edge[1]))
208+
assert undirected_graph.contains_edge(edge[0], edge[1])
209+
assert undirected_graph.contains_edge(edge[1], edge[0])
210+
assert directed_graph.contains_edge(edge[0], edge[1])
209211

210212
def __assert_graph_edge_does_not_exist_check(
211213
self,
212214
undirected_graph: GraphAdjacencyMatrix,
213215
directed_graph: GraphAdjacencyMatrix,
214216
edge: list[int],
215217
) -> None:
216-
self.assertFalse(undirected_graph.contains_edge(edge[0], edge[1]))
217-
self.assertFalse(undirected_graph.contains_edge(edge[1], edge[0]))
218-
self.assertFalse(directed_graph.contains_edge(edge[0], edge[1]))
218+
assert not undirected_graph.contains_edge(edge[0], edge[1])
219+
assert not undirected_graph.contains_edge(edge[1], edge[0])
220+
assert not directed_graph.contains_edge(edge[0], edge[1])
219221

220222
def __assert_graph_vertex_exists_check(
221223
self,
222224
undirected_graph: GraphAdjacencyMatrix,
223225
directed_graph: GraphAdjacencyMatrix,
224226
vertex: int,
225227
) -> None:
226-
self.assertTrue(undirected_graph.contains_vertex(vertex))
227-
self.assertTrue(directed_graph.contains_vertex(vertex))
228+
assert undirected_graph.contains_vertex(vertex)
229+
assert directed_graph.contains_vertex(vertex)
228230

229231
def __assert_graph_vertex_does_not_exist_check(
230232
self,
231233
undirected_graph: GraphAdjacencyMatrix,
232234
directed_graph: GraphAdjacencyMatrix,
233235
vertex: int,
234236
) -> None:
235-
self.assertFalse(undirected_graph.contains_vertex(vertex))
236-
self.assertFalse(directed_graph.contains_vertex(vertex))
237+
assert not undirected_graph.contains_vertex(vertex)
238+
assert not directed_graph.contains_vertex(vertex)
237239

238240
def __generate_random_edges(
239241
self, vertices: list[int], edge_pick_count: int
240242
) -> list[list[int]]:
241-
self.assertTrue(edge_pick_count <= len(vertices))
243+
assert edge_pick_count <= len(vertices)
242244

243245
random_source_vertices: list[int] = random.sample(
244246
vertices[0 : int(len(vertices) / 2)], edge_pick_count
@@ -300,8 +302,8 @@ def test_init_check(self) -> None:
300302
undirected_graph, directed_graph, edge
301303
)
302304

303-
self.assertFalse(undirected_graph.directed)
304-
self.assertTrue(directed_graph.directed)
305+
assert not undirected_graph.directed
306+
assert directed_graph.directed
305307

306308
def test_contains_vertex(self) -> None:
307309
random_vertices: list[int] = random.sample(range(101), 20)
@@ -316,12 +318,8 @@ def test_contains_vertex(self) -> None:
316318

317319
# Test contains_vertex
318320
for num in range(101):
319-
self.assertEqual(
320-
num in random_vertices, undirected_graph.contains_vertex(num)
321-
)
322-
self.assertEqual(
323-
num in random_vertices, directed_graph.contains_vertex(num)
324-
)
321+
assert (num in random_vertices) == undirected_graph.contains_vertex(num)
322+
assert (num in random_vertices) == directed_graph.contains_vertex(num)
325323

326324
def test_add_vertices(self) -> None:
327325
random_vertices: list[int] = random.sample(range(101), 20)
@@ -526,9 +524,9 @@ def test_add_vertex_exception_check(self) -> None:
526524
) = self.__generate_graphs(20, 0, 100, 4)
527525

528526
for vertex in random_vertices:
529-
with self.assertRaises(ValueError):
527+
with pytest.raises(ValueError):
530528
undirected_graph.add_vertex(vertex)
531-
with self.assertRaises(ValueError):
529+
with pytest.raises(ValueError):
532530
directed_graph.add_vertex(vertex)
533531

534532
def test_remove_vertex_exception_check(self) -> None:
@@ -541,9 +539,9 @@ def test_remove_vertex_exception_check(self) -> None:
541539

542540
for i in range(101):
543541
if i not in random_vertices:
544-
with self.assertRaises(ValueError):
542+
with pytest.raises(ValueError):
545543
undirected_graph.remove_vertex(i)
546-
with self.assertRaises(ValueError):
544+
with pytest.raises(ValueError):
547545
directed_graph.remove_vertex(i)
548546

549547
def test_add_edge_exception_check(self) -> None:
@@ -555,9 +553,9 @@ def test_add_edge_exception_check(self) -> None:
555553
) = self.__generate_graphs(20, 0, 100, 4)
556554

557555
for edge in random_edges:
558-
with self.assertRaises(ValueError):
556+
with pytest.raises(ValueError):
559557
undirected_graph.add_edge(edge[0], edge[1])
560-
with self.assertRaises(ValueError):
558+
with pytest.raises(ValueError):
561559
directed_graph.add_edge(edge[0], edge[1])
562560

563561
def test_remove_edge_exception_check(self) -> None:
@@ -579,9 +577,9 @@ def test_remove_edge_exception_check(self) -> None:
579577
more_random_edges.append(edge)
580578

581579
for edge in more_random_edges:
582-
with self.assertRaises(ValueError):
580+
with pytest.raises(ValueError):
583581
undirected_graph.remove_edge(edge[0], edge[1])
584-
with self.assertRaises(ValueError):
582+
with pytest.raises(ValueError):
585583
directed_graph.remove_edge(edge[0], edge[1])
586584

587585
def test_contains_edge_exception_check(self) -> None:
@@ -593,14 +591,14 @@ def test_contains_edge_exception_check(self) -> None:
593591
) = self.__generate_graphs(20, 0, 100, 4)
594592

595593
for vertex in random_vertices:
596-
with self.assertRaises(ValueError):
594+
with pytest.raises(ValueError):
597595
undirected_graph.contains_edge(vertex, 102)
598-
with self.assertRaises(ValueError):
596+
with pytest.raises(ValueError):
599597
directed_graph.contains_edge(vertex, 102)
600598

601-
with self.assertRaises(ValueError):
599+
with pytest.raises(ValueError):
602600
undirected_graph.contains_edge(103, 102)
603-
with self.assertRaises(ValueError):
601+
with pytest.raises(ValueError):
604602
directed_graph.contains_edge(103, 102)
605603

606604

‎hashes/sha256.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ def test_match_hashes(self) -> None:
203203
import hashlib
204204

205205
msg = bytes("Test String", "utf-8")
206-
self.assertEqual(SHA256(msg).hash, hashlib.sha256(msg).hexdigest())
206+
assert SHA256(msg).hash == hashlib.sha256(msg).hexdigest()
207207

208208

209209
def main() -> None:

‎knapsack/tests/test_greedy_knapsack.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import unittest
22

3+
import pytest
4+
35
from knapsack import greedy_knapsack as kp
46

57

@@ -16,7 +18,7 @@ def test_sorted(self):
1618
profit = [10, 20, 30, 40, 50, 60]
1719
weight = [2, 4, 6, 8, 10, 12]
1820
max_weight = 100
19-
self.assertEqual(kp.calc_profit(profit, weight, max_weight), 210)
21+
assert kp.calc_profit(profit, weight, max_weight) == 210
2022

2123
def test_negative_max_weight(self):
2224
"""
@@ -26,7 +28,7 @@ def test_negative_max_weight(self):
2628
# profit = [10, 20, 30, 40, 50, 60]
2729
# weight = [2, 4, 6, 8, 10, 12]
2830
# max_weight = -15
29-
self.assertRaisesRegex(ValueError, "max_weight must greater than zero.")
31+
pytest.raises(ValueError, match="max_weight must greater than zero.")
3032

3133
def test_negative_profit_value(self):
3234
"""
@@ -36,7 +38,7 @@ def test_negative_profit_value(self):
3638
# profit = [10, -20, 30, 40, 50, 60]
3739
# weight = [2, 4, 6, 8, 10, 12]
3840
# max_weight = 15
39-
self.assertRaisesRegex(ValueError, "Weight can not be negative.")
41+
pytest.raises(ValueError, match="Weight can not be negative.")
4042

4143
def test_negative_weight_value(self):
4244
"""
@@ -46,7 +48,7 @@ def test_negative_weight_value(self):
4648
# profit = [10, 20, 30, 40, 50, 60]
4749
# weight = [2, -4, 6, -8, 10, 12]
4850
# max_weight = 15
49-
self.assertRaisesRegex(ValueError, "Profit can not be negative.")
51+
pytest.raises(ValueError, match="Profit can not be negative.")
5052

5153
def test_null_max_weight(self):
5254
"""
@@ -56,7 +58,7 @@ def test_null_max_weight(self):
5658
# profit = [10, 20, 30, 40, 50, 60]
5759
# weight = [2, 4, 6, 8, 10, 12]
5860
# max_weight = null
59-
self.assertRaisesRegex(ValueError, "max_weight must greater than zero.")
61+
pytest.raises(ValueError, match="max_weight must greater than zero.")
6062

6163
def test_unequal_list_length(self):
6264
"""
@@ -66,9 +68,7 @@ def test_unequal_list_length(self):
6668
# profit = [10, 20, 30, 40, 50]
6769
# weight = [2, 4, 6, 8, 10, 12]
6870
# max_weight = 100
69-
self.assertRaisesRegex(
70-
IndexError, "The length of profit and weight must be same."
71-
)
71+
pytest.raises(IndexError, match="The length of profit and weight must be same.")
7272

7373

7474
if __name__ == "__main__":

‎knapsack/tests/test_knapsack.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ def test_base_case(self):
2020
val = [0]
2121
w = [0]
2222
c = len(val)
23-
self.assertEqual(k.knapsack(cap, w, val, c), 0)
23+
assert k.knapsack(cap, w, val, c) == 0
2424

2525
val = [60]
2626
w = [10]
2727
c = len(val)
28-
self.assertEqual(k.knapsack(cap, w, val, c), 0)
28+
assert k.knapsack(cap, w, val, c) == 0
2929

3030
def test_easy_case(self):
3131
"""
@@ -35,7 +35,7 @@ def test_easy_case(self):
3535
val = [1, 2, 3]
3636
w = [3, 2, 1]
3737
c = len(val)
38-
self.assertEqual(k.knapsack(cap, w, val, c), 5)
38+
assert k.knapsack(cap, w, val, c) == 5
3939

4040
def test_knapsack(self):
4141
"""
@@ -45,7 +45,7 @@ def test_knapsack(self):
4545
val = [60, 100, 120]
4646
w = [10, 20, 30]
4747
c = len(val)
48-
self.assertEqual(k.knapsack(cap, w, val, c), 220)
48+
assert k.knapsack(cap, w, val, c) == 220
4949

5050

5151
if __name__ == "__main__":

‎linear_algebra/src/lib.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ def unit_basis_vector(dimension: int, pos: int) -> Vector:
200200
at index 'pos' (indexing at 0)
201201
"""
202202
# precondition
203-
assert isinstance(dimension, int) and (isinstance(pos, int))
203+
assert isinstance(dimension, int)
204+
assert isinstance(pos, int)
204205
ans = [0] * dimension
205206
ans[pos] = 1
206207
return Vector(ans)
@@ -213,11 +214,9 @@ def axpy(scalar: float, x: Vector, y: Vector) -> Vector:
213214
computes the axpy operation
214215
"""
215216
# precondition
216-
assert (
217-
isinstance(x, Vector)
218-
and isinstance(y, Vector)
219-
and (isinstance(scalar, (int, float)))
220-
)
217+
assert isinstance(x, Vector)
218+
assert isinstance(y, Vector)
219+
assert isinstance(scalar, (int, float))
221220
return x * scalar + y
222221

223222

‎linear_algebra/src/schur_complement.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import unittest
22

33
import numpy as np
4+
import pytest
45

56

67
def schur_complement(
@@ -70,22 +71,22 @@ def test_schur_complement(self) -> None:
7071
det_a = np.linalg.det(a)
7172
det_s = np.linalg.det(s)
7273

73-
self.assertAlmostEqual(det_x, det_a * det_s)
74+
assert np.is_close(det_x, det_a * det_s)
7475

7576
def test_improper_a_b_dimensions(self) -> None:
7677
a = np.array([[1, 2, 1], [2, 1, 2], [3, 2, 4]])
7778
b = np.array([[0, 3], [3, 0], [2, 3]])
7879
c = np.array([[2, 1], [6, 3]])
7980

80-
with self.assertRaises(ValueError):
81+
with pytest.raises(ValueError):
8182
schur_complement(a, b, c)
8283

8384
def test_improper_b_c_dimensions(self) -> None:
8485
a = np.array([[1, 2, 1], [2, 1, 2], [3, 2, 4]])
8586
b = np.array([[0, 3], [3, 0], [2, 3]])
8687
c = np.array([[2, 1, 3], [6, 3, 5]])
8788

88-
with self.assertRaises(ValueError):
89+
with pytest.raises(ValueError):
8990
schur_complement(a, b, c)
9091

9192

‎linear_algebra/src/test_linear_algebra.py

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
"""
99
import unittest
1010

11+
import pytest
12+
1113
from .lib import (
1214
Matrix,
1315
Vector,
@@ -24,23 +26,23 @@ def test_component(self) -> None:
2426
test for method component()
2527
"""
2628
x = Vector([1, 2, 3])
27-
self.assertEqual(x.component(0), 1)
28-
self.assertEqual(x.component(2), 3)
29+
assert x.component(0) == 1
30+
assert x.component(2) == 3
2931
_ = Vector()
3032

3133
def test_str(self) -> None:
3234
"""
3335
test for method toString()
3436
"""
3537
x = Vector([0, 0, 0, 0, 0, 1])
36-
self.assertEqual(str(x), "(0,0,0,0,0,1)")
38+
assert str(x) == "(0,0,0,0,0,1)"
3739

3840
def test_size(self) -> None:
3941
"""
4042
test for method size()
4143
"""
4244
x = Vector([1, 2, 3, 4])
43-
self.assertEqual(len(x), 4)
45+
assert len(x) == 4
4446

4547
def test_euclidean_length(self) -> None:
4648
"""
@@ -50,30 +52,30 @@ def test_euclidean_length(self) -> None:
5052
y = Vector([1, 2, 3, 4, 5])
5153
z = Vector([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
5254
w = Vector([1, -1, 1, -1, 2, -3, 4, -5])
53-
self.assertAlmostEqual(x.euclidean_length(), 2.236, 3)
54-
self.assertAlmostEqual(y.euclidean_length(), 7.416, 3)
55-
self.assertEqual(z.euclidean_length(), 0)
56-
self.assertAlmostEqual(w.euclidean_length(), 7.616, 3)
55+
assert x.euclidean_length() == pytest.approx(2.236, abs=1e-3)
56+
assert y.euclidean_length() == pytest.approx(7.416, abs=1e-3)
57+
assert z.euclidean_length() == 0
58+
assert w.euclidean_length() == pytest.approx(7.616, abs=1e-3)
5759

5860
def test_add(self) -> None:
5961
"""
6062
test for + operator
6163
"""
6264
x = Vector([1, 2, 3])
6365
y = Vector([1, 1, 1])
64-
self.assertEqual((x + y).component(0), 2)
65-
self.assertEqual((x + y).component(1), 3)
66-
self.assertEqual((x + y).component(2), 4)
66+
assert (x + y).component(0) == 2
67+
assert (x + y).component(1) == 3
68+
assert (x + y).component(2) == 4
6769

6870
def test_sub(self) -> None:
6971
"""
7072
test for - operator
7173
"""
7274
x = Vector([1, 2, 3])
7375
y = Vector([1, 1, 1])
74-
self.assertEqual((x - y).component(0), 0)
75-
self.assertEqual((x - y).component(1), 1)
76-
self.assertEqual((x - y).component(2), 2)
76+
assert (x - y).component(0) == 0
77+
assert (x - y).component(1) == 1
78+
assert (x - y).component(2) == 2
7779

7880
def test_mul(self) -> None:
7981
"""
@@ -82,36 +84,36 @@ def test_mul(self) -> None:
8284
x = Vector([1, 2, 3])
8385
a = Vector([2, -1, 4]) # for test of dot product
8486
b = Vector([1, -2, -1])
85-
self.assertEqual(str(x * 3.0), "(3.0,6.0,9.0)")
86-
self.assertEqual((a * b), 0)
87+
assert str(x * 3.0) == "(3.0,6.0,9.0)"
88+
assert a * b == 0
8789

8890
def test_zero_vector(self) -> None:
8991
"""
9092
test for global function zero_vector()
9193
"""
92-
self.assertEqual(str(zero_vector(10)).count("0"), 10)
94+
assert str(zero_vector(10)).count("0") == 10
9395

9496
def test_unit_basis_vector(self) -> None:
9597
"""
9698
test for global function unit_basis_vector()
9799
"""
98-
self.assertEqual(str(unit_basis_vector(3, 1)), "(0,1,0)")
100+
assert str(unit_basis_vector(3, 1)) == "(0,1,0)"
99101

100102
def test_axpy(self) -> None:
101103
"""
102104
test for global function axpy() (operation)
103105
"""
104106
x = Vector([1, 2, 3])
105107
y = Vector([1, 0, 1])
106-
self.assertEqual(str(axpy(2, x, y)), "(3,4,7)")
108+
assert str(axpy(2, x, y)) == "(3,4,7)"
107109

108110
def test_copy(self) -> None:
109111
"""
110112
test for method copy()
111113
"""
112114
x = Vector([1, 0, 0, 0, 0, 0])
113115
y = x.copy()
114-
self.assertEqual(str(x), str(y))
116+
assert str(x) == str(y)
115117

116118
def test_change_component(self) -> None:
117119
"""
@@ -120,14 +122,14 @@ def test_change_component(self) -> None:
120122
x = Vector([1, 0, 0])
121123
x.change_component(0, 0)
122124
x.change_component(1, 1)
123-
self.assertEqual(str(x), "(0,1,0)")
125+
assert str(x) == "(0,1,0)"
124126

125127
def test_str_matrix(self) -> None:
126128
"""
127129
test for Matrix method str()
128130
"""
129131
a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
130-
self.assertEqual("|1,2,3|\n|2,4,5|\n|6,7,8|\n", str(a))
132+
assert str(a) == "|1,2,3|\n|2,4,5|\n|6,7,8|\n"
131133

132134
def test_minor(self) -> None:
133135
"""
@@ -137,7 +139,7 @@ def test_minor(self) -> None:
137139
minors = [[-3, -14, -10], [-5, -10, -5], [-2, -1, 0]]
138140
for x in range(a.height()):
139141
for y in range(a.width()):
140-
self.assertEqual(minors[x][y], a.minor(x, y))
142+
assert minors[x][y] == a.minor(x, y)
141143

142144
def test_cofactor(self) -> None:
143145
"""
@@ -147,62 +149,61 @@ def test_cofactor(self) -> None:
147149
cofactors = [[-3, 14, -10], [5, -10, 5], [-2, 1, 0]]
148150
for x in range(a.height()):
149151
for y in range(a.width()):
150-
self.assertEqual(cofactors[x][y], a.cofactor(x, y))
152+
assert cofactors[x][y] == a.cofactor(x, y)
151153

152154
def test_determinant(self) -> None:
153155
"""
154156
test for Matrix method determinant()
155157
"""
156158
a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
157-
self.assertEqual(-5, a.determinant())
159+
assert a.determinant() == -5
158160

159161
def test__mul__matrix(self) -> None:
160162
"""
161163
test for Matrix * operator
162164
"""
163165
a = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]], 3, 3)
164166
x = Vector([1, 2, 3])
165-
self.assertEqual("(14,32,50)", str(a * x))
166-
self.assertEqual("|2,4,6|\n|8,10,12|\n|14,16,18|\n", str(a * 2))
167+
assert str(a * x) == "(14,32,50)"
168+
assert str(a * 2) == "|2,4,6|\n|8,10,12|\n|14,16,18|\n"
167169

168170
def test_change_component_matrix(self) -> None:
169171
"""
170172
test for Matrix method change_component()
171173
"""
172174
a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
173175
a.change_component(0, 2, 5)
174-
self.assertEqual("|1,2,5|\n|2,4,5|\n|6,7,8|\n", str(a))
176+
assert str(a) == "|1,2,5|\n|2,4,5|\n|6,7,8|\n"
175177

176178
def test_component_matrix(self) -> None:
177179
"""
178180
test for Matrix method component()
179181
"""
180182
a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
181-
self.assertEqual(7, a.component(2, 1), 0.01)
183+
assert a.component(2, 1) == 7, 0.01
182184

183185
def test__add__matrix(self) -> None:
184186
"""
185187
test for Matrix + operator
186188
"""
187189
a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
188190
b = Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]], 3, 3)
189-
self.assertEqual("|2,4,10|\n|4,8,10|\n|12,14,18|\n", str(a + b))
191+
assert str(a + b) == "|2,4,10|\n|4,8,10|\n|12,14,18|\n"
190192

191193
def test__sub__matrix(self) -> None:
192194
"""
193195
test for Matrix - operator
194196
"""
195197
a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
196198
b = Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]], 3, 3)
197-
self.assertEqual("|0,0,-4|\n|0,0,0|\n|0,0,-2|\n", str(a - b))
199+
assert str(a - b) == "|0,0,-4|\n|0,0,0|\n|0,0,-2|\n"
198200

199201
def test_square_zero_matrix(self) -> None:
200202
"""
201203
test for global function square_zero_matrix()
202204
"""
203-
self.assertEqual(
204-
"|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n",
205-
str(square_zero_matrix(5)),
205+
assert str(square_zero_matrix(5)) == (
206+
"|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n"
206207
)
207208

208209

‎machine_learning/dimensionality_reduction.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ def test_linear_discriminant_analysis() -> None:
169169
dimensions = 2
170170

171171
# Assert that the function raises an AssertionError if dimensions > classes
172-
with pytest.raises(AssertionError) as error_info:
172+
with pytest.raises(AssertionError) as error_info: # noqa: PT012
173173
projected_data = linear_discriminant_analysis(
174174
features, labels, classes, dimensions
175175
)
@@ -185,7 +185,7 @@ def test_principal_component_analysis() -> None:
185185
dimensions = 2
186186
expected_output = np.array([[6.92820323, 8.66025404, 10.39230485], [3.0, 3.0, 3.0]])
187187

188-
with pytest.raises(AssertionError) as error_info:
188+
with pytest.raises(AssertionError) as error_info: # noqa: PT012
189189
output = principal_component_analysis(features, dimensions)
190190
if not np.allclose(expected_output, output):
191191
raise AssertionError

‎machine_learning/k_means_clust.py

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def plot_heterogeneity(heterogeneity, k):
128128
def kmeans(
129129
data, k, initial_centroids, maxiter=500, record_heterogeneity=None, verbose=False
130130
):
131-
"""This function runs k-means on given data and initial set of centroids.
131+
"""Runs k-means on given data and initial set of centroids.
132132
maxiter: maximum number of iterations to run.(default=500)
133133
record_heterogeneity: (optional) a list, to store the history of heterogeneity
134134
as function of iterations
@@ -195,20 +195,20 @@ def kmeans(
195195

196196

197197
def report_generator(
198-
df: pd.DataFrame, clustering_variables: np.ndarray, fill_missing_report=None
198+
predicted: pd.DataFrame, clustering_variables: np.ndarray, fill_missing_report=None
199199
) -> pd.DataFrame:
200200
"""
201-
Generates a clustering report. This function takes 2 arguments as input:
202-
df - dataframe with predicted cluster column
201+
Generate a clustering report given these two arguments:
202+
predicted - dataframe with predicted cluster column
203203
fill_missing_report - dictionary of rules on how we are going to fill in missing
204204
values for final generated report (not included in modelling);
205-
>>> data = pd.DataFrame()
206-
>>> data['numbers'] = [1, 2, 3]
207-
>>> data['col1'] = [0.5, 2.5, 4.5]
208-
>>> data['col2'] = [100, 200, 300]
209-
>>> data['col3'] = [10, 20, 30]
210-
>>> data['Cluster'] = [1, 1, 2]
211-
>>> report_generator(data, ['col1', 'col2'], 0)
205+
>>> predicted = pd.DataFrame()
206+
>>> predicted['numbers'] = [1, 2, 3]
207+
>>> predicted['col1'] = [0.5, 2.5, 4.5]
208+
>>> predicted['col2'] = [100, 200, 300]
209+
>>> predicted['col3'] = [10, 20, 30]
210+
>>> predicted['Cluster'] = [1, 1, 2]
211+
>>> report_generator(predicted, ['col1', 'col2'], 0)
212212
Features Type Mark 1 2
213213
0 # of Customers ClusterSize False 2.000000 1.000000
214214
1 % of Customers ClusterProportion False 0.666667 0.333333
@@ -226,11 +226,11 @@ def report_generator(
226226
"""
227227
# Fill missing values with given rules
228228
if fill_missing_report:
229-
df = df.fillna(value=fill_missing_report)
230-
df["dummy"] = 1
231-
numeric_cols = df.select_dtypes(np.number).columns
229+
predicted = predicted.fillna(value=fill_missing_report)
230+
predicted["dummy"] = 1
231+
numeric_cols = predicted.select_dtypes(np.number).columns
232232
report = (
233-
df.groupby(["Cluster"])[ # construct report dataframe
233+
predicted.groupby(["Cluster"])[ # construct report dataframe
234234
numeric_cols
235235
] # group by cluster number
236236
.agg(
@@ -267,46 +267,43 @@ def report_generator(
267267
.rename(index=str, columns={"level_0": "Features", "level_1": "Type"})
268268
) # rename columns
269269
# calculate the size of cluster(count of clientID's)
270+
# avoid SettingWithCopyWarning
270271
clustersize = report[
271272
(report["Features"] == "dummy") & (report["Type"] == "count")
272-
].copy() # avoid SettingWithCopyWarning
273-
clustersize.Type = (
274-
"ClusterSize" # rename created cluster df to match report column names
275-
)
273+
].copy()
274+
# rename created predicted cluster to match report column names
275+
clustersize.Type = "ClusterSize"
276276
clustersize.Features = "# of Customers"
277+
# calculating the proportion of cluster
277278
clusterproportion = pd.DataFrame(
278-
clustersize.iloc[:, 2:].values
279-
/ clustersize.iloc[:, 2:].values.sum() # calculating the proportion of cluster
279+
clustersize.iloc[:, 2:].to_numpy() / clustersize.iloc[:, 2:].to_numpy().sum()
280280
)
281-
clusterproportion[
282-
"Type"
283-
] = "% of Customers" # rename created cluster df to match report column names
281+
# rename created predicted cluster to match report column names
282+
clusterproportion["Type"] = "% of Customers"
284283
clusterproportion["Features"] = "ClusterProportion"
285284
cols = clusterproportion.columns.tolist()
286285
cols = cols[-2:] + cols[:-2]
287286
clusterproportion = clusterproportion[cols] # rearrange columns to match report
288287
clusterproportion.columns = report.columns
288+
# generating dataframe with count of nan values
289289
a = pd.DataFrame(
290290
abs(
291-
report[report["Type"] == "count"].iloc[:, 2:].values
292-
- clustersize.iloc[:, 2:].values
291+
report[report["Type"] == "count"].iloc[:, 2:].to_numpy()
292+
- clustersize.iloc[:, 2:].to_numpy()
293293
)
294-
) # generating df with count of nan values
294+
)
295295
a["Features"] = 0
296296
a["Type"] = "# of nan"
297-
a.Features = report[
298-
report["Type"] == "count"
299-
].Features.tolist() # filling values in order to match report
297+
# filling values in order to match report
298+
a.Features = report[report["Type"] == "count"].Features.tolist()
300299
cols = a.columns.tolist()
301300
cols = cols[-2:] + cols[:-2]
302301
a = a[cols] # rearrange columns to match report
303302
a.columns = report.columns # rename columns to match report
304-
report = report.drop(
305-
report[report.Type == "count"].index
306-
) # drop count values except for cluster size
307-
report = pd.concat(
308-
[report, a, clustersize, clusterproportion], axis=0
309-
) # concat report with cluster size and nan values
303+
# drop count values except for cluster size
304+
report = report.drop(report[report.Type == "count"].index)
305+
# concat report with cluster size and nan values
306+
report = pd.concat([report, a, clustersize, clusterproportion], axis=0)
310307
report["Mark"] = report["Features"].isin(clustering_variables)
311308
cols = report.columns.tolist()
312309
cols = cols[0:2] + cols[-1:] + cols[2:-1]

‎maths/least_common_multiple.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ def test_lcm_function(self):
6767
slow_result = least_common_multiple_slow(first_num, second_num)
6868
fast_result = least_common_multiple_fast(first_num, second_num)
6969
with self.subTest(i=i):
70-
self.assertEqual(slow_result, self.expected_results[i])
71-
self.assertEqual(fast_result, self.expected_results[i])
70+
assert slow_result == self.expected_results[i]
71+
assert fast_result == self.expected_results[i]
7272

7373

7474
if __name__ == "__main__":

‎maths/modular_division.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ def modular_division(a: int, b: int, n: int) -> int:
2828
4
2929
3030
"""
31-
assert n > 1 and a > 0 and greatest_common_divisor(a, n) == 1
31+
assert n > 1
32+
assert a > 0
33+
assert greatest_common_divisor(a, n) == 1
3234
(d, t, s) = extended_gcd(n, a) # Implemented below
3335
x = (b * s) % n
3436
return x
@@ -86,7 +88,8 @@ def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
8688
** extended_gcd function is used when d = gcd(a,b) is required in output
8789
8890
"""
89-
assert a >= 0 and b >= 0
91+
assert a >= 0
92+
assert b >= 0
9093

9194
if b == 0:
9295
d, x, y = a, 1, 0
@@ -95,7 +98,8 @@ def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
9598
x = q
9699
y = p - q * (a // b)
97100

98-
assert a % d == 0 and b % d == 0
101+
assert a % d == 0
102+
assert b % d == 0
99103
assert d == a * x + b * y
100104

101105
return (d, x, y)

‎maths/prime_check.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import math
44
import unittest
55

6+
import pytest
7+
68

79
def is_prime(number: int) -> bool:
810
"""Checks to see if a number is a prime in O(sqrt(n)).
@@ -50,33 +52,31 @@ def is_prime(number: int) -> bool:
5052

5153
class Test(unittest.TestCase):
5254
def test_primes(self):
53-
self.assertTrue(is_prime(2))
54-
self.assertTrue(is_prime(3))
55-
self.assertTrue(is_prime(5))
56-
self.assertTrue(is_prime(7))
57-
self.assertTrue(is_prime(11))
58-
self.assertTrue(is_prime(13))
59-
self.assertTrue(is_prime(17))
60-
self.assertTrue(is_prime(19))
61-
self.assertTrue(is_prime(23))
62-
self.assertTrue(is_prime(29))
55+
assert is_prime(2)
56+
assert is_prime(3)
57+
assert is_prime(5)
58+
assert is_prime(7)
59+
assert is_prime(11)
60+
assert is_prime(13)
61+
assert is_prime(17)
62+
assert is_prime(19)
63+
assert is_prime(23)
64+
assert is_prime(29)
6365

6466
def test_not_primes(self):
65-
with self.assertRaises(AssertionError):
67+
with pytest.raises(AssertionError):
6668
is_prime(-19)
67-
self.assertFalse(
68-
is_prime(0),
69-
"Zero doesn't have any positive factors, primes must have exactly two.",
70-
)
71-
self.assertFalse(
72-
is_prime(1),
73-
"One only has 1 positive factor, primes must have exactly two.",
74-
)
75-
self.assertFalse(is_prime(2 * 2))
76-
self.assertFalse(is_prime(2 * 3))
77-
self.assertFalse(is_prime(3 * 3))
78-
self.assertFalse(is_prime(3 * 5))
79-
self.assertFalse(is_prime(3 * 5 * 7))
69+
assert not is_prime(
70+
0
71+
), "Zero doesn't have any positive factors, primes must have exactly two."
72+
assert not is_prime(
73+
1
74+
), "One only has 1 positive factor, primes must have exactly two."
75+
assert not is_prime(2 * 2)
76+
assert not is_prime(2 * 3)
77+
assert not is_prime(3 * 3)
78+
assert not is_prime(3 * 5)
79+
assert not is_prime(3 * 5 * 7)
8080

8181

8282
if __name__ == "__main__":

‎matrix/sherman_morrison.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ def __add__(self, another: Matrix) -> Matrix:
114114

115115
# Validation
116116
assert isinstance(another, Matrix)
117-
assert self.row == another.row and self.column == another.column
117+
assert self.row == another.row
118+
assert self.column == another.column
118119

119120
# Add
120121
result = Matrix(self.row, self.column)
@@ -225,7 +226,8 @@ def sherman_morrison(self, u: Matrix, v: Matrix) -> Any:
225226
"""
226227

227228
# Size validation
228-
assert isinstance(u, Matrix) and isinstance(v, Matrix)
229+
assert isinstance(u, Matrix)
230+
assert isinstance(v, Matrix)
229231
assert self.row == self.column == u.row == v.row # u, v should be column vector
230232
assert u.column == v.column == 1 # u, v should be column vector
231233

‎matrix/tests/test_matrix_operation.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,47 +31,47 @@
3131
logger.addHandler(stream_handler)
3232

3333

34-
@pytest.mark.mat_ops
34+
@pytest.mark.mat_ops()
3535
@pytest.mark.parametrize(
3636
("mat1", "mat2"), [(mat_a, mat_b), (mat_c, mat_d), (mat_d, mat_e), (mat_f, mat_h)]
3737
)
3838
def test_addition(mat1, mat2):
3939
if (np.array(mat1)).shape < (2, 2) or (np.array(mat2)).shape < (2, 2):
40+
logger.info(f"\n\t{test_addition.__name__} returned integer")
4041
with pytest.raises(TypeError):
41-
logger.info(f"\n\t{test_addition.__name__} returned integer")
4242
matop.add(mat1, mat2)
4343
elif (np.array(mat1)).shape == (np.array(mat2)).shape:
4444
logger.info(f"\n\t{test_addition.__name__} with same matrix dims")
4545
act = (np.array(mat1) + np.array(mat2)).tolist()
4646
theo = matop.add(mat1, mat2)
4747
assert theo == act
4848
else:
49+
logger.info(f"\n\t{test_addition.__name__} with different matrix dims")
4950
with pytest.raises(ValueError):
50-
logger.info(f"\n\t{test_addition.__name__} with different matrix dims")
5151
matop.add(mat1, mat2)
5252

5353

54-
@pytest.mark.mat_ops
54+
@pytest.mark.mat_ops()
5555
@pytest.mark.parametrize(
5656
("mat1", "mat2"), [(mat_a, mat_b), (mat_c, mat_d), (mat_d, mat_e), (mat_f, mat_h)]
5757
)
5858
def test_subtraction(mat1, mat2):
5959
if (np.array(mat1)).shape < (2, 2) or (np.array(mat2)).shape < (2, 2):
60+
logger.info(f"\n\t{test_subtraction.__name__} returned integer")
6061
with pytest.raises(TypeError):
61-
logger.info(f"\n\t{test_subtraction.__name__} returned integer")
6262
matop.subtract(mat1, mat2)
6363
elif (np.array(mat1)).shape == (np.array(mat2)).shape:
6464
logger.info(f"\n\t{test_subtraction.__name__} with same matrix dims")
6565
act = (np.array(mat1) - np.array(mat2)).tolist()
6666
theo = matop.subtract(mat1, mat2)
6767
assert theo == act
6868
else:
69+
logger.info(f"\n\t{test_subtraction.__name__} with different matrix dims")
6970
with pytest.raises(ValueError):
70-
logger.info(f"\n\t{test_subtraction.__name__} with different matrix dims")
7171
assert matop.subtract(mat1, mat2)
7272

7373

74-
@pytest.mark.mat_ops
74+
@pytest.mark.mat_ops()
7575
@pytest.mark.parametrize(
7676
("mat1", "mat2"), [(mat_a, mat_b), (mat_c, mat_d), (mat_d, mat_e), (mat_f, mat_h)]
7777
)
@@ -86,33 +86,33 @@ def test_multiplication(mat1, mat2):
8686
theo = matop.multiply(mat1, mat2)
8787
assert theo == act
8888
else:
89+
logger.info(
90+
f"\n\t{test_multiplication.__name__} does not meet dim requirements"
91+
)
8992
with pytest.raises(ValueError):
90-
logger.info(
91-
f"\n\t{test_multiplication.__name__} does not meet dim requirements"
92-
)
9393
assert matop.subtract(mat1, mat2)
9494

9595

96-
@pytest.mark.mat_ops
96+
@pytest.mark.mat_ops()
9797
def test_scalar_multiply():
9898
act = (3.5 * np.array(mat_a)).tolist()
9999
theo = matop.scalar_multiply(mat_a, 3.5)
100100
assert theo == act
101101

102102

103-
@pytest.mark.mat_ops
103+
@pytest.mark.mat_ops()
104104
def test_identity():
105105
act = (np.identity(5)).tolist()
106106
theo = matop.identity(5)
107107
assert theo == act
108108

109109

110-
@pytest.mark.mat_ops
110+
@pytest.mark.mat_ops()
111111
@pytest.mark.parametrize("mat", [mat_a, mat_b, mat_c, mat_d, mat_e, mat_f])
112112
def test_transpose(mat):
113113
if (np.array(mat)).shape < (2, 2):
114+
logger.info(f"\n\t{test_transpose.__name__} returned integer")
114115
with pytest.raises(TypeError):
115-
logger.info(f"\n\t{test_transpose.__name__} returned integer")
116116
matop.transpose(mat)
117117
else:
118118
act = (np.transpose(mat)).tolist()

‎project_euler/problem_054/test_poker_hand.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -147,39 +147,39 @@ def generate_random_hands(number_of_hands: int = 100):
147147
return (generate_random_hand() for _ in range(number_of_hands))
148148

149149

150-
@pytest.mark.parametrize("hand, expected", TEST_FLUSH)
150+
@pytest.mark.parametrize(("hand", "expected"), TEST_FLUSH)
151151
def test_hand_is_flush(hand, expected):
152152
assert PokerHand(hand)._is_flush() == expected
153153

154154

155-
@pytest.mark.parametrize("hand, expected", TEST_STRAIGHT)
155+
@pytest.mark.parametrize(("hand", "expected"), TEST_STRAIGHT)
156156
def test_hand_is_straight(hand, expected):
157157
assert PokerHand(hand)._is_straight() == expected
158158

159159

160-
@pytest.mark.parametrize("hand, expected, card_values", TEST_FIVE_HIGH_STRAIGHT)
160+
@pytest.mark.parametrize(("hand", "expected", "card_values"), TEST_FIVE_HIGH_STRAIGHT)
161161
def test_hand_is_five_high_straight(hand, expected, card_values):
162162
player = PokerHand(hand)
163163
assert player._is_five_high_straight() == expected
164164
assert player._card_values == card_values
165165

166166

167-
@pytest.mark.parametrize("hand, expected", TEST_KIND)
167+
@pytest.mark.parametrize(("hand", "expected"), TEST_KIND)
168168
def test_hand_is_same_kind(hand, expected):
169169
assert PokerHand(hand)._is_same_kind() == expected
170170

171171

172-
@pytest.mark.parametrize("hand, expected", TEST_TYPES)
172+
@pytest.mark.parametrize(("hand", "expected"), TEST_TYPES)
173173
def test_hand_values(hand, expected):
174174
assert PokerHand(hand)._hand_type == expected
175175

176176

177-
@pytest.mark.parametrize("hand, other, expected", TEST_COMPARE)
177+
@pytest.mark.parametrize(("hand", "other", "expected"), TEST_COMPARE)
178178
def test_compare_simple(hand, other, expected):
179179
assert PokerHand(hand).compare_with(PokerHand(other)) == expected
180180

181181

182-
@pytest.mark.parametrize("hand, other, expected", generate_random_hands())
182+
@pytest.mark.parametrize(("hand", "other", "expected"), generate_random_hands())
183183
def test_compare_random(hand, other, expected):
184184
assert PokerHand(hand).compare_with(PokerHand(other)) == expected
185185

‎pyproject.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ ignore = [ # `ruff rule S101` for a description of that rule
1919
"PLW0120", # `else` clause on loop without a `break` statement -- FIX ME
2020
"PLW060", # Using global for `{name}` but no assignment is done -- DO NOT FIX
2121
"PLW2901", # PLW2901: Redefined loop variable -- FIX ME
22+
"PT011", # `pytest.raises(Exception)` is too broad, set the `match` parameter or use a more specific exception
23+
"PT018", # Assertion should be broken down into multiple parts
2224
"RUF00", # Ambiguous unicode character and other rules
2325
"RUF100", # Unused `noqa` directive -- FIX ME
2426
"S101", # Use of `assert` detected -- DO NOT FIX
@@ -37,6 +39,7 @@ select = [ # https://beta.ruff.rs/docs/rules
3739
"BLE", # flake8-blind-except
3840
"C4", # flake8-comprehensions
3941
"C90", # McCabe cyclomatic complexity
42+
"DJ", # flake8-django
4043
"DTZ", # flake8-datetimez
4144
"E", # pycodestyle
4245
"EM", # flake8-errmsg
@@ -52,9 +55,11 @@ select = [ # https://beta.ruff.rs/docs/rules
5255
"ISC", # flake8-implicit-str-concat
5356
"N", # pep8-naming
5457
"NPY", # NumPy-specific rules
58+
"PD", # pandas-vet
5559
"PGH", # pygrep-hooks
5660
"PIE", # flake8-pie
5761
"PL", # Pylint
62+
"PT", # flake8-pytest-style
5863
"PYI", # flake8-pyi
5964
"RSE", # flake8-raise
6065
"RUF", # Ruff-specific rules
@@ -70,11 +75,8 @@ select = [ # https://beta.ruff.rs/docs/rules
7075
# "ANN", # flake8-annotations # FIX ME?
7176
# "COM", # flake8-commas
7277
# "D", # pydocstyle -- FIX ME?
73-
# "DJ", # flake8-django
7478
# "ERA", # eradicate -- DO NOT FIX
7579
# "FBT", # flake8-boolean-trap # FIX ME
76-
# "PD", # pandas-vet
77-
# "PT", # flake8-pytest-style
7880
# "PTH", # flake8-use-pathlib # FIX ME
7981
# "Q", # flake8-quotes
8082
# "RET", # flake8-return # FIX ME?

‎strings/knuth_morris_pratt.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ def get_failure_array(pattern: str) -> list[int]:
7171
pattern = "abc1abc12"
7272
text1 = "alskfjaldsabc1abc1abc12k23adsfabcabc"
7373
text2 = "alskfjaldsk23adsfabcabc"
74-
assert knuth_morris_pratt(text1, pattern) and knuth_morris_pratt(text2, pattern)
74+
assert knuth_morris_pratt(text1, pattern)
75+
assert knuth_morris_pratt(text2, pattern)
7576

7677
# Test 2)
7778
pattern = "ABABX"

‎strings/rabin_karp.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ def test_rabin_karp() -> None:
6060
pattern = "abc1abc12"
6161
text1 = "alskfjaldsabc1abc1abc12k23adsfabcabc"
6262
text2 = "alskfjaldsk23adsfabcabc"
63-
assert rabin_karp(pattern, text1) and not rabin_karp(pattern, text2)
63+
assert rabin_karp(pattern, text1)
64+
assert not rabin_karp(pattern, text2)
6465

6566
# Test 2)
6667
pattern = "ABABX"

0 commit comments

Comments
 (0)
Please sign in to comment.