Funktionen definieren#
Wenn Sie in Pyton wiederholt dieselbe Berechnung durchführen möchten, dann lohnt es sich, Funktionen zu verwenden. Funktionen sind ein zentrales Werkzeug der Programmierung. Funktionen helfen Code zu strukturieren und wiederverwendbar zu machen.
Stellen Sie sich vor, Sie möchten den Flächeninhalt mehrerer Dreiecke berechnen. Die bekannte mathematische Formel dafür lautet:
In Python können Sie eine solche Berechnung für ein konkretes Dreieck einfach so ausführen:
grundseite = 4
höhe = 3
fläche = 0.5 * grundseite * höhe
print(fläche)
Doch was, wenn Sie diese Berechnung mehrfach brauchen – mit verschiedenen Werten? Dann wäre es unübersichtlich und fehleranfällig, die Formel jedes Mal neu zu schreiben. Stattdessen können Sie eine Funktion definieren:
def dreiecksfläche(grundseite, höhe):
"""Berechnet den Flächeninhalt eines Dreiecks.
Input:
grundseite (float): Die Länge der Grundseite des Dreiecks
höhe (float): Die Höhe des Dreiecks
Output:
flächeninhalt (float): Der berechnete Flächeninhalt des Dreiecks
"""
flächeninhalt = 0.5 * grundseite * höhe
return flächeninhalt
In Python beginnt jede Funktion mit dem Schlüsselwort \(\texttt{def}\). Es zeigt an, dass hier eine neue Funktion definiert wird. Der Funktionsname ist frei wählbar, solange er nicht mit reservierten Schlüsselwörten kollidiert. Wichtig ist, dass er verständlich und beschreibend ist. Namen wie \(\texttt{dreiecksfläche}\) sind deutlich hilfreicher als \(\texttt{f}\).
Bemerkung
Verwenden Sie für sich selbst sprechende Namen, die den Zweck der Funktion klar machen.
In den runden Klammern steht eine Liste von Eingabewerten, auch Parameter genannt. Das sind Platzhalter für Werte, die beim Aufruf der Funktion übergeben werden. Alle Anweisungen, die zur Funktion gehören, müssen eingerückt sein. Python erkennt anhand der Einrückung, wo der Funktionskörper beginnt und endet.
def dreiecksfläche(grundseite, höhe):
grundseite_mal_höhe = grundseite * höhe # gehört zur Funktion
# gehört nicht mehr zur Funktion
flächeninhalt = 0.5 * grundseite_mal_höhe
Mit dem Befehl \(\texttt{return}\) gibt eine Funktion ein Ergebnis zurück. Dieses Ergebnis steht dann genau an der Stelle zur Verfügung, an der die Funktion aufgerufen wurde.
Sobald Sie eine Funktion definiert haben, können Sie sie beliebig oft im Programm verwenden – mit verschiedenen Eingabewerten:
A1 = dreiecksfläche(4, 3)
A2 = dreiecksfläche(7.5, 2.1)
print(A1)
print(A2)
Allgemein ist eine Funktion also wie folgt aufgebaut:
def funktionsname(eingabe1, eingabe2, ...):
"""Kurze Beschreibung, was die Funktion macht"""
# Anweisungen, die ausgeführt werden, wenn die Funktion aufgerufen wird
return ergebnis
Bemerkung
Schreiben Sie immer eine kurze, aber aussagekräftige Beschreibung direkt zu Beginn Ihrer Funktion in den sogenannten DocString – das ist ein mehrzeiliger Kommentar in drei Anführungszeichen (\(\texttt{""" ... """}\)), der erklärt, was die Funktion macht, welche Datentypen sie erwartet und was genau zurückgegeben wird.
Aufgabe 1.1
Schreiben Sie eine Funktion \(\texttt{rechteckfläche}\), die die Fläche eines Rechtecks berechnet. Die Eingaben sind \(\texttt{breite}\) und \(\texttt{höhe}\).
# Ihr Code
Hinweis
Die Fläche eines Rechtecks berechnet sich durch Breite mal Höhe. Nutzen Sie das Schlüsselwort \(\texttt{def}\), um die Funktion zu definieren, und \(\texttt{return}\), um den Rückgabewert anzugeben. Vergessen Sie nicht Ihre Funktion angemessen zu beschreiben.
Lösung
def rechteckfläche(breite, höhe):
"""Berechnet den Flächeninhalt eines Rechteckts.
Input:
breite (float): Die Breite des Rechtecks
höhe (float): Die Höhe des Rechtecks
Output:
flächeninhalt (float): Der berechnete Flächeninhalt des Rechtecks
"""
flächeninhalt = breite * höhe
return flächeninhalt
Aufgabe 1.2
Schreiben Sie eine Funktion \(\texttt{norm(x)}\), die die euklidische Norm eines \(n\)-dimensionalen Vektors \(x\) berechnet. Das heißt: \( \Vert x \Vert_2 = \sqrt{x_1^2 + \ldots + x_n^2} \) Verwenden Sie als Eingabe ein NumPy-Array.
# Ihr Code
Hinweis
Sie können \(\texttt{np.sum(x**2)}\) verwenden. Vergessen Sie nicht Ihre Funktion angemessen zu beschreiben.
Lösung
import numpy as np
def norm(x):
"""Berechnet die 2-Norm eines n-dimensionalen Vektors.
Input:
vec (np.array): Vektor
Output:
zwei_norm (float): 2-Norm des Vektors
"""
zwei_norm = np.sqrt(np.sum(x**2))
return zwei_norm
print(norm(y))
Aufgabe 1.3
Schreiben Sie eine Funktion \(\texttt{abstand(p1, p2, norm_funktion)}\), die den Abstand zweier \(n\)-dimensionaler Punkten \(p_1\) und \(p_2\) berechnet. \(\texttt{norm_funktion}\) ist dabei eine Funktion, welche eine beliebige Norm \(\Vert \cdot \Vert\) darstellt.
# Ihr Code
Hinweis
Der Abstand zweier \(n\)-dimensionaler Punkte kann über \(\Vert p_1 - p_2 \Vert\) berechnet werden. Eine bereits definierte Funktion, kann über ihren Funktionsnamen als Input in eine andere Funktion übergeben werden.
Lösung
def abstand(p1, p2, norm_funktion):
"""Berechnet den Abstand zweier Punkte im R^n mithilfe einer übergebenen Normfunktion.
Input:
p1 (np.array): Erster Punkt
p2 (np.array): Zweiter Punkt
norm_funktion (function): Funktion, die die 2-Norm eines Vektors berechnet
Output:
abstand_der_punkte (float): Abstand zwischen den Punkten
"""
differenz = p2 - p1
abstand_der_punkte = norm_funktion(differenz)
return abstand_der_punkte
Minimalbeispiele#
Es ist immer sinnvoll, selbst geschriebene Funktionen mit Minimalbeispielen zu testen, bevor man sie in größeren Programmen verwendet. Dabei wählt man einfache Eingaben, deren Ergebnis man von Hand berechnen kann, und überprüft, ob die Funktion das erwartete Ergebnis liefert.
Solche Tests helfen, Fehler früh zu erkennen, und geben Sicherheit, dass die Funktion korrekt arbeitet – besonders bei komplexeren Aufgaben oder wenn mehrere Funktionen zusammenwirken.
Aufgabe 2.1
Berechnen Sie den Abstand der beiden Punkte \(p1=(3,4)\) und \(p2=(0,0)\) mithilfe Ihrer \(\texttt{abstand}\)-Funktion. Was erwarten Sie als Ergebnis?
# Ihr Code
Hinweis
Erstellen Sie zwei NumPy-Arrays und übergeben Sie diese an \(\texttt{abstand}\). Das Ergebnis sollte \(\sqrt{3^2+4^2} = 5\) entsprechen.
Lösung
p1 = np.array([3, 4])
p2 = np.array([0, 0])
print(abstand(p1, p2, norm))
Wenn Sie eine Funktion definieren, geben Sie die Namen der Eingabevariablen in runden Klammern an – sogenannte Argumente. Beim Aufruf der Funktion müssen Sie diese Argumente normalerweise in der richtigen Reihenfolge angeben. Das nennt man Positionsargumente. Ein Aufruf muss dann so aussehen:
A1 = dreiecksfläche(4, 3)
print(A1)
Sie können aber auch Schlüsselwortargumente verwenden. Dabei wird dem Namen eines Arguments beim Aufruf direkt ein Wert zugewiesen, wodurch die Lesbarkeit erhöht wird und Fehler bei der Reihenfolge der Variablen verhindert.
A1 = dreiecksfläche(höhe = 3, grundseite = 4)
print(A1)
Aufgabe 2.2
Berechnen Sie den Abstand der beiden Punkte \(p1=(3,4)\) und \(p2=(0,0)\) mithilfe Ihrer \(\texttt{abstand}\)-Funktion, welche als erster Eingabeparameter übergeben werden soll.
# Ihr Code
Hinweis
Nutzen Sie Schlüsselwortargumente.
Lösung
p1 = np.array([3, 4])
p2 = np.array([0, 0])
print(abstand(norm_funktion = norm, p1 = p1, p2 = p2))
Best Practice#
Beim Schreiben eigener Funktionen lohnt es sich, ein paar bewährte Grundsätze zu beachten:
Lokale Variablen: Variablen, die innerhalb einer Funktion definiert sind, gelten nur dort. Sie überschreiben keine gleichnamigen Variablen außerhalb der Funktion.
Sinnvolle Namen wählen: Verwenden Sie für sich selbst sprechende Funktions- und Variablennamen, z. B. \(\texttt{berechne_mittelwert}\) statt \(\texttt{f1}\).
Keine doppelten Berechnungen: Wenn Sie eine Berechnung mehrfach benötigen, lagern Sie sie in eine Funktion aus – das spart Zeit und vermeidet Fehler.
Dokumentation hilft auch Ihnen selbst: Ein klarer DocString spart Nachdenken, wenn Sie später Ihren eigenen Code wieder verwenden oder erweitern wollen.
Funktionen sind Bausteine: Denken Sie Funktionen als kleine Werkzeuge, die sich kombinieren lassen – das macht auch komplexe numerische Probleme leichter handhabbar.