commit bb7f16d11ebe254c1ca8caf3ae1e8eccb35c0e35 Author: Vivien Engling Date: Thu Oct 15 12:48:46 2026 +0200 Erster Stand: compute,py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d1eb6e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.venv/ +__pycache__/ +.env \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/matrixmania.iml b/.idea/matrixmania.iml new file mode 100644 index 0000000..57669e6 --- /dev/null +++ b/.idea/matrixmania.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..cd70baf --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..7b1daae --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..2b6a69a --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,4 @@ +# Regeln für dieses Projekt +Code nach PEP 8, Zeilenlänge maximal 88 Zeichen. +Jede Funktion und Methode hat einen Docstring und Type Hints. +Vor jedem Commit: ruff check und ruff format. \ No newline at end of file diff --git a/compute.py b/compute.py new file mode 100644 index 0000000..ed0c168 --- /dev/null +++ b/compute.py @@ -0,0 +1,157 @@ +"""Compute operations for matrices. + +This module provides a single public function, :func:`matmul`, which multiplies two +2‑D matrices represented as lists of lists of floats. The implementation is +lightweight, well typed and contains detailed Google‑style documentation. +""" + +from __future__ import annotations + +from typing import List + +import math + +def rot_2D(theta: float) -> List[List[float]]: + """Erzeugt eine 2D-Rotationsmatrix für einen Winkel theta (im Bogenmaß).""" + c = math.cos(theta) + s = math.sin(theta) + return [[c, -s], [s, c]] + +def matmul( + matrix_a: List[List[float]], + matrix_b: List[List[float]] +) -> List[List[float]]: + """Multiply two 2D matrices. + + Both matrices are expected to be non‑empty and to have consistent row + lengths. The number of columns in ``matrix_a`` must equal the number of + rows in ``matrix_b``. + + Args: + matrix_a: A matrix of shape (m, n) represented as a list of m rows, + each a list of n floats. + matrix_b: A matrix of shape (n, p) represented as a list of n rows, + each a list of p floats. + + Returns: + A new matrix of shape (m, p) containing the product + ``matrix_a @ matrix_b``. + + Raises: + ValueError: If either matrix is empty or if the column count of + ``matrix_a`` does not match the row count of ``matrix_b``. + """ + + # SCHRITT 1: Validierung – Prüfen, ob die Matrizen überhaupt Daten enthalten + if not matrix_a or not matrix_b: + raise ValueError("Input matrices must not be empty.") + + n_cols_a = len(matrix_a[0]) + + # SCHRITT 2: Konsistenzprüfung für Matrix A (Programm schaut erste Zeile an merkt sich die Spaltenanzahl, geht jede weitere Zeile durch und zählt, gibt es eine Zeile die abweicht und nicht gleich viele Spalten wie die andere hat wirft er einen sauberen Fehler statt abzustürzen) + if any(len(row) != n_cols_a for row in matrix_a): + raise ValueError("All rows of matrix_a must have the same number of columns.") + + n_rows_b = len(matrix_b) + + # SCHRITT 3: Mathematische Regel prüfen: Spalten von A müssen gleich Zeilen von B sein + if n_cols_a != n_rows_b: + raise ValueError( + f"Matrix dimension mismatch: matrix_a columns {n_cols_a} != matrix_b rows {n_rows_b}" + ) + + n_cols_b = len(matrix_b[0]) + + # SCHRITT 4: Konsistenzprüfung für Matrix B + if any(len(row) != n_cols_b for row in matrix_b): + raise ValueError("All rows of matrix_b must have the same number of columns.") + + # SCHRITT 5: Eigentliche Matrixmultiplikation (Skalarprodukt der Zeilen und Spalten) + result: List[List[float]] = [] + for i in range(len(matrix_a)): # Gehe jede Zeile von Matrix A durch + row: List[float] = [] + for j in range(n_cols_b): # Gehe jede Spalte von Matrix B durch + # Berechne das Skalarprodukt: Summe der Produkte aus Zeilenelementen und Spaltenelementen + elem = sum(matrix_a[i][k] * matrix_b[k][j] for k in range(n_cols_a)) + row.append(elem) + result.append(row) + + return result + + +def transpose(matrix: List[List[float]]) -> List[List[float]]: + """Return the transpose of a 2‑D matrix. + + Args: + matrix: A non‑empty matrix represented as a list of rows. + + Returns: + A new matrix where rows become columns. + + Raises: + ValueError: If the input matrix is empty or ragged. + """ + + # Prüfen, ob die Matrix leer ist + if not matrix: + raise ValueError("Cannot transpose an empty matrix.") + + n_rows = len(matrix) + n_cols = len(matrix[0]) + + # Konsistenzprüfung sicherstellen + if any(len(row) != n_cols for row in matrix): + raise ValueError("All rows of the matrix must have the same number of columns.") + + # SCHRITT: Zeilen und Spalten vertauschen (List Comprehension) + # Aus Matrix[i][j] wird Matrix[j][i] + return [[matrix[i][j] for i in range(n_rows)] for j in range(n_cols)] + + +def rotate_clockwise(matrix: List[List[float]]) -> List[List[float]]: + """Rotate a square matrix 90 degrees clockwise. + + The function works for any rectangular matrix but will produce a matrix + of dimensions (cols, rows). + + Args: + matrix: A non‑empty matrix. + + Returns: + The rotated matrix. + + Raises: + ValueError: If the matrix is empty. + """ + + # Prüfen, ob die Matrix leer ist + if not matrix: + raise ValueError("Cannot rotate an empty matrix.") + + n_rows = len(matrix) + n_cols = len(matrix[0]) + + # Konsistenzprüfung sicherstellen + if any(len(row) != n_cols for row in matrix): + raise ValueError("All rows of the matrix must have the same number of columns.") + + # SCHRITT: 90-Grad-Drehung im Uhrzeigersinn + # Trick: Erst transponieren (Spiegeln) und danach jede Zeile umkehren! + transposed = transpose(matrix) + return [row[::-1] for row in transposed] + + +if __name__ == "__main__": + # Testdaten für die Demonstration + a = [[1, 2, 3], [4, 5, 6]] + b = [[7, 8], [9, 10], [11, 12]] + + print("matmul(a, b):") + print(matmul(a, b)) + + print("transpose(a):") + print(transpose(a)) + + c = [[1, 2], [3, 4], [5, 6]] + print("rotate_clockwise(c):") + print(rotate_clockwise(c)) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..46e3b47 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[project] +name = "matrixmania" +version = "0.1.0" \ No newline at end of file