Ruff pandas vet (#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>
This commit is contained in:
Christian Clauss 2023-10-11 20:30:02 +02:00 committed by GitHub
parent d5323dbaee
commit 3f094fe49d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 260 additions and 241 deletions

View File

@ -51,7 +51,7 @@ repos:
- id: validate-pyproject - id: validate-pyproject
- repo: https://github.com/pre-commit/mirrors-mypy - repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.5.1 rev: v1.6.0
hooks: hooks:
- id: mypy - id: mypy
args: args:

View File

@ -532,6 +532,7 @@
* [Logistic Regression](machine_learning/logistic_regression.py) * [Logistic Regression](machine_learning/logistic_regression.py)
* Loss Functions * Loss Functions
* [Binary Cross Entropy](machine_learning/loss_functions/binary_cross_entropy.py) * [Binary Cross Entropy](machine_learning/loss_functions/binary_cross_entropy.py)
* [Categorical Cross Entropy](machine_learning/loss_functions/categorical_cross_entropy.py)
* [Huber Loss](machine_learning/loss_functions/huber_loss.py) * [Huber Loss](machine_learning/loss_functions/huber_loss.py)
* [Mean Squared Error](machine_learning/loss_functions/mean_squared_error.py) * [Mean Squared Error](machine_learning/loss_functions/mean_squared_error.py)
* [Mfcc](machine_learning/mfcc.py) * [Mfcc](machine_learning/mfcc.py)

View File

@ -83,7 +83,8 @@ def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
(1, -2, 3) (1, -2, 3)
""" """
assert a >= 0 and b >= 0 assert a >= 0
assert b >= 0
if b == 0: if b == 0:
d, x, y = a, 1, 0 d, x, y = a, 1, 0
@ -92,7 +93,8 @@ def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
x = q x = q
y = p - q * (a // b) y = p - q * (a // b)
assert a % d == 0 and b % d == 0 assert a % d == 0
assert b % d == 0
assert d == a * x + b * y assert d == a * x + b * y
return (d, x, y) return (d, x, y)

View File

@ -38,7 +38,8 @@ class XORCipher:
""" """
# precondition # precondition
assert isinstance(key, int) and isinstance(content, str) assert isinstance(key, int)
assert isinstance(content, str)
key = key or self.__key or 1 key = key or self.__key or 1
@ -56,7 +57,8 @@ class XORCipher:
""" """
# precondition # precondition
assert isinstance(key, int) and isinstance(content, list) assert isinstance(key, int)
assert isinstance(content, list)
key = key or self.__key or 1 key = key or self.__key or 1
@ -74,7 +76,8 @@ class XORCipher:
""" """
# precondition # precondition
assert isinstance(key, int) and isinstance(content, str) assert isinstance(key, int)
assert isinstance(content, str)
key = key or self.__key or 1 key = key or self.__key or 1
@ -99,7 +102,8 @@ class XORCipher:
""" """
# precondition # precondition
assert isinstance(key, int) and isinstance(content, str) assert isinstance(key, int)
assert isinstance(content, str)
key = key or self.__key or 1 key = key or self.__key or 1
@ -125,7 +129,8 @@ class XORCipher:
""" """
# precondition # precondition
assert isinstance(file, str) and isinstance(key, int) assert isinstance(file, str)
assert isinstance(key, int)
try: try:
with open(file) as fin, open("encrypt.out", "w+") as fout: with open(file) as fin, open("encrypt.out", "w+") as fout:
@ -148,7 +153,8 @@ class XORCipher:
""" """
# precondition # precondition
assert isinstance(file, str) and isinstance(key, int) assert isinstance(file, str)
assert isinstance(key, int)
try: try:
with open(file) as fin, open("decrypt.out", "w+") as fout: with open(file) as fin, open("decrypt.out", "w+") as fout:

View File

@ -57,7 +57,8 @@ def decimal_to_hexadecimal(decimal: float) -> str:
>>> decimal_to_hexadecimal(-256) == hex(-256) >>> decimal_to_hexadecimal(-256) == hex(-256)
True True
""" """
assert type(decimal) in (int, float) and decimal == int(decimal) assert isinstance(decimal, (int, float))
assert decimal == int(decimal)
decimal = int(decimal) decimal = int(decimal)
hexadecimal = "" hexadecimal = ""
negative = False negative = False

View File

@ -12,6 +12,8 @@ from __future__ import annotations
import unittest import unittest
from collections.abc import Iterator from collections.abc import Iterator
import pytest
class Node: class Node:
def __init__(self, label: int, parent: Node | None) -> None: def __init__(self, label: int, parent: Node | None) -> None:
@ -78,7 +80,7 @@ class BinarySearchTree:
node.right = self._put(node.right, label, node) node.right = self._put(node.right, label, node)
else: else:
msg = f"Node with label {label} already exists" msg = f"Node with label {label} already exists"
raise Exception(msg) raise ValueError(msg)
return node return node
@ -95,14 +97,14 @@ class BinarySearchTree:
>>> node = t.search(3) >>> node = t.search(3)
Traceback (most recent call last): Traceback (most recent call last):
... ...
Exception: Node with label 3 does not exist ValueError: Node with label 3 does not exist
""" """
return self._search(self.root, label) return self._search(self.root, label)
def _search(self, node: Node | None, label: int) -> Node: def _search(self, node: Node | None, label: int) -> Node:
if node is None: if node is None:
msg = f"Node with label {label} does not exist" msg = f"Node with label {label} does not exist"
raise Exception(msg) raise ValueError(msg)
else: else:
if label < node.label: if label < node.label:
node = self._search(node.left, label) node = self._search(node.left, label)
@ -124,7 +126,7 @@ class BinarySearchTree:
>>> t.remove(3) >>> t.remove(3)
Traceback (most recent call last): Traceback (most recent call last):
... ...
Exception: Node with label 3 does not exist ValueError: Node with label 3 does not exist
""" """
node = self.search(label) node = self.search(label)
if node.right and node.left: if node.right and node.left:
@ -179,7 +181,7 @@ class BinarySearchTree:
try: try:
self.search(label) self.search(label)
return True return True
except Exception: except ValueError:
return False return False
def get_max_label(self) -> int: def get_max_label(self) -> int:
@ -190,7 +192,7 @@ class BinarySearchTree:
>>> t.get_max_label() >>> t.get_max_label()
Traceback (most recent call last): Traceback (most recent call last):
... ...
Exception: Binary search tree is empty ValueError: Binary search tree is empty
>>> t.put(8) >>> t.put(8)
>>> t.put(10) >>> t.put(10)
@ -198,7 +200,7 @@ class BinarySearchTree:
10 10
""" """
if self.root is None: if self.root is None:
raise Exception("Binary search tree is empty") raise ValueError("Binary search tree is empty")
node = self.root node = self.root
while node.right is not None: while node.right is not None:
@ -214,7 +216,7 @@ class BinarySearchTree:
>>> t.get_min_label() >>> t.get_min_label()
Traceback (most recent call last): Traceback (most recent call last):
... ...
Exception: Binary search tree is empty ValueError: Binary search tree is empty
>>> t.put(8) >>> t.put(8)
>>> t.put(10) >>> t.put(10)
@ -222,7 +224,7 @@ class BinarySearchTree:
8 8
""" """
if self.root is None: if self.root is None:
raise Exception("Binary search tree is empty") raise ValueError("Binary search tree is empty")
node = self.root node = self.root
while node.left is not None: while node.left is not None:
@ -359,7 +361,7 @@ class BinarySearchTreeTest(unittest.TestCase):
assert t.root.left.left.parent == t.root.left assert t.root.left.left.parent == t.root.left
assert t.root.left.left.label == 1 assert t.root.left.left.label == 1
with self.assertRaises(Exception): # noqa: B017 with pytest.raises(ValueError):
t.put(1) t.put(1)
def test_search(self) -> None: def test_search(self) -> None:
@ -371,7 +373,7 @@ class BinarySearchTreeTest(unittest.TestCase):
node = t.search(13) node = t.search(13)
assert node.label == 13 assert node.label == 13
with self.assertRaises(Exception): # noqa: B017 with pytest.raises(ValueError):
t.search(2) t.search(2)
def test_remove(self) -> None: def test_remove(self) -> None:
@ -517,7 +519,7 @@ class BinarySearchTreeTest(unittest.TestCase):
assert t.get_max_label() == 14 assert t.get_max_label() == 14
t.empty() t.empty()
with self.assertRaises(Exception): # noqa: B017 with pytest.raises(ValueError):
t.get_max_label() t.get_max_label()
def test_get_min_label(self) -> None: def test_get_min_label(self) -> None:
@ -526,7 +528,7 @@ class BinarySearchTreeTest(unittest.TestCase):
assert t.get_min_label() == 1 assert t.get_min_label() == 1
t.empty() t.empty()
with self.assertRaises(Exception): # noqa: B017 with pytest.raises(ValueError):
t.get_min_label() t.get_min_label()
def test_inorder_traversal(self) -> None: def test_inorder_traversal(self) -> None:

View File

@ -65,14 +65,14 @@ _add_with_resize_down = [
@pytest.mark.parametrize( @pytest.mark.parametrize(
"operations", "operations",
( [
pytest.param(_add_items, id="add items"), pytest.param(_add_items, id="add items"),
pytest.param(_overwrite_items, id="overwrite items"), pytest.param(_overwrite_items, id="overwrite items"),
pytest.param(_delete_items, id="delete items"), pytest.param(_delete_items, id="delete items"),
pytest.param(_access_absent_items, id="access absent items"), pytest.param(_access_absent_items, id="access absent items"),
pytest.param(_add_with_resize_up, id="add with resize up"), pytest.param(_add_with_resize_up, id="add with resize up"),
pytest.param(_add_with_resize_down, id="add with resize down"), pytest.param(_add_with_resize_down, id="add with resize down"),
), ],
) )
def test_hash_map_is_the_same_as_dict(operations): def test_hash_map_is_the_same_as_dict(operations):
my = HashMap(initial_block_size=4) my = HashMap(initial_block_size=4)

View File

@ -124,7 +124,8 @@ class CircularLinkedList:
if not 0 <= index < len(self): if not 0 <= index < len(self):
raise IndexError("list index out of range.") raise IndexError("list index out of range.")
assert self.head is not None and self.tail is not None assert self.head is not None
assert self.tail is not None
delete_node: Node = self.head delete_node: Node = self.head
if self.head == self.tail: # Just one node if self.head == self.tail: # Just one node
self.head = self.tail = None self.head = self.tail = None
@ -137,7 +138,8 @@ class CircularLinkedList:
for _ in range(index - 1): for _ in range(index - 1):
assert temp is not None assert temp is not None
temp = temp.next temp = temp.next
assert temp is not None and temp.next is not None assert temp is not None
assert temp.next is not None
delete_node = temp.next delete_node = temp.next
temp.next = temp.next.next temp.next = temp.next.next
if index == len(self) - 1: # Delete at tail if index == len(self) - 1: # Delete at tail

View File

@ -73,7 +73,8 @@ def test_median_filter():
def test_sobel_filter(): def test_sobel_filter():
grad, theta = sob.sobel_filter(gray) grad, theta = sob.sobel_filter(gray)
assert grad.any() and theta.any() assert grad.any()
assert theta.any()
def test_sepia(): def test_sepia():

View File

@ -22,6 +22,8 @@ import unittest
from pprint import pformat from pprint import pformat
from typing import Generic, TypeVar from typing import Generic, TypeVar
import pytest
T = TypeVar("T") T = TypeVar("T")
@ -185,9 +187,9 @@ class TestGraphAdjacencyList(unittest.TestCase):
directed_graph: GraphAdjacencyList, directed_graph: GraphAdjacencyList,
edge: list[int], edge: list[int],
) -> None: ) -> None:
self.assertTrue(undirected_graph.contains_edge(edge[0], edge[1])) assert undirected_graph.contains_edge(edge[0], edge[1])
self.assertTrue(undirected_graph.contains_edge(edge[1], edge[0])) assert undirected_graph.contains_edge(edge[1], edge[0])
self.assertTrue(directed_graph.contains_edge(edge[0], edge[1])) assert directed_graph.contains_edge(edge[0], edge[1])
def __assert_graph_edge_does_not_exist_check( def __assert_graph_edge_does_not_exist_check(
self, self,
@ -195,9 +197,9 @@ class TestGraphAdjacencyList(unittest.TestCase):
directed_graph: GraphAdjacencyList, directed_graph: GraphAdjacencyList,
edge: list[int], edge: list[int],
) -> None: ) -> None:
self.assertFalse(undirected_graph.contains_edge(edge[0], edge[1])) assert not undirected_graph.contains_edge(edge[0], edge[1])
self.assertFalse(undirected_graph.contains_edge(edge[1], edge[0])) assert not undirected_graph.contains_edge(edge[1], edge[0])
self.assertFalse(directed_graph.contains_edge(edge[0], edge[1])) assert not directed_graph.contains_edge(edge[0], edge[1])
def __assert_graph_vertex_exists_check( def __assert_graph_vertex_exists_check(
self, self,
@ -205,8 +207,8 @@ class TestGraphAdjacencyList(unittest.TestCase):
directed_graph: GraphAdjacencyList, directed_graph: GraphAdjacencyList,
vertex: int, vertex: int,
) -> None: ) -> None:
self.assertTrue(undirected_graph.contains_vertex(vertex)) assert undirected_graph.contains_vertex(vertex)
self.assertTrue(directed_graph.contains_vertex(vertex)) assert directed_graph.contains_vertex(vertex)
def __assert_graph_vertex_does_not_exist_check( def __assert_graph_vertex_does_not_exist_check(
self, self,
@ -214,13 +216,13 @@ class TestGraphAdjacencyList(unittest.TestCase):
directed_graph: GraphAdjacencyList, directed_graph: GraphAdjacencyList,
vertex: int, vertex: int,
) -> None: ) -> None:
self.assertFalse(undirected_graph.contains_vertex(vertex)) assert not undirected_graph.contains_vertex(vertex)
self.assertFalse(directed_graph.contains_vertex(vertex)) assert not directed_graph.contains_vertex(vertex)
def __generate_random_edges( def __generate_random_edges(
self, vertices: list[int], edge_pick_count: int self, vertices: list[int], edge_pick_count: int
) -> list[list[int]]: ) -> list[list[int]]:
self.assertTrue(edge_pick_count <= len(vertices)) assert edge_pick_count <= len(vertices)
random_source_vertices: list[int] = random.sample( random_source_vertices: list[int] = random.sample(
vertices[0 : int(len(vertices) / 2)], edge_pick_count vertices[0 : int(len(vertices) / 2)], edge_pick_count
@ -281,8 +283,8 @@ class TestGraphAdjacencyList(unittest.TestCase):
self.__assert_graph_edge_exists_check( self.__assert_graph_edge_exists_check(
undirected_graph, directed_graph, edge undirected_graph, directed_graph, edge
) )
self.assertFalse(undirected_graph.directed) assert not undirected_graph.directed
self.assertTrue(directed_graph.directed) assert directed_graph.directed
def test_contains_vertex(self) -> None: def test_contains_vertex(self) -> None:
random_vertices: list[int] = random.sample(range(101), 20) random_vertices: list[int] = random.sample(range(101), 20)
@ -297,12 +299,8 @@ class TestGraphAdjacencyList(unittest.TestCase):
# Test contains_vertex # Test contains_vertex
for num in range(101): for num in range(101):
self.assertEqual( assert (num in random_vertices) == undirected_graph.contains_vertex(num)
num in random_vertices, undirected_graph.contains_vertex(num) assert (num in random_vertices) == directed_graph.contains_vertex(num)
)
self.assertEqual(
num in random_vertices, directed_graph.contains_vertex(num)
)
def test_add_vertices(self) -> None: def test_add_vertices(self) -> None:
random_vertices: list[int] = random.sample(range(101), 20) random_vertices: list[int] = random.sample(range(101), 20)
@ -507,9 +505,9 @@ class TestGraphAdjacencyList(unittest.TestCase):
) = self.__generate_graphs(20, 0, 100, 4) ) = self.__generate_graphs(20, 0, 100, 4)
for vertex in random_vertices: for vertex in random_vertices:
with self.assertRaises(ValueError): with pytest.raises(ValueError):
undirected_graph.add_vertex(vertex) undirected_graph.add_vertex(vertex)
with self.assertRaises(ValueError): with pytest.raises(ValueError):
directed_graph.add_vertex(vertex) directed_graph.add_vertex(vertex)
def test_remove_vertex_exception_check(self) -> None: def test_remove_vertex_exception_check(self) -> None:
@ -522,9 +520,9 @@ class TestGraphAdjacencyList(unittest.TestCase):
for i in range(101): for i in range(101):
if i not in random_vertices: if i not in random_vertices:
with self.assertRaises(ValueError): with pytest.raises(ValueError):
undirected_graph.remove_vertex(i) undirected_graph.remove_vertex(i)
with self.assertRaises(ValueError): with pytest.raises(ValueError):
directed_graph.remove_vertex(i) directed_graph.remove_vertex(i)
def test_add_edge_exception_check(self) -> None: def test_add_edge_exception_check(self) -> None:
@ -536,9 +534,9 @@ class TestGraphAdjacencyList(unittest.TestCase):
) = self.__generate_graphs(20, 0, 100, 4) ) = self.__generate_graphs(20, 0, 100, 4)
for edge in random_edges: for edge in random_edges:
with self.assertRaises(ValueError): with pytest.raises(ValueError):
undirected_graph.add_edge(edge[0], edge[1]) undirected_graph.add_edge(edge[0], edge[1])
with self.assertRaises(ValueError): with pytest.raises(ValueError):
directed_graph.add_edge(edge[0], edge[1]) directed_graph.add_edge(edge[0], edge[1])
def test_remove_edge_exception_check(self) -> None: def test_remove_edge_exception_check(self) -> None:
@ -560,9 +558,9 @@ class TestGraphAdjacencyList(unittest.TestCase):
more_random_edges.append(edge) more_random_edges.append(edge)
for edge in more_random_edges: for edge in more_random_edges:
with self.assertRaises(ValueError): with pytest.raises(ValueError):
undirected_graph.remove_edge(edge[0], edge[1]) undirected_graph.remove_edge(edge[0], edge[1])
with self.assertRaises(ValueError): with pytest.raises(ValueError):
directed_graph.remove_edge(edge[0], edge[1]) directed_graph.remove_edge(edge[0], edge[1])
def test_contains_edge_exception_check(self) -> None: def test_contains_edge_exception_check(self) -> None:
@ -574,14 +572,14 @@ class TestGraphAdjacencyList(unittest.TestCase):
) = self.__generate_graphs(20, 0, 100, 4) ) = self.__generate_graphs(20, 0, 100, 4)
for vertex in random_vertices: for vertex in random_vertices:
with self.assertRaises(ValueError): with pytest.raises(ValueError):
undirected_graph.contains_edge(vertex, 102) undirected_graph.contains_edge(vertex, 102)
with self.assertRaises(ValueError): with pytest.raises(ValueError):
directed_graph.contains_edge(vertex, 102) directed_graph.contains_edge(vertex, 102)
with self.assertRaises(ValueError): with pytest.raises(ValueError):
undirected_graph.contains_edge(103, 102) undirected_graph.contains_edge(103, 102)
with self.assertRaises(ValueError): with pytest.raises(ValueError):
directed_graph.contains_edge(103, 102) directed_graph.contains_edge(103, 102)

View File

@ -22,6 +22,8 @@ import unittest
from pprint import pformat from pprint import pformat
from typing import Generic, TypeVar from typing import Generic, TypeVar
import pytest
T = TypeVar("T") T = TypeVar("T")
@ -203,9 +205,9 @@ class TestGraphMatrix(unittest.TestCase):
directed_graph: GraphAdjacencyMatrix, directed_graph: GraphAdjacencyMatrix,
edge: list[int], edge: list[int],
) -> None: ) -> None:
self.assertTrue(undirected_graph.contains_edge(edge[0], edge[1])) assert undirected_graph.contains_edge(edge[0], edge[1])
self.assertTrue(undirected_graph.contains_edge(edge[1], edge[0])) assert undirected_graph.contains_edge(edge[1], edge[0])
self.assertTrue(directed_graph.contains_edge(edge[0], edge[1])) assert directed_graph.contains_edge(edge[0], edge[1])
def __assert_graph_edge_does_not_exist_check( def __assert_graph_edge_does_not_exist_check(
self, self,
@ -213,9 +215,9 @@ class TestGraphMatrix(unittest.TestCase):
directed_graph: GraphAdjacencyMatrix, directed_graph: GraphAdjacencyMatrix,
edge: list[int], edge: list[int],
) -> None: ) -> None:
self.assertFalse(undirected_graph.contains_edge(edge[0], edge[1])) assert not undirected_graph.contains_edge(edge[0], edge[1])
self.assertFalse(undirected_graph.contains_edge(edge[1], edge[0])) assert not undirected_graph.contains_edge(edge[1], edge[0])
self.assertFalse(directed_graph.contains_edge(edge[0], edge[1])) assert not directed_graph.contains_edge(edge[0], edge[1])
def __assert_graph_vertex_exists_check( def __assert_graph_vertex_exists_check(
self, self,
@ -223,8 +225,8 @@ class TestGraphMatrix(unittest.TestCase):
directed_graph: GraphAdjacencyMatrix, directed_graph: GraphAdjacencyMatrix,
vertex: int, vertex: int,
) -> None: ) -> None:
self.assertTrue(undirected_graph.contains_vertex(vertex)) assert undirected_graph.contains_vertex(vertex)
self.assertTrue(directed_graph.contains_vertex(vertex)) assert directed_graph.contains_vertex(vertex)
def __assert_graph_vertex_does_not_exist_check( def __assert_graph_vertex_does_not_exist_check(
self, self,
@ -232,13 +234,13 @@ class TestGraphMatrix(unittest.TestCase):
directed_graph: GraphAdjacencyMatrix, directed_graph: GraphAdjacencyMatrix,
vertex: int, vertex: int,
) -> None: ) -> None:
self.assertFalse(undirected_graph.contains_vertex(vertex)) assert not undirected_graph.contains_vertex(vertex)
self.assertFalse(directed_graph.contains_vertex(vertex)) assert not directed_graph.contains_vertex(vertex)
def __generate_random_edges( def __generate_random_edges(
self, vertices: list[int], edge_pick_count: int self, vertices: list[int], edge_pick_count: int
) -> list[list[int]]: ) -> list[list[int]]:
self.assertTrue(edge_pick_count <= len(vertices)) assert edge_pick_count <= len(vertices)
random_source_vertices: list[int] = random.sample( random_source_vertices: list[int] = random.sample(
vertices[0 : int(len(vertices) / 2)], edge_pick_count vertices[0 : int(len(vertices) / 2)], edge_pick_count
@ -300,8 +302,8 @@ class TestGraphMatrix(unittest.TestCase):
undirected_graph, directed_graph, edge undirected_graph, directed_graph, edge
) )
self.assertFalse(undirected_graph.directed) assert not undirected_graph.directed
self.assertTrue(directed_graph.directed) assert directed_graph.directed
def test_contains_vertex(self) -> None: def test_contains_vertex(self) -> None:
random_vertices: list[int] = random.sample(range(101), 20) random_vertices: list[int] = random.sample(range(101), 20)
@ -316,12 +318,8 @@ class TestGraphMatrix(unittest.TestCase):
# Test contains_vertex # Test contains_vertex
for num in range(101): for num in range(101):
self.assertEqual( assert (num in random_vertices) == undirected_graph.contains_vertex(num)
num in random_vertices, undirected_graph.contains_vertex(num) assert (num in random_vertices) == directed_graph.contains_vertex(num)
)
self.assertEqual(
num in random_vertices, directed_graph.contains_vertex(num)
)
def test_add_vertices(self) -> None: def test_add_vertices(self) -> None:
random_vertices: list[int] = random.sample(range(101), 20) random_vertices: list[int] = random.sample(range(101), 20)
@ -526,9 +524,9 @@ class TestGraphMatrix(unittest.TestCase):
) = self.__generate_graphs(20, 0, 100, 4) ) = self.__generate_graphs(20, 0, 100, 4)
for vertex in random_vertices: for vertex in random_vertices:
with self.assertRaises(ValueError): with pytest.raises(ValueError):
undirected_graph.add_vertex(vertex) undirected_graph.add_vertex(vertex)
with self.assertRaises(ValueError): with pytest.raises(ValueError):
directed_graph.add_vertex(vertex) directed_graph.add_vertex(vertex)
def test_remove_vertex_exception_check(self) -> None: def test_remove_vertex_exception_check(self) -> None:
@ -541,9 +539,9 @@ class TestGraphMatrix(unittest.TestCase):
for i in range(101): for i in range(101):
if i not in random_vertices: if i not in random_vertices:
with self.assertRaises(ValueError): with pytest.raises(ValueError):
undirected_graph.remove_vertex(i) undirected_graph.remove_vertex(i)
with self.assertRaises(ValueError): with pytest.raises(ValueError):
directed_graph.remove_vertex(i) directed_graph.remove_vertex(i)
def test_add_edge_exception_check(self) -> None: def test_add_edge_exception_check(self) -> None:
@ -555,9 +553,9 @@ class TestGraphMatrix(unittest.TestCase):
) = self.__generate_graphs(20, 0, 100, 4) ) = self.__generate_graphs(20, 0, 100, 4)
for edge in random_edges: for edge in random_edges:
with self.assertRaises(ValueError): with pytest.raises(ValueError):
undirected_graph.add_edge(edge[0], edge[1]) undirected_graph.add_edge(edge[0], edge[1])
with self.assertRaises(ValueError): with pytest.raises(ValueError):
directed_graph.add_edge(edge[0], edge[1]) directed_graph.add_edge(edge[0], edge[1])
def test_remove_edge_exception_check(self) -> None: def test_remove_edge_exception_check(self) -> None:
@ -579,9 +577,9 @@ class TestGraphMatrix(unittest.TestCase):
more_random_edges.append(edge) more_random_edges.append(edge)
for edge in more_random_edges: for edge in more_random_edges:
with self.assertRaises(ValueError): with pytest.raises(ValueError):
undirected_graph.remove_edge(edge[0], edge[1]) undirected_graph.remove_edge(edge[0], edge[1])
with self.assertRaises(ValueError): with pytest.raises(ValueError):
directed_graph.remove_edge(edge[0], edge[1]) directed_graph.remove_edge(edge[0], edge[1])
def test_contains_edge_exception_check(self) -> None: def test_contains_edge_exception_check(self) -> None:
@ -593,14 +591,14 @@ class TestGraphMatrix(unittest.TestCase):
) = self.__generate_graphs(20, 0, 100, 4) ) = self.__generate_graphs(20, 0, 100, 4)
for vertex in random_vertices: for vertex in random_vertices:
with self.assertRaises(ValueError): with pytest.raises(ValueError):
undirected_graph.contains_edge(vertex, 102) undirected_graph.contains_edge(vertex, 102)
with self.assertRaises(ValueError): with pytest.raises(ValueError):
directed_graph.contains_edge(vertex, 102) directed_graph.contains_edge(vertex, 102)
with self.assertRaises(ValueError): with pytest.raises(ValueError):
undirected_graph.contains_edge(103, 102) undirected_graph.contains_edge(103, 102)
with self.assertRaises(ValueError): with pytest.raises(ValueError):
directed_graph.contains_edge(103, 102) directed_graph.contains_edge(103, 102)

View File

@ -203,7 +203,7 @@ class SHA256HashTest(unittest.TestCase):
import hashlib import hashlib
msg = bytes("Test String", "utf-8") msg = bytes("Test String", "utf-8")
self.assertEqual(SHA256(msg).hash, hashlib.sha256(msg).hexdigest()) assert SHA256(msg).hash == hashlib.sha256(msg).hexdigest()
def main() -> None: def main() -> None:

View File

@ -1,5 +1,7 @@
import unittest import unittest
import pytest
from knapsack import greedy_knapsack as kp from knapsack import greedy_knapsack as kp
@ -16,7 +18,7 @@ class TestClass(unittest.TestCase):
profit = [10, 20, 30, 40, 50, 60] profit = [10, 20, 30, 40, 50, 60]
weight = [2, 4, 6, 8, 10, 12] weight = [2, 4, 6, 8, 10, 12]
max_weight = 100 max_weight = 100
self.assertEqual(kp.calc_profit(profit, weight, max_weight), 210) assert kp.calc_profit(profit, weight, max_weight) == 210
def test_negative_max_weight(self): def test_negative_max_weight(self):
""" """
@ -26,7 +28,7 @@ class TestClass(unittest.TestCase):
# profit = [10, 20, 30, 40, 50, 60] # profit = [10, 20, 30, 40, 50, 60]
# weight = [2, 4, 6, 8, 10, 12] # weight = [2, 4, 6, 8, 10, 12]
# max_weight = -15 # max_weight = -15
self.assertRaisesRegex(ValueError, "max_weight must greater than zero.") pytest.raises(ValueError, match="max_weight must greater than zero.")
def test_negative_profit_value(self): def test_negative_profit_value(self):
""" """
@ -36,7 +38,7 @@ class TestClass(unittest.TestCase):
# profit = [10, -20, 30, 40, 50, 60] # profit = [10, -20, 30, 40, 50, 60]
# weight = [2, 4, 6, 8, 10, 12] # weight = [2, 4, 6, 8, 10, 12]
# max_weight = 15 # max_weight = 15
self.assertRaisesRegex(ValueError, "Weight can not be negative.") pytest.raises(ValueError, match="Weight can not be negative.")
def test_negative_weight_value(self): def test_negative_weight_value(self):
""" """
@ -46,7 +48,7 @@ class TestClass(unittest.TestCase):
# profit = [10, 20, 30, 40, 50, 60] # profit = [10, 20, 30, 40, 50, 60]
# weight = [2, -4, 6, -8, 10, 12] # weight = [2, -4, 6, -8, 10, 12]
# max_weight = 15 # max_weight = 15
self.assertRaisesRegex(ValueError, "Profit can not be negative.") pytest.raises(ValueError, match="Profit can not be negative.")
def test_null_max_weight(self): def test_null_max_weight(self):
""" """
@ -56,7 +58,7 @@ class TestClass(unittest.TestCase):
# profit = [10, 20, 30, 40, 50, 60] # profit = [10, 20, 30, 40, 50, 60]
# weight = [2, 4, 6, 8, 10, 12] # weight = [2, 4, 6, 8, 10, 12]
# max_weight = null # max_weight = null
self.assertRaisesRegex(ValueError, "max_weight must greater than zero.") pytest.raises(ValueError, match="max_weight must greater than zero.")
def test_unequal_list_length(self): def test_unequal_list_length(self):
""" """
@ -66,9 +68,7 @@ class TestClass(unittest.TestCase):
# profit = [10, 20, 30, 40, 50] # profit = [10, 20, 30, 40, 50]
# weight = [2, 4, 6, 8, 10, 12] # weight = [2, 4, 6, 8, 10, 12]
# max_weight = 100 # max_weight = 100
self.assertRaisesRegex( pytest.raises(IndexError, match="The length of profit and weight must be same.")
IndexError, "The length of profit and weight must be same."
)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -20,12 +20,12 @@ class Test(unittest.TestCase):
val = [0] val = [0]
w = [0] w = [0]
c = len(val) c = len(val)
self.assertEqual(k.knapsack(cap, w, val, c), 0) assert k.knapsack(cap, w, val, c) == 0
val = [60] val = [60]
w = [10] w = [10]
c = len(val) c = len(val)
self.assertEqual(k.knapsack(cap, w, val, c), 0) assert k.knapsack(cap, w, val, c) == 0
def test_easy_case(self): def test_easy_case(self):
""" """
@ -35,7 +35,7 @@ class Test(unittest.TestCase):
val = [1, 2, 3] val = [1, 2, 3]
w = [3, 2, 1] w = [3, 2, 1]
c = len(val) c = len(val)
self.assertEqual(k.knapsack(cap, w, val, c), 5) assert k.knapsack(cap, w, val, c) == 5
def test_knapsack(self): def test_knapsack(self):
""" """
@ -45,7 +45,7 @@ class Test(unittest.TestCase):
val = [60, 100, 120] val = [60, 100, 120]
w = [10, 20, 30] w = [10, 20, 30]
c = len(val) c = len(val)
self.assertEqual(k.knapsack(cap, w, val, c), 220) assert k.knapsack(cap, w, val, c) == 220
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -200,7 +200,8 @@ def unit_basis_vector(dimension: int, pos: int) -> Vector:
at index 'pos' (indexing at 0) at index 'pos' (indexing at 0)
""" """
# precondition # precondition
assert isinstance(dimension, int) and (isinstance(pos, int)) assert isinstance(dimension, int)
assert isinstance(pos, int)
ans = [0] * dimension ans = [0] * dimension
ans[pos] = 1 ans[pos] = 1
return Vector(ans) return Vector(ans)
@ -213,11 +214,9 @@ def axpy(scalar: float, x: Vector, y: Vector) -> Vector:
computes the axpy operation computes the axpy operation
""" """
# precondition # precondition
assert ( assert isinstance(x, Vector)
isinstance(x, Vector) assert isinstance(y, Vector)
and isinstance(y, Vector) assert isinstance(scalar, (int, float))
and (isinstance(scalar, (int, float)))
)
return x * scalar + y return x * scalar + y

View File

@ -1,6 +1,7 @@
import unittest import unittest
import numpy as np import numpy as np
import pytest
def schur_complement( def schur_complement(
@ -70,14 +71,14 @@ class TestSchurComplement(unittest.TestCase):
det_a = np.linalg.det(a) det_a = np.linalg.det(a)
det_s = np.linalg.det(s) det_s = np.linalg.det(s)
self.assertAlmostEqual(det_x, det_a * det_s) assert np.is_close(det_x, det_a * det_s)
def test_improper_a_b_dimensions(self) -> None: def test_improper_a_b_dimensions(self) -> None:
a = np.array([[1, 2, 1], [2, 1, 2], [3, 2, 4]]) a = np.array([[1, 2, 1], [2, 1, 2], [3, 2, 4]])
b = np.array([[0, 3], [3, 0], [2, 3]]) b = np.array([[0, 3], [3, 0], [2, 3]])
c = np.array([[2, 1], [6, 3]]) c = np.array([[2, 1], [6, 3]])
with self.assertRaises(ValueError): with pytest.raises(ValueError):
schur_complement(a, b, c) schur_complement(a, b, c)
def test_improper_b_c_dimensions(self) -> None: def test_improper_b_c_dimensions(self) -> None:
@ -85,7 +86,7 @@ class TestSchurComplement(unittest.TestCase):
b = np.array([[0, 3], [3, 0], [2, 3]]) b = np.array([[0, 3], [3, 0], [2, 3]])
c = np.array([[2, 1, 3], [6, 3, 5]]) c = np.array([[2, 1, 3], [6, 3, 5]])
with self.assertRaises(ValueError): with pytest.raises(ValueError):
schur_complement(a, b, c) schur_complement(a, b, c)

View File

@ -8,6 +8,8 @@ This file contains the test-suite for the linear algebra library.
""" """
import unittest import unittest
import pytest
from .lib import ( from .lib import (
Matrix, Matrix,
Vector, Vector,
@ -24,8 +26,8 @@ class Test(unittest.TestCase):
test for method component() test for method component()
""" """
x = Vector([1, 2, 3]) x = Vector([1, 2, 3])
self.assertEqual(x.component(0), 1) assert x.component(0) == 1
self.assertEqual(x.component(2), 3) assert x.component(2) == 3
_ = Vector() _ = Vector()
def test_str(self) -> None: def test_str(self) -> None:
@ -33,14 +35,14 @@ class Test(unittest.TestCase):
test for method toString() test for method toString()
""" """
x = Vector([0, 0, 0, 0, 0, 1]) x = Vector([0, 0, 0, 0, 0, 1])
self.assertEqual(str(x), "(0,0,0,0,0,1)") assert str(x) == "(0,0,0,0,0,1)"
def test_size(self) -> None: def test_size(self) -> None:
""" """
test for method size() test for method size()
""" """
x = Vector([1, 2, 3, 4]) x = Vector([1, 2, 3, 4])
self.assertEqual(len(x), 4) assert len(x) == 4
def test_euclidean_length(self) -> None: def test_euclidean_length(self) -> None:
""" """
@ -50,10 +52,10 @@ class Test(unittest.TestCase):
y = Vector([1, 2, 3, 4, 5]) y = Vector([1, 2, 3, 4, 5])
z = Vector([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) z = Vector([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
w = Vector([1, -1, 1, -1, 2, -3, 4, -5]) w = Vector([1, -1, 1, -1, 2, -3, 4, -5])
self.assertAlmostEqual(x.euclidean_length(), 2.236, 3) assert x.euclidean_length() == pytest.approx(2.236, abs=1e-3)
self.assertAlmostEqual(y.euclidean_length(), 7.416, 3) assert y.euclidean_length() == pytest.approx(7.416, abs=1e-3)
self.assertEqual(z.euclidean_length(), 0) assert z.euclidean_length() == 0
self.assertAlmostEqual(w.euclidean_length(), 7.616, 3) assert w.euclidean_length() == pytest.approx(7.616, abs=1e-3)
def test_add(self) -> None: def test_add(self) -> None:
""" """
@ -61,9 +63,9 @@ class Test(unittest.TestCase):
""" """
x = Vector([1, 2, 3]) x = Vector([1, 2, 3])
y = Vector([1, 1, 1]) y = Vector([1, 1, 1])
self.assertEqual((x + y).component(0), 2) assert (x + y).component(0) == 2
self.assertEqual((x + y).component(1), 3) assert (x + y).component(1) == 3
self.assertEqual((x + y).component(2), 4) assert (x + y).component(2) == 4
def test_sub(self) -> None: def test_sub(self) -> None:
""" """
@ -71,9 +73,9 @@ class Test(unittest.TestCase):
""" """
x = Vector([1, 2, 3]) x = Vector([1, 2, 3])
y = Vector([1, 1, 1]) y = Vector([1, 1, 1])
self.assertEqual((x - y).component(0), 0) assert (x - y).component(0) == 0
self.assertEqual((x - y).component(1), 1) assert (x - y).component(1) == 1
self.assertEqual((x - y).component(2), 2) assert (x - y).component(2) == 2
def test_mul(self) -> None: def test_mul(self) -> None:
""" """
@ -82,20 +84,20 @@ class Test(unittest.TestCase):
x = Vector([1, 2, 3]) x = Vector([1, 2, 3])
a = Vector([2, -1, 4]) # for test of dot product a = Vector([2, -1, 4]) # for test of dot product
b = Vector([1, -2, -1]) b = Vector([1, -2, -1])
self.assertEqual(str(x * 3.0), "(3.0,6.0,9.0)") assert str(x * 3.0) == "(3.0,6.0,9.0)"
self.assertEqual((a * b), 0) assert a * b == 0
def test_zero_vector(self) -> None: def test_zero_vector(self) -> None:
""" """
test for global function zero_vector() test for global function zero_vector()
""" """
self.assertEqual(str(zero_vector(10)).count("0"), 10) assert str(zero_vector(10)).count("0") == 10
def test_unit_basis_vector(self) -> None: def test_unit_basis_vector(self) -> None:
""" """
test for global function unit_basis_vector() test for global function unit_basis_vector()
""" """
self.assertEqual(str(unit_basis_vector(3, 1)), "(0,1,0)") assert str(unit_basis_vector(3, 1)) == "(0,1,0)"
def test_axpy(self) -> None: def test_axpy(self) -> None:
""" """
@ -103,7 +105,7 @@ class Test(unittest.TestCase):
""" """
x = Vector([1, 2, 3]) x = Vector([1, 2, 3])
y = Vector([1, 0, 1]) y = Vector([1, 0, 1])
self.assertEqual(str(axpy(2, x, y)), "(3,4,7)") assert str(axpy(2, x, y)) == "(3,4,7)"
def test_copy(self) -> None: def test_copy(self) -> None:
""" """
@ -111,7 +113,7 @@ class Test(unittest.TestCase):
""" """
x = Vector([1, 0, 0, 0, 0, 0]) x = Vector([1, 0, 0, 0, 0, 0])
y = x.copy() y = x.copy()
self.assertEqual(str(x), str(y)) assert str(x) == str(y)
def test_change_component(self) -> None: def test_change_component(self) -> None:
""" """
@ -120,14 +122,14 @@ class Test(unittest.TestCase):
x = Vector([1, 0, 0]) x = Vector([1, 0, 0])
x.change_component(0, 0) x.change_component(0, 0)
x.change_component(1, 1) x.change_component(1, 1)
self.assertEqual(str(x), "(0,1,0)") assert str(x) == "(0,1,0)"
def test_str_matrix(self) -> None: def test_str_matrix(self) -> None:
""" """
test for Matrix method str() test for Matrix method str()
""" """
a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3) a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
self.assertEqual("|1,2,3|\n|2,4,5|\n|6,7,8|\n", str(a)) assert str(a) == "|1,2,3|\n|2,4,5|\n|6,7,8|\n"
def test_minor(self) -> None: def test_minor(self) -> None:
""" """
@ -137,7 +139,7 @@ class Test(unittest.TestCase):
minors = [[-3, -14, -10], [-5, -10, -5], [-2, -1, 0]] minors = [[-3, -14, -10], [-5, -10, -5], [-2, -1, 0]]
for x in range(a.height()): for x in range(a.height()):
for y in range(a.width()): for y in range(a.width()):
self.assertEqual(minors[x][y], a.minor(x, y)) assert minors[x][y] == a.minor(x, y)
def test_cofactor(self) -> None: def test_cofactor(self) -> None:
""" """
@ -147,14 +149,14 @@ class Test(unittest.TestCase):
cofactors = [[-3, 14, -10], [5, -10, 5], [-2, 1, 0]] cofactors = [[-3, 14, -10], [5, -10, 5], [-2, 1, 0]]
for x in range(a.height()): for x in range(a.height()):
for y in range(a.width()): for y in range(a.width()):
self.assertEqual(cofactors[x][y], a.cofactor(x, y)) assert cofactors[x][y] == a.cofactor(x, y)
def test_determinant(self) -> None: def test_determinant(self) -> None:
""" """
test for Matrix method determinant() test for Matrix method determinant()
""" """
a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3) a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
self.assertEqual(-5, a.determinant()) assert a.determinant() == -5
def test__mul__matrix(self) -> None: def test__mul__matrix(self) -> None:
""" """
@ -162,8 +164,8 @@ class Test(unittest.TestCase):
""" """
a = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]], 3, 3) a = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]], 3, 3)
x = Vector([1, 2, 3]) x = Vector([1, 2, 3])
self.assertEqual("(14,32,50)", str(a * x)) assert str(a * x) == "(14,32,50)"
self.assertEqual("|2,4,6|\n|8,10,12|\n|14,16,18|\n", str(a * 2)) assert str(a * 2) == "|2,4,6|\n|8,10,12|\n|14,16,18|\n"
def test_change_component_matrix(self) -> None: def test_change_component_matrix(self) -> None:
""" """
@ -171,14 +173,14 @@ class Test(unittest.TestCase):
""" """
a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3) a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
a.change_component(0, 2, 5) a.change_component(0, 2, 5)
self.assertEqual("|1,2,5|\n|2,4,5|\n|6,7,8|\n", str(a)) assert str(a) == "|1,2,5|\n|2,4,5|\n|6,7,8|\n"
def test_component_matrix(self) -> None: def test_component_matrix(self) -> None:
""" """
test for Matrix method component() test for Matrix method component()
""" """
a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3) a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
self.assertEqual(7, a.component(2, 1), 0.01) assert a.component(2, 1) == 7, 0.01
def test__add__matrix(self) -> None: def test__add__matrix(self) -> None:
""" """
@ -186,7 +188,7 @@ class Test(unittest.TestCase):
""" """
a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3) a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
b = Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]], 3, 3) b = Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]], 3, 3)
self.assertEqual("|2,4,10|\n|4,8,10|\n|12,14,18|\n", str(a + b)) assert str(a + b) == "|2,4,10|\n|4,8,10|\n|12,14,18|\n"
def test__sub__matrix(self) -> None: def test__sub__matrix(self) -> None:
""" """
@ -194,15 +196,14 @@ class Test(unittest.TestCase):
""" """
a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3) a = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
b = Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]], 3, 3) b = Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]], 3, 3)
self.assertEqual("|0,0,-4|\n|0,0,0|\n|0,0,-2|\n", str(a - b)) assert str(a - b) == "|0,0,-4|\n|0,0,0|\n|0,0,-2|\n"
def test_square_zero_matrix(self) -> None: def test_square_zero_matrix(self) -> None:
""" """
test for global function square_zero_matrix() test for global function square_zero_matrix()
""" """
self.assertEqual( assert str(square_zero_matrix(5)) == (
"|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", "|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"
str(square_zero_matrix(5)),
) )

View File

@ -169,7 +169,7 @@ def test_linear_discriminant_analysis() -> None:
dimensions = 2 dimensions = 2
# Assert that the function raises an AssertionError if dimensions > classes # Assert that the function raises an AssertionError if dimensions > classes
with pytest.raises(AssertionError) as error_info: with pytest.raises(AssertionError) as error_info: # noqa: PT012
projected_data = linear_discriminant_analysis( projected_data = linear_discriminant_analysis(
features, labels, classes, dimensions features, labels, classes, dimensions
) )
@ -185,7 +185,7 @@ def test_principal_component_analysis() -> None:
dimensions = 2 dimensions = 2
expected_output = np.array([[6.92820323, 8.66025404, 10.39230485], [3.0, 3.0, 3.0]]) expected_output = np.array([[6.92820323, 8.66025404, 10.39230485], [3.0, 3.0, 3.0]])
with pytest.raises(AssertionError) as error_info: with pytest.raises(AssertionError) as error_info: # noqa: PT012
output = principal_component_analysis(features, dimensions) output = principal_component_analysis(features, dimensions)
if not np.allclose(expected_output, output): if not np.allclose(expected_output, output):
raise AssertionError raise AssertionError

View File

@ -128,7 +128,7 @@ def plot_heterogeneity(heterogeneity, k):
def kmeans( def kmeans(
data, k, initial_centroids, maxiter=500, record_heterogeneity=None, verbose=False data, k, initial_centroids, maxiter=500, record_heterogeneity=None, verbose=False
): ):
"""This function runs k-means on given data and initial set of centroids. """Runs k-means on given data and initial set of centroids.
maxiter: maximum number of iterations to run.(default=500) maxiter: maximum number of iterations to run.(default=500)
record_heterogeneity: (optional) a list, to store the history of heterogeneity record_heterogeneity: (optional) a list, to store the history of heterogeneity
as function of iterations as function of iterations
@ -195,20 +195,20 @@ if False: # change to true to run this test case.
def report_generator( def report_generator(
df: pd.DataFrame, clustering_variables: np.ndarray, fill_missing_report=None predicted: pd.DataFrame, clustering_variables: np.ndarray, fill_missing_report=None
) -> pd.DataFrame: ) -> pd.DataFrame:
""" """
Generates a clustering report. This function takes 2 arguments as input: Generate a clustering report given these two arguments:
df - dataframe with predicted cluster column predicted - dataframe with predicted cluster column
fill_missing_report - dictionary of rules on how we are going to fill in missing fill_missing_report - dictionary of rules on how we are going to fill in missing
values for final generated report (not included in modelling); values for final generated report (not included in modelling);
>>> data = pd.DataFrame() >>> predicted = pd.DataFrame()
>>> data['numbers'] = [1, 2, 3] >>> predicted['numbers'] = [1, 2, 3]
>>> data['col1'] = [0.5, 2.5, 4.5] >>> predicted['col1'] = [0.5, 2.5, 4.5]
>>> data['col2'] = [100, 200, 300] >>> predicted['col2'] = [100, 200, 300]
>>> data['col3'] = [10, 20, 30] >>> predicted['col3'] = [10, 20, 30]
>>> data['Cluster'] = [1, 1, 2] >>> predicted['Cluster'] = [1, 1, 2]
>>> report_generator(data, ['col1', 'col2'], 0) >>> report_generator(predicted, ['col1', 'col2'], 0)
Features Type Mark 1 2 Features Type Mark 1 2
0 # of Customers ClusterSize False 2.000000 1.000000 0 # of Customers ClusterSize False 2.000000 1.000000
1 % of Customers ClusterProportion False 0.666667 0.333333 1 % of Customers ClusterProportion False 0.666667 0.333333
@ -226,11 +226,11 @@ def report_generator(
""" """
# Fill missing values with given rules # Fill missing values with given rules
if fill_missing_report: if fill_missing_report:
df = df.fillna(value=fill_missing_report) predicted = predicted.fillna(value=fill_missing_report)
df["dummy"] = 1 predicted["dummy"] = 1
numeric_cols = df.select_dtypes(np.number).columns numeric_cols = predicted.select_dtypes(np.number).columns
report = ( report = (
df.groupby(["Cluster"])[ # construct report dataframe predicted.groupby(["Cluster"])[ # construct report dataframe
numeric_cols numeric_cols
] # group by cluster number ] # group by cluster number
.agg( .agg(
@ -267,46 +267,43 @@ def report_generator(
.rename(index=str, columns={"level_0": "Features", "level_1": "Type"}) .rename(index=str, columns={"level_0": "Features", "level_1": "Type"})
) # rename columns ) # rename columns
# calculate the size of cluster(count of clientID's) # calculate the size of cluster(count of clientID's)
# avoid SettingWithCopyWarning
clustersize = report[ clustersize = report[
(report["Features"] == "dummy") & (report["Type"] == "count") (report["Features"] == "dummy") & (report["Type"] == "count")
].copy() # avoid SettingWithCopyWarning ].copy()
clustersize.Type = ( # rename created predicted cluster to match report column names
"ClusterSize" # rename created cluster df to match report column names clustersize.Type = "ClusterSize"
)
clustersize.Features = "# of Customers" clustersize.Features = "# of Customers"
# calculating the proportion of cluster
clusterproportion = pd.DataFrame( clusterproportion = pd.DataFrame(
clustersize.iloc[:, 2:].values clustersize.iloc[:, 2:].to_numpy() / clustersize.iloc[:, 2:].to_numpy().sum()
/ clustersize.iloc[:, 2:].values.sum() # calculating the proportion of cluster
) )
clusterproportion[ # rename created predicted cluster to match report column names
"Type" clusterproportion["Type"] = "% of Customers"
] = "% of Customers" # rename created cluster df to match report column names
clusterproportion["Features"] = "ClusterProportion" clusterproportion["Features"] = "ClusterProportion"
cols = clusterproportion.columns.tolist() cols = clusterproportion.columns.tolist()
cols = cols[-2:] + cols[:-2] cols = cols[-2:] + cols[:-2]
clusterproportion = clusterproportion[cols] # rearrange columns to match report clusterproportion = clusterproportion[cols] # rearrange columns to match report
clusterproportion.columns = report.columns clusterproportion.columns = report.columns
# generating dataframe with count of nan values
a = pd.DataFrame( a = pd.DataFrame(
abs( abs(
report[report["Type"] == "count"].iloc[:, 2:].values report[report["Type"] == "count"].iloc[:, 2:].to_numpy()
- clustersize.iloc[:, 2:].values - clustersize.iloc[:, 2:].to_numpy()
)
) )
) # generating df with count of nan values
a["Features"] = 0 a["Features"] = 0
a["Type"] = "# of nan" a["Type"] = "# of nan"
a.Features = report[ # filling values in order to match report
report["Type"] == "count" a.Features = report[report["Type"] == "count"].Features.tolist()
].Features.tolist() # filling values in order to match report
cols = a.columns.tolist() cols = a.columns.tolist()
cols = cols[-2:] + cols[:-2] cols = cols[-2:] + cols[:-2]
a = a[cols] # rearrange columns to match report a = a[cols] # rearrange columns to match report
a.columns = report.columns # rename columns to match report a.columns = report.columns # rename columns to match report
report = report.drop( # drop count values except for cluster size
report[report.Type == "count"].index report = report.drop(report[report.Type == "count"].index)
) # drop count values except for cluster size # concat report with cluster size and nan values
report = pd.concat( report = pd.concat([report, a, clustersize, clusterproportion], axis=0)
[report, a, clustersize, clusterproportion], axis=0
) # concat report with cluster size and nan values
report["Mark"] = report["Features"].isin(clustering_variables) report["Mark"] = report["Features"].isin(clustering_variables)
cols = report.columns.tolist() cols = report.columns.tolist()
cols = cols[0:2] + cols[-1:] + cols[2:-1] cols = cols[0:2] + cols[-1:] + cols[2:-1]

View File

@ -67,8 +67,8 @@ class TestLeastCommonMultiple(unittest.TestCase):
slow_result = least_common_multiple_slow(first_num, second_num) slow_result = least_common_multiple_slow(first_num, second_num)
fast_result = least_common_multiple_fast(first_num, second_num) fast_result = least_common_multiple_fast(first_num, second_num)
with self.subTest(i=i): with self.subTest(i=i):
self.assertEqual(slow_result, self.expected_results[i]) assert slow_result == self.expected_results[i]
self.assertEqual(fast_result, self.expected_results[i]) assert fast_result == self.expected_results[i]
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -28,7 +28,9 @@ def modular_division(a: int, b: int, n: int) -> int:
4 4
""" """
assert n > 1 and a > 0 and greatest_common_divisor(a, n) == 1 assert n > 1
assert a > 0
assert greatest_common_divisor(a, n) == 1
(d, t, s) = extended_gcd(n, a) # Implemented below (d, t, s) = extended_gcd(n, a) # Implemented below
x = (b * s) % n x = (b * s) % n
return x return x
@ -86,7 +88,8 @@ def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
** extended_gcd function is used when d = gcd(a,b) is required in output ** extended_gcd function is used when d = gcd(a,b) is required in output
""" """
assert a >= 0 and b >= 0 assert a >= 0
assert b >= 0
if b == 0: if b == 0:
d, x, y = a, 1, 0 d, x, y = a, 1, 0
@ -95,7 +98,8 @@ def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
x = q x = q
y = p - q * (a // b) y = p - q * (a // b)
assert a % d == 0 and b % d == 0 assert a % d == 0
assert b % d == 0
assert d == a * x + b * y assert d == a * x + b * y
return (d, x, y) return (d, x, y)

View File

@ -3,6 +3,8 @@
import math import math
import unittest import unittest
import pytest
def is_prime(number: int) -> bool: def is_prime(number: int) -> bool:
"""Checks to see if a number is a prime in O(sqrt(n)). """Checks to see if a number is a prime in O(sqrt(n)).
@ -50,33 +52,31 @@ def is_prime(number: int) -> bool:
class Test(unittest.TestCase): class Test(unittest.TestCase):
def test_primes(self): def test_primes(self):
self.assertTrue(is_prime(2)) assert is_prime(2)
self.assertTrue(is_prime(3)) assert is_prime(3)
self.assertTrue(is_prime(5)) assert is_prime(5)
self.assertTrue(is_prime(7)) assert is_prime(7)
self.assertTrue(is_prime(11)) assert is_prime(11)
self.assertTrue(is_prime(13)) assert is_prime(13)
self.assertTrue(is_prime(17)) assert is_prime(17)
self.assertTrue(is_prime(19)) assert is_prime(19)
self.assertTrue(is_prime(23)) assert is_prime(23)
self.assertTrue(is_prime(29)) assert is_prime(29)
def test_not_primes(self): def test_not_primes(self):
with self.assertRaises(AssertionError): with pytest.raises(AssertionError):
is_prime(-19) is_prime(-19)
self.assertFalse( assert not is_prime(
is_prime(0), 0
"Zero doesn't have any positive factors, primes must have exactly two.", ), "Zero doesn't have any positive factors, primes must have exactly two."
) assert not is_prime(
self.assertFalse( 1
is_prime(1), ), "One only has 1 positive factor, primes must have exactly two."
"One only has 1 positive factor, primes must have exactly two.", assert not is_prime(2 * 2)
) assert not is_prime(2 * 3)
self.assertFalse(is_prime(2 * 2)) assert not is_prime(3 * 3)
self.assertFalse(is_prime(2 * 3)) assert not is_prime(3 * 5)
self.assertFalse(is_prime(3 * 3)) assert not is_prime(3 * 5 * 7)
self.assertFalse(is_prime(3 * 5))
self.assertFalse(is_prime(3 * 5 * 7))
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -114,7 +114,8 @@ class Matrix:
# Validation # Validation
assert isinstance(another, Matrix) assert isinstance(another, Matrix)
assert self.row == another.row and self.column == another.column assert self.row == another.row
assert self.column == another.column
# Add # Add
result = Matrix(self.row, self.column) result = Matrix(self.row, self.column)
@ -225,7 +226,8 @@ class Matrix:
""" """
# Size validation # Size validation
assert isinstance(u, Matrix) and isinstance(v, Matrix) assert isinstance(u, Matrix)
assert isinstance(v, Matrix)
assert self.row == self.column == u.row == v.row # u, v should be column vector assert self.row == self.column == u.row == v.row # u, v should be column vector
assert u.column == v.column == 1 # u, v should be column vector assert u.column == v.column == 1 # u, v should be column vector

View File

@ -31,14 +31,14 @@ stream_handler = logging.StreamHandler(sys.stdout)
logger.addHandler(stream_handler) logger.addHandler(stream_handler)
@pytest.mark.mat_ops @pytest.mark.mat_ops()
@pytest.mark.parametrize( @pytest.mark.parametrize(
("mat1", "mat2"), [(mat_a, mat_b), (mat_c, mat_d), (mat_d, mat_e), (mat_f, mat_h)] ("mat1", "mat2"), [(mat_a, mat_b), (mat_c, mat_d), (mat_d, mat_e), (mat_f, mat_h)]
) )
def test_addition(mat1, mat2): def test_addition(mat1, mat2):
if (np.array(mat1)).shape < (2, 2) or (np.array(mat2)).shape < (2, 2): if (np.array(mat1)).shape < (2, 2) or (np.array(mat2)).shape < (2, 2):
with pytest.raises(TypeError):
logger.info(f"\n\t{test_addition.__name__} returned integer") logger.info(f"\n\t{test_addition.__name__} returned integer")
with pytest.raises(TypeError):
matop.add(mat1, mat2) matop.add(mat1, mat2)
elif (np.array(mat1)).shape == (np.array(mat2)).shape: elif (np.array(mat1)).shape == (np.array(mat2)).shape:
logger.info(f"\n\t{test_addition.__name__} with same matrix dims") logger.info(f"\n\t{test_addition.__name__} with same matrix dims")
@ -46,19 +46,19 @@ def test_addition(mat1, mat2):
theo = matop.add(mat1, mat2) theo = matop.add(mat1, mat2)
assert theo == act assert theo == act
else: else:
with pytest.raises(ValueError):
logger.info(f"\n\t{test_addition.__name__} with different matrix dims") logger.info(f"\n\t{test_addition.__name__} with different matrix dims")
with pytest.raises(ValueError):
matop.add(mat1, mat2) matop.add(mat1, mat2)
@pytest.mark.mat_ops @pytest.mark.mat_ops()
@pytest.mark.parametrize( @pytest.mark.parametrize(
("mat1", "mat2"), [(mat_a, mat_b), (mat_c, mat_d), (mat_d, mat_e), (mat_f, mat_h)] ("mat1", "mat2"), [(mat_a, mat_b), (mat_c, mat_d), (mat_d, mat_e), (mat_f, mat_h)]
) )
def test_subtraction(mat1, mat2): def test_subtraction(mat1, mat2):
if (np.array(mat1)).shape < (2, 2) or (np.array(mat2)).shape < (2, 2): if (np.array(mat1)).shape < (2, 2) or (np.array(mat2)).shape < (2, 2):
with pytest.raises(TypeError):
logger.info(f"\n\t{test_subtraction.__name__} returned integer") logger.info(f"\n\t{test_subtraction.__name__} returned integer")
with pytest.raises(TypeError):
matop.subtract(mat1, mat2) matop.subtract(mat1, mat2)
elif (np.array(mat1)).shape == (np.array(mat2)).shape: elif (np.array(mat1)).shape == (np.array(mat2)).shape:
logger.info(f"\n\t{test_subtraction.__name__} with same matrix dims") logger.info(f"\n\t{test_subtraction.__name__} with same matrix dims")
@ -66,12 +66,12 @@ def test_subtraction(mat1, mat2):
theo = matop.subtract(mat1, mat2) theo = matop.subtract(mat1, mat2)
assert theo == act assert theo == act
else: else:
with pytest.raises(ValueError):
logger.info(f"\n\t{test_subtraction.__name__} with different matrix dims") logger.info(f"\n\t{test_subtraction.__name__} with different matrix dims")
with pytest.raises(ValueError):
assert matop.subtract(mat1, mat2) assert matop.subtract(mat1, mat2)
@pytest.mark.mat_ops @pytest.mark.mat_ops()
@pytest.mark.parametrize( @pytest.mark.parametrize(
("mat1", "mat2"), [(mat_a, mat_b), (mat_c, mat_d), (mat_d, mat_e), (mat_f, mat_h)] ("mat1", "mat2"), [(mat_a, mat_b), (mat_c, mat_d), (mat_d, mat_e), (mat_f, mat_h)]
) )
@ -86,33 +86,33 @@ def test_multiplication(mat1, mat2):
theo = matop.multiply(mat1, mat2) theo = matop.multiply(mat1, mat2)
assert theo == act assert theo == act
else: else:
with pytest.raises(ValueError):
logger.info( logger.info(
f"\n\t{test_multiplication.__name__} does not meet dim requirements" f"\n\t{test_multiplication.__name__} does not meet dim requirements"
) )
with pytest.raises(ValueError):
assert matop.subtract(mat1, mat2) assert matop.subtract(mat1, mat2)
@pytest.mark.mat_ops @pytest.mark.mat_ops()
def test_scalar_multiply(): def test_scalar_multiply():
act = (3.5 * np.array(mat_a)).tolist() act = (3.5 * np.array(mat_a)).tolist()
theo = matop.scalar_multiply(mat_a, 3.5) theo = matop.scalar_multiply(mat_a, 3.5)
assert theo == act assert theo == act
@pytest.mark.mat_ops @pytest.mark.mat_ops()
def test_identity(): def test_identity():
act = (np.identity(5)).tolist() act = (np.identity(5)).tolist()
theo = matop.identity(5) theo = matop.identity(5)
assert theo == act assert theo == act
@pytest.mark.mat_ops @pytest.mark.mat_ops()
@pytest.mark.parametrize("mat", [mat_a, mat_b, mat_c, mat_d, mat_e, mat_f]) @pytest.mark.parametrize("mat", [mat_a, mat_b, mat_c, mat_d, mat_e, mat_f])
def test_transpose(mat): def test_transpose(mat):
if (np.array(mat)).shape < (2, 2): if (np.array(mat)).shape < (2, 2):
with pytest.raises(TypeError):
logger.info(f"\n\t{test_transpose.__name__} returned integer") logger.info(f"\n\t{test_transpose.__name__} returned integer")
with pytest.raises(TypeError):
matop.transpose(mat) matop.transpose(mat)
else: else:
act = (np.transpose(mat)).tolist() act = (np.transpose(mat)).tolist()

View File

@ -147,39 +147,39 @@ def generate_random_hands(number_of_hands: int = 100):
return (generate_random_hand() for _ in range(number_of_hands)) return (generate_random_hand() for _ in range(number_of_hands))
@pytest.mark.parametrize("hand, expected", TEST_FLUSH) @pytest.mark.parametrize(("hand", "expected"), TEST_FLUSH)
def test_hand_is_flush(hand, expected): def test_hand_is_flush(hand, expected):
assert PokerHand(hand)._is_flush() == expected assert PokerHand(hand)._is_flush() == expected
@pytest.mark.parametrize("hand, expected", TEST_STRAIGHT) @pytest.mark.parametrize(("hand", "expected"), TEST_STRAIGHT)
def test_hand_is_straight(hand, expected): def test_hand_is_straight(hand, expected):
assert PokerHand(hand)._is_straight() == expected assert PokerHand(hand)._is_straight() == expected
@pytest.mark.parametrize("hand, expected, card_values", TEST_FIVE_HIGH_STRAIGHT) @pytest.mark.parametrize(("hand", "expected", "card_values"), TEST_FIVE_HIGH_STRAIGHT)
def test_hand_is_five_high_straight(hand, expected, card_values): def test_hand_is_five_high_straight(hand, expected, card_values):
player = PokerHand(hand) player = PokerHand(hand)
assert player._is_five_high_straight() == expected assert player._is_five_high_straight() == expected
assert player._card_values == card_values assert player._card_values == card_values
@pytest.mark.parametrize("hand, expected", TEST_KIND) @pytest.mark.parametrize(("hand", "expected"), TEST_KIND)
def test_hand_is_same_kind(hand, expected): def test_hand_is_same_kind(hand, expected):
assert PokerHand(hand)._is_same_kind() == expected assert PokerHand(hand)._is_same_kind() == expected
@pytest.mark.parametrize("hand, expected", TEST_TYPES) @pytest.mark.parametrize(("hand", "expected"), TEST_TYPES)
def test_hand_values(hand, expected): def test_hand_values(hand, expected):
assert PokerHand(hand)._hand_type == expected assert PokerHand(hand)._hand_type == expected
@pytest.mark.parametrize("hand, other, expected", TEST_COMPARE) @pytest.mark.parametrize(("hand", "other", "expected"), TEST_COMPARE)
def test_compare_simple(hand, other, expected): def test_compare_simple(hand, other, expected):
assert PokerHand(hand).compare_with(PokerHand(other)) == expected assert PokerHand(hand).compare_with(PokerHand(other)) == expected
@pytest.mark.parametrize("hand, other, expected", generate_random_hands()) @pytest.mark.parametrize(("hand", "other", "expected"), generate_random_hands())
def test_compare_random(hand, other, expected): def test_compare_random(hand, other, expected):
assert PokerHand(hand).compare_with(PokerHand(other)) == expected assert PokerHand(hand).compare_with(PokerHand(other)) == expected

View File

@ -19,6 +19,8 @@ ignore = [ # `ruff rule S101` for a description of that rule
"PLW0120", # `else` clause on loop without a `break` statement -- FIX ME "PLW0120", # `else` clause on loop without a `break` statement -- FIX ME
"PLW060", # Using global for `{name}` but no assignment is done -- DO NOT FIX "PLW060", # Using global for `{name}` but no assignment is done -- DO NOT FIX
"PLW2901", # PLW2901: Redefined loop variable -- FIX ME "PLW2901", # PLW2901: Redefined loop variable -- FIX ME
"PT011", # `pytest.raises(Exception)` is too broad, set the `match` parameter or use a more specific exception
"PT018", # Assertion should be broken down into multiple parts
"RUF00", # Ambiguous unicode character and other rules "RUF00", # Ambiguous unicode character and other rules
"RUF100", # Unused `noqa` directive -- FIX ME "RUF100", # Unused `noqa` directive -- FIX ME
"S101", # Use of `assert` detected -- DO NOT FIX "S101", # Use of `assert` detected -- DO NOT FIX
@ -37,6 +39,7 @@ select = [ # https://beta.ruff.rs/docs/rules
"BLE", # flake8-blind-except "BLE", # flake8-blind-except
"C4", # flake8-comprehensions "C4", # flake8-comprehensions
"C90", # McCabe cyclomatic complexity "C90", # McCabe cyclomatic complexity
"DJ", # flake8-django
"DTZ", # flake8-datetimez "DTZ", # flake8-datetimez
"E", # pycodestyle "E", # pycodestyle
"EM", # flake8-errmsg "EM", # flake8-errmsg
@ -52,9 +55,11 @@ select = [ # https://beta.ruff.rs/docs/rules
"ISC", # flake8-implicit-str-concat "ISC", # flake8-implicit-str-concat
"N", # pep8-naming "N", # pep8-naming
"NPY", # NumPy-specific rules "NPY", # NumPy-specific rules
"PD", # pandas-vet
"PGH", # pygrep-hooks "PGH", # pygrep-hooks
"PIE", # flake8-pie "PIE", # flake8-pie
"PL", # Pylint "PL", # Pylint
"PT", # flake8-pytest-style
"PYI", # flake8-pyi "PYI", # flake8-pyi
"RSE", # flake8-raise "RSE", # flake8-raise
"RUF", # Ruff-specific rules "RUF", # Ruff-specific rules
@ -70,11 +75,8 @@ select = [ # https://beta.ruff.rs/docs/rules
# "ANN", # flake8-annotations # FIX ME? # "ANN", # flake8-annotations # FIX ME?
# "COM", # flake8-commas # "COM", # flake8-commas
# "D", # pydocstyle -- FIX ME? # "D", # pydocstyle -- FIX ME?
# "DJ", # flake8-django
# "ERA", # eradicate -- DO NOT FIX # "ERA", # eradicate -- DO NOT FIX
# "FBT", # flake8-boolean-trap # FIX ME # "FBT", # flake8-boolean-trap # FIX ME
# "PD", # pandas-vet
# "PT", # flake8-pytest-style
# "PTH", # flake8-use-pathlib # FIX ME # "PTH", # flake8-use-pathlib # FIX ME
# "Q", # flake8-quotes # "Q", # flake8-quotes
# "RET", # flake8-return # FIX ME? # "RET", # flake8-return # FIX ME?

View File

@ -71,7 +71,8 @@ if __name__ == "__main__":
pattern = "abc1abc12" pattern = "abc1abc12"
text1 = "alskfjaldsabc1abc1abc12k23adsfabcabc" text1 = "alskfjaldsabc1abc1abc12k23adsfabcabc"
text2 = "alskfjaldsk23adsfabcabc" text2 = "alskfjaldsk23adsfabcabc"
assert knuth_morris_pratt(text1, pattern) and knuth_morris_pratt(text2, pattern) assert knuth_morris_pratt(text1, pattern)
assert knuth_morris_pratt(text2, pattern)
# Test 2) # Test 2)
pattern = "ABABX" pattern = "ABABX"

View File

@ -60,7 +60,8 @@ def test_rabin_karp() -> None:
pattern = "abc1abc12" pattern = "abc1abc12"
text1 = "alskfjaldsabc1abc1abc12k23adsfabcabc" text1 = "alskfjaldsabc1abc1abc12k23adsfabcabc"
text2 = "alskfjaldsk23adsfabcabc" text2 = "alskfjaldsk23adsfabcabc"
assert rabin_karp(pattern, text1) and not rabin_karp(pattern, text2) assert rabin_karp(pattern, text1)
assert not rabin_karp(pattern, text2)
# Test 2) # Test 2)
pattern = "ABABX" pattern = "ABABX"