… 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 Funktion pencolor
mit “red”
als Argument.penup()
ist ein Aufruf der Funktion penup
; 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!
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):
Schau dir das folgende Video zu Funktionen an und löse die darin enthaltenen Aufgaben!
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:
def
(für define).:
.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.
Ö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.
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.
ornament(a)
: Sie soll den roten Streckenzug zeichnen, wobei das “kürzeste” Teilstück a
Pixel lang ist. Die beiden anderen Teilstücke sind dann 2 * a
und 3 * 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.
n = 23
Einzelmustern besteht (wieder alles einfarbig). Zum anfänglichen Positionieren der Turtle könnte die folgende Infobox nützlich sein. Die wichtigsten Zustandsparameter der Turtle sind ihre Position und ihre Blickrichtung (weniger wichtig sind Farbe und Stiftdicke etc.).
Das zugrunde liegende Koordinatensystem liegt zentriert im Standard-Turtle-Fenster: Sichtbar sind alle Punkte mit
Man kann die Turtle direkt in einen gewissen Zustand versetzen:
setposition(-100, 50)
bewegt die Turtle auf den Punkt $(-100, 50)$. (Kürzer hat setpos(-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 hat seth(45)
denselben Effekt.)home()
bewegt die Turtle in die Start-Position.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
Zum besseren Verständnis ist es sinnvoll, Funktionen in vier Arten einzuteilen, je nachdem, ob sie
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.
Ergänze das folgende Programm um die Definition zweier Funktionen (um so das obige Bild zu zeichnen):
spirale
mit vier Parametern: Der Funktionsaufruf spirale(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). bewege_unsichtbar
mit zwei Parametern: Der Funktionsaufruf bewege_unsichtbar(-200, 200)
soll die Turtle ohne zu zeichnen auf die Position (-200, 200) bewegen.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()
ist_prim
(und nicht ist_prim(x)
).