Hausaufgabe Blatt 2: rot_3D implementiert, Tests ergänzt und Paketstruktur erstellt
This commit is contained in:
parent
762d0ab9dc
commit
c6a8b0dc68
4
README.md
Normal file
4
README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# MatrixMania
|
||||
|
||||
Dies ist eine Übungsbibliothek für Programmieren III.
|
||||
Enthält Funktionen für Matrix-Operationen und 3D-Rotationen.
|
||||
1
matrixmania/__init__.py
Normal file
1
matrixmania/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .compute import matmul, transpose, rot_2D, rot_3D
|
||||
@ -1,4 +1,5 @@
|
||||
# hab ich alles selbst programmiert
|
||||
# created by ChatGPT
|
||||
|
||||
from typing import List
|
||||
import math
|
||||
from tabulate import tabulate
|
||||
@ -44,6 +45,38 @@ def rot_2D(angle_degrees: float) -> Matrix:
|
||||
]
|
||||
return rotation_matrix
|
||||
|
||||
|
||||
def rot_3D(angle_degrees: float, axis: str) -> Matrix:
|
||||
"""
|
||||
Erzeugt eine 3x3 Rotationsmatrix für die angegebene Achse.
|
||||
"""
|
||||
rad = math.radians(angle_degrees)
|
||||
cos_a = math.cos(rad)
|
||||
sin_a = math.sin(rad)
|
||||
|
||||
axis = axis.lower()
|
||||
|
||||
if axis == "x":
|
||||
return [
|
||||
[1.0, 0.0, 0.0],
|
||||
[0.0, cos_a, -sin_a],
|
||||
[0.0, sin_a, cos_a]
|
||||
]
|
||||
elif axis == "y":
|
||||
return [
|
||||
[cos_a, 0.0, sin_a],
|
||||
[0.0, 1.0, 0.0],
|
||||
[-sin_a, 0.0, cos_a]
|
||||
]
|
||||
elif axis == "z":
|
||||
return [
|
||||
[cos_a, -sin_a, 0.0],
|
||||
[sin_a, cos_a, 0.0],
|
||||
[0.0, 0.0, 1.0]
|
||||
]
|
||||
else:
|
||||
raise ValueError("Achse muss x, y oder z sein.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
matrix = [[1,2,3], [2,3,4]]
|
||||
|
||||
15
pyproject.toml
Normal file
15
pyproject.toml
Normal file
@ -0,0 +1,15 @@
|
||||
[project]
|
||||
name = "MatrixMania_dimartinoma102424"
|
||||
version = "0.2.0"
|
||||
description = "MatrixMania Library for Prog3"
|
||||
authors = [{ name="Marco", email="dimartinoma102424@th-nuernberg.de" }]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["tabulate"]
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["matrixmania"]
|
||||
39
test/test_matmul.py
Normal file
39
test/test_matmul.py
Normal file
@ -0,0 +1,39 @@
|
||||
import pytest
|
||||
from matrixmania.compute import matmul, transpose
|
||||
|
||||
# --- Tests für Transponieren ---
|
||||
def test_transpose_regular():
|
||||
# Testet eine normale 2x3 Matrix
|
||||
matrix = [
|
||||
[1, 2, 3],
|
||||
[4, 5, 6]
|
||||
]
|
||||
expected = [
|
||||
[1, 4],
|
||||
[2, 5],
|
||||
[3, 6]
|
||||
]
|
||||
assert transpose(matrix) == expected
|
||||
|
||||
def test_transpose_empty():
|
||||
# Testet, ob der ValueError bei leerer Matrix kommt
|
||||
with pytest.raises(ValueError):
|
||||
transpose([])
|
||||
|
||||
# --- Tests für Matrixmultiplikation (matmul) ---
|
||||
def test_matmul_simple():
|
||||
# Einfache Multiplikation 2x2 * 2x1
|
||||
A = [[1, 2], [3, 4]]
|
||||
B = [[5], [6]]
|
||||
# Rechnung:
|
||||
# 1*5 + 2*6 = 5 + 12 = 17
|
||||
# 3*5 + 4*6 = 15 + 24 = 39
|
||||
expected = [[17], [39]]
|
||||
assert matmul(A, B) == expected
|
||||
|
||||
def test_matmul_invalid_dimensions():
|
||||
# Testet, ob Fehler geworfen wird, wenn Dimensionen nicht passen
|
||||
A = [[1, 2]] # 1x2
|
||||
B = [[1, 2]] # 1x2 -> Spalten A (2) != Zeilen B (1)
|
||||
with pytest.raises(ValueError):
|
||||
matmul(A, B)
|
||||
48
test/test_rot.py
Normal file
48
test/test_rot.py
Normal file
@ -0,0 +1,48 @@
|
||||
import pytest
|
||||
from matrixmania.compute import rot_2D, rot_3D
|
||||
|
||||
|
||||
# --- Tests für Rotationen (2D & 3D) ---
|
||||
def test_rot_2D():
|
||||
# 90 Grad Rotation in 2D: (1, 0) -> (0, 1)
|
||||
# Matrix sollte [[0, -1], [1, 0]] sein (cos(90)=0, sin(90)=1)
|
||||
result = rot_2D(90)
|
||||
|
||||
# Wir nutzen pytest.approx für Float-Vergleiche, da 0.00000000001 != 0 ist
|
||||
assert result[0][0] == pytest.approx(0.0) # cos
|
||||
assert result[0][1] == pytest.approx(-1.0) # -sin
|
||||
assert result[1][0] == pytest.approx(1.0) # sin
|
||||
assert result[1][1] == pytest.approx(0.0) # cos
|
||||
|
||||
|
||||
def test_rot_3D_x_axis():
|
||||
# 90 Grad um X-Achse
|
||||
# Erwartet:
|
||||
# 1 0 0
|
||||
# 0 0 -1
|
||||
# 0 1 0
|
||||
result = rot_3D(90, 'x')
|
||||
|
||||
assert result[0] == [1.0, 0.0, 0.0] # X-Achse bleibt stabil
|
||||
assert result[1][1] == pytest.approx(0.0)
|
||||
assert result[1][2] == pytest.approx(-1.0)
|
||||
assert result[2][1] == pytest.approx(1.0)
|
||||
|
||||
|
||||
def test_rot_3D_z_axis():
|
||||
# 180 Grad um Z-Achse
|
||||
# Erwartet:
|
||||
# -1 0 0
|
||||
# 0 -1 0
|
||||
# 0 0 1
|
||||
result = rot_3D(180, 'z')
|
||||
|
||||
assert result[0][0] == pytest.approx(-1.0)
|
||||
assert result[1][1] == pytest.approx(-1.0)
|
||||
assert result[2][2] == pytest.approx(1.0)
|
||||
|
||||
|
||||
def test_rot_3D_invalid_input():
|
||||
# Testet, ob Fehler geworfen wird bei falscher Achse
|
||||
with pytest.raises(ValueError):
|
||||
rot_3D(90, 'q') # 'q' gibt es nicht
|
||||
Loading…
x
Reference in New Issue
Block a user