From f0d64bee733cdff0b2a0eb575c21c56cd92fce80 Mon Sep 17 00:00:00 2001 From: Maximilian Kuehnlein Date: Thu, 22 Oct 2026 23:56:08 +0200 Subject: [PATCH] Organisation Tests --- src/matrixmania/compute.py | 157 ++------------------------ test/test_matrixmania/test_compute.py | 154 ------------------------- test/test_matrixmania/test_matmul.py | 85 ++++++++++++++ 3 files changed, 95 insertions(+), 301 deletions(-) delete mode 100644 test/test_matrixmania/test_compute.py create mode 100644 test/test_matrixmania/test_matmul.py diff --git a/src/matrixmania/compute.py b/src/matrixmania/compute.py index df581c8..f7ad3da 100644 --- a/src/matrixmania/compute.py +++ b/src/matrixmania/compute.py @@ -148,155 +148,18 @@ def project_ortho( return x * scale, y * scale -def project_perspective(point: tuple[float, float, float], - focal_length: float = 1.0, - scale: float = 1.0, - camera_distance: float = 4.0) -> tuple[float, float]: +def project_perspective( + point: tuple[float, float, float], + focal_length: float = 1.0, + scale: float = 1.0, + camera_distance: float = 4.0, +) -> tuple[float, float]: + """Projiziert einen 3D-Punkt perspektivisch auf eine 2D-Ebene.""" x, y, z = point - return (((x * focal_length) / z + camera_distance) * scale, - ((y * focal_length) / z + camera_distance) * scale) - - -def test_functions() -> None: - """Testet die mathematischen Hilfsfunktionen für Matrixoperationen.""" - a1 = [ - [3, 4, -1, 4], - [-2, 2, 5, 1], - ] - b1 = [ - [1, 3, -2], - [2, 5, 1], - [-1, 4, -4], - [2, 3, 6], - ] - expected_c1 = [ - [20, 37, 26], - [-1, 27, -8], - ] - c1 = matmul(a1, b1) - assert c1 == expected_c1, ( - f"Fehler in Beispiel 1: Erwartet {expected_c1}, erhalten {c1}" + return ( + ((x * focal_length) / z + camera_distance) * scale, + ((y * focal_length) / z + camera_distance) * scale, ) - print("Test 1 (Skript-Beispiel) erfolgreich bestanden!") - - a2 = [ - [1, 2], - [3, 4], - ] - identity = [ - [1, 0], - [0, 1], - ] - c2 = matmul(a2, identity) - assert c2 == a2, f"Fehler in Beispiel 2: Erwartet {a2}, erhalten {c2}" - print("Test 2 (Einheitsmatrix) erfolgreich bestanden!") - - incompatible_b = [ - [1, 2], - [3, 4], - ] - try: - matmul(a1, incompatible_b) - raise AssertionError("Fehlerfall wurde nicht abgefangen!") - except ValueError: - print("Test 3 (Fehlerfall inkompatible Dimensionen) erfolgreich abgefangen!") - - # Tests für Transpose - example_matrix = [ - [1, 2, 3], - [4, 5, 6], - ] - expected_transposed = [ - [1, 4], - [2, 5], - [3, 6], - ] - assert transpose(example_matrix) == expected_transposed, ( - f"Erwartet: {expected_transposed}, Erhalten: {transpose(example_matrix)}" - ) - print("Test 4 (transpose) erfolgreich bestanden!") - - # Test transpose: Leere Matrix - try: - transpose([]) - raise AssertionError("Leere Matrix wurde nicht abgefangen!") - except ValueError: - print("Test 5 (transpose leere Matrix) erfolgreich abgefangen!") - - # Test transpose: Ungleichmäßige Zeilenlänge - uneven_matrix = [ - [1, 2, 3], - [4, 5], - ] - try: - transpose(uneven_matrix) - raise AssertionError("Ungleichmäßige Matrix wurde nicht abgefangen!") - except ValueError: - print("Test 6 (transpose ungleichmäßige Matrix) erfolgreich abgefangen!") - - # Test 7: Rotation um 0 Radianten (entspricht der Einheitsmatrix) - rot_0 = rot_2d(0.0) - assert math.isclose(rot_0[0][0], 1.0, abs_tol=1e-9) - assert math.isclose(rot_0[0][1], 0.0, abs_tol=1e-9) - assert math.isclose(rot_0[1][0], 0.0, abs_tol=1e-9) - assert math.isclose(rot_0[1][1], 1.0, abs_tol=1e-9) - print("Test rot_2D (0 Radiant) erfolgreich bestanden!") - - # Test 8: Rotation um 90 Grad (pi / 2) -> [[0, -1], [1, 0]] - rot_90 = rot_2d(math.pi / 2) - assert math.isclose(rot_90[0][0], 0.0, abs_tol=1e-9) - assert math.isclose(rot_90[0][1], -1.0, abs_tol=1e-9) - assert math.isclose(rot_90[1][0], 1.0, abs_tol=1e-9) - assert math.isclose(rot_90[1][1], 0.0, abs_tol=1e-9) - print("Test rot_2D (pi / 2 Radiant) erfolgreich bestanden!") - - # Test 9: Drehung des Vektors (1, 0) um 90 Grad ergibt (0, 1) via matmul - point = [[1.0], [0.0]] - rotated_point = matmul(rot_90, point) - assert math.isclose(rotated_point[0][0], 0.0, abs_tol=1e-9) - assert math.isclose(rotated_point[1][0], 1.0, abs_tol=1e-9) - print("Test rot_2D (Vektordrehung mit matmul) erfolgreich bestanden!") - - # Test 10: rot_3d um x-Achse um pi / 2 - rot_x_90 = rot_3d(math.pi / 2, "x") - v_y = [[0.0], [1.0], [0.0]] - rotated_v_y = matmul(rot_x_90, v_y) - assert math.isclose(rotated_v_y[0][0], 0.0, abs_tol=1e-9) - assert math.isclose(rotated_v_y[1][0], 0.0, abs_tol=1e-9) - assert math.isclose(rotated_v_y[2][0], 1.0, abs_tol=1e-9) - print("Test rot_3D (x-Achse) erfolgreich bestanden!") - - # Test 11: rot_3d um y-Achse um pi / 2 - rot_y_90 = rot_3d(math.pi / 2, "y") - v_z = [[0.0], [0.0], [1.0]] - rotated_v_z = matmul(rot_y_90, v_z) - assert math.isclose(rotated_v_z[0][0], 1.0, abs_tol=1e-9) - assert math.isclose(rotated_v_z[1][0], 0.0, abs_tol=1e-9) - assert math.isclose(rotated_v_z[2][0], 0.0, abs_tol=1e-9) - print("Test rot_3D (y-Achse) erfolgreich bestanden!") - - # Test 12: rot_3d um z-Achse um pi / 2 - rot_z_90 = rot_3d(math.pi / 2, "z") - v_x = [[1.0], [0.0], [0.0]] - rotated_v_x = matmul(rot_z_90, v_x) - assert math.isclose(rotated_v_x[0][0], 0.0, abs_tol=1e-9) - assert math.isclose(rotated_v_x[1][0], 1.0, abs_tol=1e-9) - assert math.isclose(rotated_v_x[2][0], 0.0, abs_tol=1e-9) - print("Test rot_3D (z-Achse) erfolgreich bestanden!") - - # Test 13: rot_3d mit ungültiger Achse - try: - rot_3d(math.pi / 2, "invalid") - raise AssertionError("Ungültige Achse wurde nicht abgefangen!") - except ValueError: - print("Test 13 (rot_3d ungültige Achse) erfolgreich abgefangen!") - - # Test 14: project_ortho - projected = project_ortho((0.5, -0.5, 10.0), scale=200) - assert projected == (100.0, -100.0), ( - f"Fehler in project_ortho: Erwartet (100.0, -100.0), erhalten {projected}" - ) - print("Test 14 (project_ortho) erfolgreich bestanden!") if __name__ == "__main__": diff --git a/test/test_matrixmania/test_compute.py b/test/test_matrixmania/test_compute.py deleted file mode 100644 index d538f8b..0000000 --- a/test/test_matrixmania/test_compute.py +++ /dev/null @@ -1,154 +0,0 @@ -"""Unit-Tests für die mathematischen Matrixfunktionen in compute.py.""" - -import math - -import pytest - -from matrixmania.compute import matmul, rot_2d, rot_3d, test_functions, transpose - - -def test_matmul_valid() -> None: - """Testet die Matrixmultiplikation mit gültigen Matrizen.""" - a = [ - [3.0, 4.0, -1.0, 4.0], - [-2.0, 2.0, 5.0, 1.0], - ] - b = [ - [1.0, 3.0, -2.0], - [2.0, 5.0, 1.0], - [-1.0, 4.0, -4.0], - [2.0, 3.0, 6.0], - ] - expected = [ - [20.0, 37.0, 26.0], - [-1.0, 27.0, -8.0], - ] - assert matmul(a, b) == expected - - -def test_matmul_invalid_dimensions() -> None: - """Testet, dass bei inkompatiblen Matrixdimensionen ValueError geworfen wird.""" - a = [[1.0, 2.0], [3.0, 4.0]] - b = [[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]] - with pytest.raises(ValueError): - matmul(a, b) - - -def test_matmul_empty_or_uneven() -> None: - """Testet matmul mit leeren oder ungleichmäßigen Matrizen.""" - with pytest.raises(ValueError): - matmul([], [[1.0]]) - with pytest.raises(ValueError): - matmul([[1.0, 2.0], [3.0]], [[1.0], [2.0]]) - - -def test_transpose_valid() -> None: - """Testet das Transponieren einer regulären Matrix.""" - matrix = [ - [1.0, 2.0, 3.0], - [4.0, 5.0, 6.0], - ] - expected = [ - [1.0, 4.0], - [2.0, 5.0], - [3.0, 6.0], - ] - assert transpose(matrix) == expected - - -def test_transpose_invalid() -> None: - """Testet, dass transpose bei leeren oder unregelmäßigen Matrizen Fehler wirft.""" - with pytest.raises(ValueError): - transpose([]) - with pytest.raises(ValueError): - transpose([[1.0, 2.0], [3.0]]) - - -def test_rot_2d() -> None: - """Testet die 2D-Rotation für verschiedene Winkel.""" - rot_0 = rot_2d(0.0) - assert math.isclose(rot_0[0][0], 1.0, abs_tol=1e-9) - assert math.isclose(rot_0[0][1], 0.0, abs_tol=1e-9) - assert math.isclose(rot_0[1][0], 0.0, abs_tol=1e-9) - assert math.isclose(rot_0[1][1], 1.0, abs_tol=1e-9) - - rot_90 = rot_2d(math.pi / 2) - assert math.isclose(rot_90[0][0], 0.0, abs_tol=1e-9) - assert math.isclose(rot_90[0][1], -1.0, abs_tol=1e-9) - assert math.isclose(rot_90[1][0], 1.0, abs_tol=1e-9) - assert math.isclose(rot_90[1][1], 0.0, abs_tol=1e-9) - - -def test_rot_3d_x_axis() -> None: - """Testet die 3D-Rotation um die x-Achse.""" - matrix_x_0 = rot_3d(0.0, "x") - expected_identity = [ - [1.0, 0.0, 0.0], - [0.0, 1.0, 0.0], - [0.0, 0.0, 1.0], - ] - for r in range(3): - for c in range(3): - assert math.isclose(matrix_x_0[r][c], expected_identity[r][c], abs_tol=1e-9) - - matrix_x_90 = rot_3d(math.pi / 2, "x") - v_y = [[0.0], [1.0], [0.0]] - rotated = matmul(matrix_x_90, v_y) - assert math.isclose(rotated[0][0], 0.0, abs_tol=1e-9) - assert math.isclose(rotated[1][0], 0.0, abs_tol=1e-9) - assert math.isclose(rotated[2][0], 1.0, abs_tol=1e-9) - - -def test_rot_3d_y_axis() -> None: - """Testet die 3D-Rotation um die y-Achse.""" - matrix_y_0 = rot_3d(0.0, "y") - expected_identity = [ - [1.0, 0.0, 0.0], - [0.0, 1.0, 0.0], - [0.0, 0.0, 1.0], - ] - for r in range(3): - for c in range(3): - assert math.isclose(matrix_y_0[r][c], expected_identity[r][c], abs_tol=1e-9) - - matrix_y_90 = rot_3d(math.pi / 2, "y") - v_z = [[0.0], [0.0], [1.0]] - rotated = matmul(matrix_y_90, v_z) - assert math.isclose(rotated[0][0], 1.0, abs_tol=1e-9) - assert math.isclose(rotated[1][0], 0.0, abs_tol=1e-9) - assert math.isclose(rotated[2][0], 0.0, abs_tol=1e-9) - - -def test_rot_3d_z_axis() -> None: - """Testet die 3D-Rotation um die z-Achse.""" - matrix_z_0 = rot_3d(0.0, "z") - expected_identity = [ - [1.0, 0.0, 0.0], - [0.0, 1.0, 0.0], - [0.0, 0.0, 1.0], - ] - for r in range(3): - for c in range(3): - assert math.isclose(matrix_z_0[r][c], expected_identity[r][c], abs_tol=1e-9) - - matrix_z_90 = rot_3d(math.pi / 2, "z") - v_x = [[1.0], [0.0], [0.0]] - rotated = matmul(matrix_z_90, v_x) - assert math.isclose(rotated[0][0], 0.0, abs_tol=1e-9) - assert math.isclose(rotated[1][0], 1.0, abs_tol=1e-9) - assert math.isclose(rotated[2][0], 0.0, abs_tol=1e-9) - - -def test_rot_3d_invalid_axis() -> None: - """Testet, dass ungültige Achsen einen ValueError auslösen.""" - with pytest.raises(ValueError, match="Ungültige Achse"): - rot_3d(1.0, "w") - with pytest.raises(ValueError): - rot_3d(0.5, "123") - with pytest.raises(ValueError): - rot_3d(0.0, "") - - -def test_test_functions_execution() -> None: - """Testet die Ausführung der integrierten Testfunktion.""" - test_functions() diff --git a/test/test_matrixmania/test_matmul.py b/test/test_matrixmania/test_matmul.py new file mode 100644 index 0000000..cba087b --- /dev/null +++ b/test/test_matrixmania/test_matmul.py @@ -0,0 +1,85 @@ +"""Unit-Tests für die mathematischen Matrixfunktionen matmul und transpose.""" + +import pytest + +from matrixmania.compute import matmul, transpose + + +def test_matmul_valid() -> None: + """Testet die Matrixmultiplikation mit gültigen Matrizen.""" + a = [ + [3.0, 4.0, -1.0, 4.0], + [-2.0, 2.0, 5.0, 1.0], + ] + b = [ + [1.0, 3.0, -2.0], + [2.0, 5.0, 1.0], + [-1.0, 4.0, -4.0], + [2.0, 3.0, 6.0], + ] + expected = [ + [20.0, 37.0, 26.0], + [-1.0, 27.0, -8.0], + ] + assert matmul(a, b) == expected + + +def test_matmul_identity() -> None: + """Testet die Matrixmultiplikation mit der Einheitsmatrix.""" + a = [ + [1.0, 2.0], + [3.0, 4.0], + ] + identity = [ + [1.0, 0.0], + [0.0, 1.0], + ] + assert matmul(a, identity) == a + + +def test_matmul_invalid_dimensions() -> None: + """Testet, dass bei inkompatiblen Matrixdimensionen ValueError geworfen wird.""" + a = [[1.0, 2.0], [3.0, 4.0]] + b = [[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]] + with pytest.raises(ValueError): + matmul(a, b) + + +def test_matmul_empty_or_uneven() -> None: + """Testet matmul mit leeren oder ungleichmäßigen Matrizen.""" + with pytest.raises(ValueError): + matmul([], [[1.0]]) + with pytest.raises(ValueError): + matmul([[1.0]], []) + with pytest.raises(ValueError): + matmul([[]], [[1.0]]) + with pytest.raises(ValueError): + matmul([[1.0]], [[]]) + with pytest.raises(ValueError): + matmul([[1.0, 2.0], [3.0]], [[1.0], [2.0]]) + with pytest.raises(ValueError): + matmul([[1.0, 2.0], [3.0, 4.0]], [[1.0], [2.0, 3.0]]) + + +def test_transpose_valid() -> None: + """Testet das Transponieren einer regulären Matrix.""" + matrix = [ + [1.0, 2.0, 3.0], + [4.0, 5.0, 6.0], + ] + expected = [ + [1.0, 4.0], + [2.0, 5.0], + [3.0, 6.0], + ] + assert transpose(matrix) == expected + + +def test_transpose_invalid() -> None: + """Testet, dass transpose bei leeren oder unregelmäßigen Matrizen Fehler wirft.""" + with pytest.raises(ValueError): + transpose([]) + with pytest.raises(ValueError): + transpose([[]]) + with pytest.raises(ValueError): + transpose([[1.0, 2.0], [3.0]])