Funktionen
… oder: Wie man grössere Programme übersichtlich gestaltet.
(teilweise Vorschau auf die Videos)
Das Aufteilen eines grösseren Vorhabens in Teilvorhaben, die sogenannten Module, nennt man Modularisierung, auch modularen Entwurf oder Baukastenprinzip. Dadurch ist es leichter, die Übersicht über das gesamte Vorhaben zu behalten.
Beispiel: Beim Bau eines Hauses übernehmen verschiedene Handwerker als Spezialisten diverse Aufgaben.
In der Informatik wird dies oft durch Funktionen bewerkstelligt. Funktionen sind “Miniprogramme” oder “Unterprogramme” und erledigen eine gewisse Teilaufgabe (sie sind die “Spezialisten”).
Wir haben schon viele Funktionen kennengelernt und verwendet, z. B. print
, input
, forward
, right
, penup
, setcolor
, random.random
.
Funktionen werden aufgerufen (Funktionsaufruf), indem man den jeweiligen Funktionsnamen angibt und danach in runden Klammern die benötigten Argumente (= Übergabewerte) angibt (manchmal wird auch gar kein Argument benötigt). Als Argumente sind integers, strings, Booleans etc. erlaubt.
Die runden Klammern sind beim Funktionsaufreu stets hinzuschreiben, auch wenn keine Argumente übergeben werden.
Beispiele:
pencolor(“red”)
ist ein Aufruf der Funktionpencolor
mit“red”
als Argument.penup()
ist ein Aufruf der Funktionpenup
; diese Funktion nimmt keine Argumente entgegen.
Funktionen haben einerseits den Zweck, sonst mehrfach auftauchenden Code zu bündeln; andererseits erlauben sie es, Programme sinnvoll zu strukturieren und so lesbarer zu machen (vgl. die Videos).
Nun wirst du lernen, wie du selbst Funktionen definieren kannst!
Funktionen ohne Rückgabewert definieren (teils mit Turtle-Grafik)
Schau dir das folgende Video zu Funktionen an und löse die darin enthaltenen drei Aufgaben!
Video "Funktionen mit Parametern selbst definieren (teils mit Turtle)"
Endzustand der Programme aus dem Video (mit kleinen sprachlichen Verbesserungen):
Funktionen mit Rückgabewert definieren
Schau dir das folgende Video zu Funktionen an und löse die darin enthaltenen Aufgaben!
Definition von Funktionen (wurde in den Videos bereits erklärt)
Eine Funktionsdefinition sieht in Python wie folgt aus:
def <Name der Funktion>(<keiner, einer oder mehrere durch Kommas getrennte Parameter>): # Hier steht, # um vier Leerschläge eingerückt, # was die Funktion tut. # # Falls ein Rückgabewert zurückgegeben werden soll: return <Ausdruck, der den Rückgabewert berechnet>
In Worten:
- Die Funktionsdefinition wird mit einer Kopfzeile eingeleitet:
- Sie beginnt mit dem Schlüsselwort
def
(für define). - Danach kommt der Name der Funktion, der im Wesentlichen frei gewählt werden kann.
- Danach kommt ein Paar von Klammern, zwischen denen nichts steht oder ein Parameter (Name frei wählbar) oder mehrere durch Kommas getrennte Parameter.
- Danach kommt ein Doppelpunkt
:
.
- Nun folgt in den nächsten Zeilen eingerückt der eigentliche Code der Funktion (“body of the function”).
- Optional, wenn ein Rückgabewert zurückgeliefert werden soll1): Verwende das Schlüsselwort
return
und schreibe dahinter den Ausdruck für den Rückgabewert.
Die Syntax ist also ähnlich wie bei for
- oder while
-Schleifen und if
-Statments: Eine Art Kopfzeile mit Doppelpunkt am Ende, danach eingerückt der eigentliche Code: Dieser wird bei jedem Funktionsaufruf ausgeführt.
Aufgaben
Aufgabe: Liste der ersten Primzahlen; Funktion mit Rückgabewert
Öffne eine neues Python-Programm.
(1) Schreibe eine Funktion2) ist_prim(x)
, die entscheidet, ob der Parameterx
eine Primzahl ist, und dementsprechend True
oder False
zurückgibt.
(2) Nutze deine Funktion ist_prim
, um eine Liste aller Primzahlen bis n = 10000
auszugeben.
Hinweis: Damit nicht jede Primzahl in einer neuen Zeile steht: Der Befehl print(p, end = “, ”)
gibt den Wert der Variablen p
aus, danach ein Komma gefolgt von einem Leerschlag, und geht danach nicht in die nächste Zeile.
Bemerkung: Diese Methode, eine Liste von Primzahlen, ist nicht besonders effizient. Schneller geht es etwa mit dem Sieb des Eratosthenes.
Aufgabe: Mäander (Ornamentik); Funktion ohne Rückgabewert
Ziel der Aufgabe ist, den kreisförmigen Mäander effizient zu zeichnen.
Da die rote Figur mehrfach vorkommt, ist es sinnvoll, diese Figur von einer Funktion zeichnen zu lassen.
- (1) Definiere eine Funktion
ornament(a)
: Sie soll den roten Streckenzug zeichnen, wobei das “kürzeste” Teilstücka
Pixel lang ist. Die beiden anderen Teilstücke sind dann2 * a
und3 * a
Pixel lang. Der Streckenzug soll links oben beginnend gezeichnet werden mit Blickrichtung der Turtle nach rechts; am Ende soll sie wieder nach rechts schauen).
Hinweis: Die Bilder wurden mit a = 20
erzeugt.
- (2) Verwende deine Funktion und eine for-Schleife, um den folgenden Mäander zu zeichnen (alles soll einfarbig sein). Passe die Stiftdicke geeignet an.
- (3) Ändere dein Programm so, dass der obige kreisförmige Mäander entsteht, der aus
n = 23
Einzelmustern besteht (wieder alles einfarbig). Zum anfänglichen Positionieren der Turtle könnte die folgende Infobox nützlich sein.
Direktes Positionieren der Turtle
Die wichtigsten Zustandsparameter der Turtle sind ihre Position und ihre Blickrichtung (weniger wichtig sind Farbe und Stiftdicke etc.).
- Ihre Position wird durch $x$- und $y$-Koordinate angegeben.
- Ihre Blickrichtung wird durch einen Winkel in Grad angegeben: $0^\circ$: nach rechts; $90^\circ$: nach oben, $180^\circ$: nach links etc.
Das zugrunde liegende Koordinatensystem liegt zentriert im Standard-Turtle-Fenster: Sichtbar sind alle Punkte mit
- x-Koordinaten zwischen -473 und +473 und
- y-Koordinaten zwischen -398 und +398. 3)
Man kann die Turtle direkt in einen gewissen Zustand versetzen:
setposition(-100, 50)
bewegt die Turtle auf den Punkt $(-100, 50)$. (Kürzer hatsetpos(-100, 50)
denselben Effekt.)setheading(45)
dreht man die Turtle so, dass ihre Blickrichtung zur positiven $x$-Achse einen Winkel von $45^\circ$ bildet bildet (in mathematisch positivem Drehsinn, also dem Gegenuhrzeigersinn), die Turtle schaut also nach rechts oben. (Kürzer hatseth(45)
denselben Effekt.)home()
bewegt die Turtle in die Start-Position.
W3Schools-Material zu Funktionen
Alles vor dem roten Kasten sollte bekannt sein auf der Seite https://www.w3schools.com/python/python_functions.asp.
Exercises dazu (die ersten vier Fragen solltest du beantworten können): https://www.w3schools.com/python/exercise.asp?filename=exercise_functions1
Weitere Bemerkungen zu Funktionen (einiges wurde bereits in den Videos erklärt)
Zum besseren Verständnis ist es sinnvoll, Funktionen in vier Arten einzuteilen, je nachdem, ob sie
- Parameter besitzen oder nicht (also Argumente beim Funktionsaufruf angegeben werden müssen oder nicht);
- einen Rückgabewert zurückgeben oder nicht.
In der folgenden Tabelle ist für jeder dieser vier Arten ein Beispiel angegeben und darunter ein Aufruf der Funktion.
Funktionen | ohne Parameter | mit Parameter(n) |
---|---|---|
ohne Rückgabewert | penup | pensize |
penup() | pensize(10) |
|
mit Rückgabewert | random.random | input |
random.random() | input(“Wie heisst du?”) |
Grob gesagt kann man Aufrufe und Definitionen von Funktionen daran erkennen, dass nach ihnen ein Paar runder Klammern (mit oder ohne Argumente bzw. Parameter dazwischen) auftaucht!
Beachte: Sogenannte Schlüsselworte wie if
, else
, for
, while
, def
etc. sind keine Funktionen. Sie werden verwendet, um den Ablauf von Python-Programmen zu steuern.
Bisher nicht in diesem Kurs erklärt: Variablen haben in Python Geltungsbereiche, vgl. https://www.w3schools.com/python/python_scope.asp.
Dies erlaubt, denselben Variablennamen mehrfach zu verwenden (etwa eine Variable namens x
im “Hauptprogramm” und eine Variable (oder einen Parameter) namens x
in einer Funktion), ohne dass dies zu Konfliken führt.
Wenn man als Programmieranfänger auf Nummer sicher gehen will, verwende man jeden Variablennamen nur einmal.
Bonus-Aufgabe: Funktionen zum Zeichnen einer Spirale und zum "unsichtbaren" Bewegen der Turtle
Ergänze das folgende Programm um die Definition zweier Funktionen (um so das obige Bild zu zeichnen):
- Eine Funktion
spirale
mit vier Parametern: Der Funktionsaufrufspirale(80, 1, 2, 61)
soll eine Spirale aus 80 Segmenten mit Anfangslänge 1, Veränderung 2 und Abbiegewinkel 61 zeichnen (also die leicht verdrehte hexagonale Spirale im obigen Screenshot). - Eine Funktion
bewege_unsichtbar
mit zwei Parametern: Der Funktionsaufrufbewege_unsichtbar(-200, 200)
soll die Turtle ohne zu zeichnen auf die Position (-200, 200) bewegen.
- vorlage-funktionen-spirale-und-bewege.py
from turtle import * def spirale(n, a, veraenderung, winkel): # # Ergänze hier den "Funktionsrumpf" der Funktion "spirale", # also den Code, der eine Spirale abhängig # von den obigen Parametern zeichnet. # # Ergänze hier die Definition der Funktion "bewege_unsichtbar". # Hinweis: Verwende die Funktion "setpos(x,y)". speed(0) bewege_unsichtbar(200, 200) spirale(40, 10, 5, 90) bewege_unsichtbar(-200, 200) spirale(30, 10, 5, 360/6) bewege_unsichtbar(-200, -200) spirale(80, 1, 2, 61) bewege_unsichtbar(200, -200) spirale(150, 1, 0.3, 360/20) exitonclick()
Link zur Kursseite
ist_prim
(und nicht ist_prim(x)
).