lehrkraefte:snr:informatik:python:funktionen

Funktionen

Mit dem Schlüsselwort def (für define) kann man Funktionen definieren. Wie man an den Beispielen unten sieht, ist die Syntax ähnlich wie bei Schleifen (for) und Bedingungen (if): Ein Doppelpunkt ist in der “Kopfzeile” nötig, der eigentliche Code der Funktion ist einzurücken.

Funktionen nehmen einen oder mehrere oder auch gar keinen Wert als Input (man spricht auch von den Parametern der Funktion). Als Wert sind integer, string, Boolean etc. erlaubt. Funktionen können (müssen aber nicht) mit Hilfe des Schlüsselworts return einen Wert zurückgeben (so wie man das erwartet, wenn man an den Funktionsbegriff in der Mathematik denkt).

Funktionen haben einerseits den Zweck, sonst mehrfach auftauchenden Code zu bündeln; andererseits dienen sie der besseren Struktur/Lesbarkeit des Programms.

Verstehe die folgenden Programme.

# Funktion mit einem Parameter
def quadrat(x):
    return x*x
 
print(quadrat(12))
# Dieses Beispiel zeigt, dass Funktion recht flexibel sind, was Parameter angeht:
# Hier kann der Übergabeparameter sowohl eine Zahl als auch ein String sein.
# (Viele andere Programmiersprachen sind weniger flexibel.)
def quadrat(x):
    return 3*x

print(quadrat(14))
print(quadrat("abc"))
# Funktion mit zwei Parametern
def addiere(x,y):
    return x + y
 
print(addiere(2, 5))
# Funktion ohne Parameter
def gib_text_aus():
    print("Hallo Welt")
 
gib_text_aus()
print(gib_text_aus())
# Gibt eine Funktion wie hier keinen Wert mit "return" zurück, so gibt Python per Konvention den Wert "None" zurück.

Implementiere die Fakultätsfunktion $n!$ und die Binomialkoeffizientenfunktion $n \choose k$ in Python und teste sie, zum Beispiel durch Ausgabe des Pascalschen Dreiecks (in möglichst schöner Formatierung!).

Du kannst einer Funktion auch eine Liste als Parameter übergeben. Schreibe ein Programm, das dies ausnutzt! - Etwa ein Programm, das den Durschnitt einer Liste von Zahlen ausrechnet.

Jemand hat versucht, ein Programm zu schreiben, dass alle Primzahlen kleiner-gleich n ausgibt, die Ausgabe ist aber falsch. Verbessere das Programm (es genügt, vier Zeichen (und eventuell Leerzeichen) zu ergänzen)!

Bemerkung: Sobald die return-Anweisung in einer Funktion aufgerufen wird, wird die weitere Ausführung der Funktion abgebrochen.

(Hierbei steht sqrt(…) für “square root”, Quadratwurzel und int(…) macht aus einer Kommazahl eine ganze Zahl.)

# Fehlerhaftes Programm!
n = 97
 
def ist_prim(x):
    for t in range(2, int(sqrt(x))):
        if x % t == 0:
            return False
    return True
 
l = []
for i in range(2, n):
    if ist_prim(i):
        l.append(i)
 
print(l) 

Funktionen können sich selbst aufrufen! Dies ist oftmals sehr hilfreich (siehe Abschnitt Rekursion).

Ändere das folgende Programm so, dass es nach endlicher Zeit endet!

Abbruch mit dem roten Achteck in der Menüleiste von Tigerjython.

# Nicht endendes Programm (es sei denn, der Strom fällt aus oder der Computer verrottet oder
#  - was in Wirklichkeit eintritt - es gibt einen Laufzeitfehler, wie du sehen wirst.)
def schreibe(n):
    print(n * "A" + ";")
    schreibe(n+1)
    print(n * "B" + ";")
 
schreibe(1)
print("Ende")

Hinweis ausklappbar

Hinweis ausklappbar

Ersetze die Zeile schreibe(n+1) beispielsweise durch

    if n < 10:
        schreibe(n+1)

ACHTUNG, ICH HATTE LEIDER ZUNÄCHST DAS AUSRUFEZEICHEN IN DER ZWEITEN ZEILE VERGESSEN!

Versuche die folgende Definition der Fakultätsfunktion

in ein Programm zu übersetzen.

Wenn dir das gelingt, hast du “selbst” entdeckt, was Rekursion ist: Eine Funktion, die sich selbst (oft auch mehrfach) aufruft - aber so, dass das Programm nicht unendlich lange läuft.

Die obige Definition ist übrigens die sogenannte induktive oder rekursive Definition der Fakultätsfunktion.

Globale und lokale Variablen

Überrascht dich die Ausgabe des folgenden Programms?

def test():
    s = "Welt"
    print(s)
 
s = "Hallo" 
test()
print(s)

Variablen haben Sichtbarkeitsbereiche (englisch scope). Bevor wir Funktionen kennengelernt hatten, war dies unwichtig: Alle Variablen waren sogenannte globale Variablen.

Im obigen Beispiel gibt es einerseits die globale Variable s (mit wert “Hallo”), andererseits die lokale Variable s in der Funktion test. Diese beiden Variablen tragen (aus didaktischen Gründen) denselben Namen, werden aber beim Ablauf des Programms vollkommen unabhängig voneinander behandelt - so als ob die eine Variable s1 und die andere s2 hiesse. Innerhalb der Funktion ist nur die lokale Variable s in dem Sinne sichtbar, dass man kann ihren Wert abrufen und ändern kann. Ausserhalb ist nur die globale Variable s sichtbar.

  • Lösche im obigen Programm den Befehl s = “Welt” und teste das Programm.
  • Füge diesen Befehl dann in der Funktion HINTER print(s) wieder ein und teste das Programm!

Wir lernen daraus: Solange es keine lokale Variable gleichen Namens gibt, ist eine globale Variable wie s im Beispiel (= im ganzen Programm) lesbar zugänglich, kann aber innerhalb von Funktionen nicht verändert werden. Existiert eine lokale Variable gleichen Namens, so muss diese in ihrer Funktion zunächst initialisiert werden (etwa mit s = “Welt”), bevor man auf sie zugreifen kann.

Manchmal ist es jedoch sinnvoll, eine globale Variable auch innerhalb von Funktionen verändern zu können (wie es ja der Name global eigentlich nahelegt)1). Dies geschieht, indem man am Funktionsbeginn mit dem Schlüsselwort global expliziert festlegt, dass auch dieser “Schreibzugriff” auf die Variable möglich ist:

def test():
    print(s)
    global s
    s = "Welt"
    print(s)
 
s = "Hallo" 
test()
print(s)

In diesem Beispiel bedeutet der Befehl s = “Welt” also nicht wie zuvor “lege eine neue lokale Variable ss mit dem Wert “Welt” an. Stattdessen wird der globalen (mit global lokal veränderlich gemachten) Variablen ss der Wert “Welt” zugewiesen.

Vermutlich ist es intuitiv klar, der Vollständigkeit halber sei aber erwähnt, dass lokale Variablen ausserhalb ihres Sichtbarkeitsbereichst nicht zugänglich sind in dem Sinne, dass ihr Wert nicht abrufbar ist:

def test():
    s = "Welt"
    print(s)
 
test()
if s == "Welt":
    print("Weltschmerz")
# s = "Hallo"
# print(s)

Wenn man hier aber die if-Kontrollstruktur durch die beiden auskommentierten Zeilen ersetzt, so funktioniert das Programm wieder: Nun gibt es aber wie oben zwei voneinander unabhängige Variablen mit dem Namen s.

Fakultät

Fakultät

def fakultaet(x):
    wert = 1
    for i in range(1, x + 1):
        wert = wert * i
    return(wert)
 
print(fakultaet(5))
 
for k in range(10):
    print("%d! = %d" % (k, fakultaet(k)))

1)
in vielen Programmiersprachen ist dies standardmässig möglich
  • lehrkraefte/snr/informatik/python/funktionen.txt
  • Last modified: 2021/11/04 18:09
  • by Olaf Schnürer