# Mathematische Funktionen

> For AI agents: use [llms.txt](https://nakafa.com/llms.txt) for the site index. Markdown versions are available by appending `.md` to content URLs or sending `Accept: text/markdown`.

URL: https://nakafa.com/de/faecher/ki-und-data-science/ki-programmierung/mathematische-funktionen
Source: https://raw.githubusercontent.com/nakafaai/aksara/992eb09ded1422859aca3966c80b52a16b2832f4/packages/corpus/material/lesson/ai-ds/ai-programming/math-function/de.mdx

Nutze Pythons math-Modul, numerische Built-ins, Importstile, Definitionsbereiche und Konstanten in überprüften Berechnungen.

---

## Modulkonzept in Python

Python <Highlight>speichert viel wiederverwendbaren Code in Modulen</Highlight>. Ein Modul kann Funktionen, Konstanten, Klassen und weitere Namen enthalten, ohne sie alle im globalen Namensraum abzulegen.

Ein `import` lädt ein Modul bei Bedarf und bindet einen Namen, über den dein Code auf dessen öffentliche Elemente zugreift. Die Standardbibliothek bietet bereits gut getestete mathematische Operationen. Anwendungscode sollte sie nutzen, statt Formeln unbedacht neu zu implementieren.

## Das Modul Math

Das Modul `math` stellt **reellwertige Funktionen und Konstanten** bereit. Es akzeptiert kompatible reelle Zahlen wie `int` und `float`, nimmt bei Operationen wie `sqrt()` aber keine komplexen Werte an. Verwende `cmath`, wenn der Definitionsbereich oder das Ergebnis komplex sein kann.

## Das Modul Math importieren

Python bietet mehrere Möglichkeiten, ein Modul zu importieren, und die Wahl prägt das **Aussehen jedes späteren Aufrufs**. Du kannst das ganze Modul importieren, einzelne Namen daraus oder das Modul beim Import umbenennen.

### Basisimport mit Namespace

Die Anweisung `import math` importiert das Modul unter dem **Namensraum `math`**. Funktionen und Konstanten werden anschließend über Namen wie `math.sqrt` und `math.pi` aufgerufen.

File: import_basic.py
```python
import math

# sqrt mit dem Präfix math verwenden
print(math.sqrt(9))  # Ausgabe: 3.0

# Zugriff auf die Pi-Konstante
print(math.pi)  # Ausgabe: 3.141592653589793

# Ein Aufruf ohne Präfix führt zu einem Fehler
# sqrt(9)  # NameError: name 'sqrt' is not defined
```

### Importieren mit Alias

Ein Alias bindet das Modul an einen **anderen lokalen Namen**. Nutze ihn nur, wenn er einer etablierten Konvention folgt oder einen echten Namenskonflikt löst. `math` selbst ist bereits kurz und eindeutig.

File: import_alias.py
```python
import math as m

# Den Alias „m“ anstelle von „math“ verwenden
print(m.sqrt(9))  # Ausgabe: 3.0
print(m.pi)       # Ausgabe: 3.141592653589793

# Dieser Import bindet m, nicht math
# math.sqrt(9)  # NameError: name 'math' is not defined
```

### Alle Funktionen importieren

Diese Form importiert jeden öffentlichen Namen aus `math` in den aktuellen Namensraum. In einer einmaligen interaktiven Sitzung mag das bequem sein, Anwendungscode sollte es jedoch vermeiden.

File: import_all.py
```python
from math import *

# Funktionen können ohne Präfix direkt aufgerufen werden
print(sqrt(9))  # Ausgabe: 3.0
print(pi)       # Ausgabe: 3.141592653589793

# Der Name „math“ ist nicht verfügbar, da er nicht importiert wurde
# math.sqrt(9)  # NameError: name 'math' is not defined
```

`from math import *` fügt jeden öffentlichen Namen aus `math` in den aktuellen Namensraum ein. Wird einer dieser Namen bereits verwendet, ersetzt der Wert aus `math` ihn ohne Fehlermeldung. Im Code ist außerdem nicht mehr erkennbar, aus welchem Modul der jeweilige Name stammt. Eine spätere Änderung an `math` kann dem importierenden Modul weitere Namen hinzufügen. Ein expliziter Import <Highlight>nennt jede Abhängigkeit in der Importzeile</Highlight>.

### Spezifische Funktionen importieren

Importiere **nur die Funktionen**, die das Programm verwendet. Der Funktionsname bleibt ohne Modulpräfix verfügbar, während die Importzeile weiterhin seine Herkunft nennt.

File: import_specific.py
```python
from math import sqrt

# Die sqrt-Funktion kann direkt aufgerufen werden
print(sqrt(9))  # Ausgabe: 3.0

# Die pi-Konstante ist nicht verfügbar, da sie nicht importiert wurde
# print(pi)  # NameError: name 'pi' is not defined

# Der Name „math“ ist ebenfalls nicht verfügbar
# math.sqrt(9)  # NameError: name 'math' is not defined
```

### Importieren mit Funktionsalias

Eine importierte Funktion kann einen Alias erhalten, um einen **Namenskonflikt aufzulösen** oder einer etablierten lokalen Konvention zu folgen.

File: import_function_alias.py
```python
from math import factorial as fac

# Den Alias „fac“ für factorial verwenden
print(fac(5))  # Ausgabe: 120

# Der ursprüngliche Name „factorial“ ist nicht verfügbar
# factorial(5)  # NameError: name 'factorial' is not defined

# Das Gleiche gilt für „math“
# math.factorial(5)  # NameError: name 'math' is not defined
```

## Eingebaute Funktionen und Modulfunktionen

Python stellt numerische Built-ins wie `abs()` und `round()` **ohne Import** bereit. Sie arbeiten über Pythons numerische Protokolle mit verschiedenen Typen: Ein Typ kann die unterstützte Operation definieren. Python wählt dabei nicht zwischen mehreren statisch überladenen Funktionsdeklarationen.

### Absolutwertfunktion

Für reelle Zahlen liefert `abs()` einen nichtnegativen Betrag. Für eine komplexe Zahl liefert die Funktion den **Abstand zum Ursprung**.

File: abs_function.py
```python
# Absoluter Wert für negative Ganzzahl
print(abs(-5))    # Ausgabe: 5

# Absolutwert einer negativen Gleitkommazahl
print(abs(-1.4))  # Ausgabe: 1.4

# Absolutwert für komplexe Zahl (Modul)
print(abs(4 + 3j))  # Ausgabe: 5.0
```

Für `4 + 3j` ergibt sich $$5.0$$, denn $$|4+3i|=\sqrt{4^2+3^2}=\sqrt{25}=5$$. Python schreibt die imaginäre Einheit als `j`, während mathematische Formeln üblicherweise $$i$$ verwenden.

Visible text: Für `4 + 3j` ergibt sich , denn . Python schreibt die imaginäre Einheit als `j`, während mathematische Formeln üblicherweise verwenden.

### Rundungsfunktion

Für Pythons eingebaute Zahlentypen rundet `round()` auf den nächsten Wert und wählt bei einem exakten Gleichstand **die gerade Möglichkeit**. Ein Aufruf ohne `ndigits` liefert für einen Float einen Integer. Das zweite Argument bestimmt die Dezimalstelle.

File: round_function.py
```python
# Standardrundung
print(round(-3.8))  # Ausgabe: -4
print(round(3.5))   # Ausgabe: 4
print(round(4.5))   # Ausgabe: 4

# Runden mit spezifischer Präzision
print(round(3.141592653589793, 3))  # Ausgabe: 3.142
print(round(1234.4321, -2))         # Ausgabe: 1200.0
```

Deshalb ergibt `round(4.5)` den Wert $$4$$, während auch `round(3.5)` den Wert $$4$$ liefert. Dezimal aussehende Float-Werte werden binär gespeichert. Ein scheinbar exakter Gleichstand muss intern also keiner sein. Verwende Dezimalarithmetik, wenn ein Fachgebiet dezimale Rundungsregeln verlangt.

Visible text: Deshalb ergibt `round(4.5)` den Wert , während auch `round(3.5)` den Wert liefert. Dezimal aussehende Float-Werte werden binär gespeichert. Ein scheinbar exakter Gleichstand muss intern also keiner sein. Verwende Dezimalarithmetik, wenn ein Fachgebiet dezimale Rundungsregeln verlangt.

## Funktionen und Konstanten im Mathematikmodul

Jede `math`-Funktion hat **einen Definitionsbereich**. `sqrt(x)` benötigt beispielsweise eine nichtnegative reelle Eingabe, Logarithmen benötigen positive reelle Eingaben. Ein Wert außerhalb dieses Bereichs löst einen `ValueError` aus, statt eine Zahl zurückzugeben.

### Funktionen für Quadratwurzeln und Logarithmen

Das Beispiel ruft die Wurzel- und die Logarithmusfunktion auf und zeigt, wie Python eine **Eingabe außerhalb des Definitionsbereichs** meldet.

File: math_functions.py
```python
import math

# Quadratwurzelfunktion
print(f"Quadratwurzel von 16: {math.sqrt(16)}")  # Ausgabe: Quadratwurzel von 16: 4.0

# Exponentialfunktion (e^x)
print(f"e hoch 2: {math.exp(2)}")  # Ausgabe: e hoch 2: 7.38905609893065

# Natürliche Logarithmusfunktion
print(f"ln(10): {math.log(10)}")  # Ausgabe: ln(10): 2.302585092994046

# Basis der Logarithmusfunktion 10
print(f"log10(100): {math.log10(100)}")  # Ausgabe: log10(100): 2.0

# Logarithmus mit spezifischer Basis
print(f"log2(8): {math.log(8, 2)}")  # Ausgabe: log2(8): 3.0

try:
  math.sqrt(-1)
except ValueError as error:
  print(type(error).__name__)
# Ausgabe: ValueError
```

### Trigonometriefunktionen

Die Trigonometriefunktionen arbeiten **im Bogenmaß**. Das Beispiel rechnet einen Winkel um und ruft die drei Hauptfunktionen auf.

File: trigonometry.py
```python
import math

# Trigonometriefunktionen (Eingabe im Bogenmaß)
angle_rad = math.pi / 4  # 45 Grad im Bogenmaß

print(f"sin(π/4): {math.sin(angle_rad)}")  # Ausgabe: sin(π/4): 0.7071067811865475
print(f"cos(π/4): {math.cos(angle_rad)}")  # Ausgabe: cos(π/4): 0.7071067811865476
print(f"tan(π/4): {math.tan(angle_rad)}")  # Ausgabe: tan(π/4): 0.9999999999999999

# Grad in Bogenmaß umrechnen
angle_deg = 45
angle_rad = math.radians(angle_deg)
print(f"45 Grad = {angle_rad} Bogenmaß")  # Ausgabe: 45 Grad = 0.7853981633974483 Bogenmaß
```

### Aufrunden Abrunden und Fakultät

Aufrunden, Abrunden und Fakultät beantworten **verschiedene Fragen**. Das Beispiel wendet jede Funktion an und gibt das Ergebnis aus.

File: ceiling_floor.py
```python
import math

number = 4.7

# ceil: kleinste ganze Zahl >= x
print(f"ceil(4.7): {math.ceil(number)}")    # Ausgabe: ceil(4.7): 5

# floor: größte ganze Zahl <= x
print(f"floor(4.7): {math.floor(number)}")  # Ausgabe: floor(4.7): 4

# Fakultät
print(f"5!: {math.factorial(5)}")  # Ausgabe: 5!: 120
```

### Mathematische Konstanten

Das Modul stellt außerdem Konstanten bereit, darunter endliche mathematische Konstanten und **besondere Gleitkommawerte**.

File: math_constants.py
```python
import math

# Pi-Konstante (π ≈ 3.141592...)
print(f"Wert von π: {math.pi}")

# e-Konstante (Eulersche Zahl ≈ 2.718281...)
print(f"Wert von e: {math.e}")

# Unendlichkeit (positive Unendlichkeit)
print(f"Infinity: {math.inf}")

# NaN (kein gültiger Zahlenwert)
print(f"NaN: {math.nan}")

# Beispiel für die Verwendung von Konstanten
circle_radius = 5
circle_area = math.pi * circle_radius ** 2
print(f"Kreisfläche mit Radius {circle_radius}: {circle_area}")
```

## Auswahl der richtigen Importmethode

Wähle einen Importstil, der den **Modulnamen bei jedem Aufruf** nennt, wenn dieser Kontext nötig ist, und importiere nur Namen, die das Programm tatsächlich verwendet. Eine einzelne Funktion, die einmal gebraucht wird, liest sich als `from math import sqrt` gut, während mehrere Aufrufe mit `import math` klarer bleiben.

### Leitfaden zur Auswahl von Importmethoden

Wähle den Importstil danach, wie viele Namen du brauchst und **wie lesbar der Aufruf bleibt**. Die Liste unten ordnet die Möglichkeiten von der ausdrücklichsten zur knappsten.

1. **Bevorzuge `import math`**, wenn das Programm mehrere Elemente nutzt. Aufrufe wie `math.sqrt()` nennen das Modul direkt neben der Funktion.
2. **Verwende `import math as m` bewusst** und nur, wenn der Alias eine dokumentierte lokale Konvention ist.
3. **Verwende `from math import sqrt, pi`**, wenn eine kleine Menge eindeutiger Namen den lokalen Code klarer macht.
4. **Vermeide `from math import *`**, weil die importierten Namen kein Modulpräfix tragen und bereits verwendete Namen ersetzen können.

### Abstände und Flächen berechnen

Für die Punkte `(0, 0)` und `(3, 4)` ist der **euklidische Abstand** die Wurzel aus der Summe der quadrierten Koordinatendifferenzen. Bei den Seiten `3`, `4` und `5` stimmt Herons Formel mit der Flächenformel für rechtwinklige Dreiecke überein.

```math
\begin{aligned}d&=\sqrt{(3-0)^2+(4-0)^2}=5\\s&=\frac{3+4+5}{2}=6\\A&=\sqrt{6(6-3)(6-4)(6-5)}=\sqrt{36}=6\end{aligned}
```

File: practical_example.py
```python
import math

def calculate_euclidean_distance(x1, y1, x2, y2):
  """Berechnet den euklidischen Abstand zwischen zwei Punkten."""
  return math.hypot(x2 - x1, y2 - y1)

def calculate_triangle_area(a, b, c):
  """Berechnet die Dreiecksfläche mit der heronischen Formel."""
  if not all(math.isfinite(side) for side in (a, b, c)):
      raise ValueError("Seitenlängen müssen endlich sein")
  if min(a, b, c) <= 0:
      raise ValueError("Seitenlängen müssen positiv sein")

  if a + b <= c or a + c <= b or b + c <= a:
      raise ValueError("Seitenlängen müssen ein Dreieck bilden")

  # Halbumfang berechnen
  s = (a + b + c) / 2

  # Herons Formel
  area = math.sqrt(s * (s - a) * (s - b) * (s - c))
  return area

# Anwendungsbeispiel
point1 = (0, 0)
point2 = (3, 4)
distance = calculate_euclidean_distance(*point1, *point2)
print(f"Abstand zwischen {point1} und {point2}: {distance}")

# Dreiecksfläche für die Seitenlängen 3, 4 und 5 berechnen
area = calculate_triangle_area(3, 4, 5)
print(f"Dreiecksfläche bei Seitenlängen 3, 4 und 5: {area}")
```

In klarem numerischem Code lassen sich drei Entscheidungen direkt erkennen: Welcher Namensraum besitzt eine Operation, **welchen Eingabebereich** akzeptiert sie und wie behandelt der Code außergewöhnliche Eingaben? Diese Entscheidungen sind wichtiger, als einen Funktionsnamen um wenige Zeichen zu verkürzen.