Seite anzeigenÄltere VersionenLinks hierherCopy this pageFold/unfold allNach oben Diese Seite ist nicht editierbar. Du kannst den Quelltext sehen, jedoch nicht verändern. Kontaktiere den Administrator, wenn du glaubst, dass hier ein Fehler vorliegt. ===== Funktionen ===== Komplexe Programme können mit Hilfe von Funktionen in kleinere, leichter zu programmierende Teilprogramme zerlegt werden. Solche Teilprogramme können zudem mehrmals verwendet werden. ==== Definition ==== Eine **Funktion** ist immer wie folgt aufgebaut: <code python> def name_der_funktion(PARAMETER): # Parameter sind optional # CODE DER FUNKTION return RETURN_WERT # optional </code> * Das Schlüsselwort `def` leitet immer die Definition einer Funktion ein. * Darauf folgt der **Funktionsname**. Typischerweise schreibt man diesen ausschliesslich mit Kleinbuchstaben und Underscores `_`. * Direkt anschliessend werden `(`**runde Klammern**`)` geschrieben. Diese enthalten die **Parameter**. Das sind Werte, die an die Funktion übergeben werden. Funktionen können auch ohne Parameter definiert werden, die Klammern sind dann halt einfach leer. * Nach einem **Doppelpunkt** `:` * folgt der **Funktionskörper**, welcher den eigentlichen Code der Funktion beinhaltet. Dieser Code muss **eingerückt** sein. Nachdem du eine Funktion definiert hast, kannst du sie ganz einfach aufrufen. Dazu mehr in den Beispielen unten. Übrigens hast du schon viele Funktionen kennengelernt - ohne dass du es wahrscheinlich gemerkt hast. Zum Beispiel ist die Funktion `print()` für Turtles eine Funktion, die die Parameter ausgibt. Diese Funktion wurde vorprogrammiert. Nun wollen wir schauen, wie wir unsere eigenen Funktionen definieren können. ==== Funktionen ohne Rückgabewert ==== In diesem Unterkapitel schauen wir Funktionen ohne Rückgabewert an, also Funktionen ohne das `return`-Statement am Ende. **Beispiel:** Du möchtest das gleiche Quadrat mehrfach zeichnen. Dies kannst du wie folgt machen: <code python> from turtle import * fritz = Turtle() fritz.hideturtle() # Quadrat 1 fritz.setpos(-130,0) repeat 4: fritz.forward(100) fritz.left(90) # Quadrat 2 fritz.setpos(0,0) repeat 4: fritz.forward(100) fritz.left(90) </code> Es fällt auf, das hier zweimal der //identische// Code vorkommt: <code python> repeat 4: fritz.forward(100) fritz.left(90) </code> Dies ist nicht sehr elegant. Wenn man nun das gleiche Quadrat zehnmal zeichnen möchte, wird es noch viel schlimmer! Es lohnt sich deshalb hier, eine Funktion //quadrat// zu definieren und diese dann mehrfach aufzurufen: <code python> from turtle import * fritz = Turtle() fritz.hideturtle() def quadrat(): repeat 4: fritz.forward(100) fritz.left(90) # Quadrat 1 fritz.setpos(-130,0) quadrat() # Quadrat 2 fritz.setpos(0,0) quadrat() </code> Beachte, dass in obigem Code jeweils zuerst die Position der Turtle festgelegt wird, bevor die Funktion aufgerufen wird. Noch eleganter wäre es, wenn das Setzen der Position //in der Funktion// geschieht. Die Koordinaten könnten dann der Funktion als **Argument** übergeben werden: <code python> from turtle import * fritz = Turtle() fritz.hideturtle() def quadrat(x,y): fritz.setpos(x,y) repeat 4: fritz.forward(100) fritz.left(90) # Quadrat 1 quadrat(-130,0) # Quadrat 2 quadrat(0,0) </code> Du kannst der Funktion auch noch weitere Argumente übergeben, zum Beispiel um die Grösse des Quadrats und dessen Farbe anzugeben: <code python> from turtle import * fritz = Turtle() fritz.hideturtle() def quadrat(x,y,seite,farbe): fritz.setpos(x,y) fritz.pencolor(farbe) repeat 4: fritz.forward(seite) fritz.left(90) # Quadrat 1 quadrat(-130,0,70,"red") # Quadrat 2 quadrat(0,0,100,"magenta") </code> ==== Funktionen mit Rückgabewert ==== Funktionen bieten sich auch an, wenn man mehrfach die gleiche Rechnung, einfach mit verschiedenen Werten, ausführen möchte. Allerdings möchte man dann, dass die Funktion einem das Resultat als **Rückgabewert** zurück gibt. **Beispiel:** Wir wollen eine Funktion definieren, die uns das Volumen eines Quaders zurück gibt. Falls der Quader die Seitenlängen $a,b$ und $c$ hat, so ist sein Volumen $$V = a \cdot b \cdot c$$ Die zugehörige Funktion ist dann: <code python quader.py> def quader(a,b,c): resultat = a*b*c return resultat print(quader(4,3,2)) </code> Auf der letzten Zeile wird das Volumen für einen Quader mit Seitenlängen $4, 3$ und $2$ berechnet und dann in der Konsole ausgegeben. ==== Probleme mit Funktionen ==== [[gf_informatik:funktionen:problems|Probleme mit Funktionen]] ==== Aufgaben G – Funktionen ohne/mit Rückgabewert ==== === Aufgabe G1 === Für diese Aufgabe benötigst du Turtle graphics. - Definiere eine Funktion namens ''spirale()''. Diese zeichnet eine beliebige Spirale aus mindestens 6 Halbkreisen. - Rufe im Code die Funkton ''spirale()'' mindestens dreimal auf. Ändere vorher jeweils die Position deiner Turtle (mit ''setpos()''), sodass die drei Spiralen an unterschiedlichen Orten gezeichnet werden. === Aufgabe G2 === - Erweitere die Funktion ''spirale()'' aus obiger Aufgabe in die Funktion ''spirale(x, y)'': Neu sollst du der Funktion die Startposition (x- und y-Koordinate) übergeben können. - Rufe im Code die Funkton ''spirale()'' mindestens drei mal auf, sodass die drei Spiralen an unterschiedlichen Orten gezeichnet werden. === Aufgabe G3 === - Erweitere die Funktion ''spirale()'' erneut: Neu sollst du der Funktion neben der Startposition (x- und y-Koordinate) auch die Anzahl Halbkreise und die Grösse des Radius des kleinsten Halbkreises übergeben können. - Rufe im Code die Funkton ''spirale()'' mindestens drei mal mit unterschiedlichen Parametern auf. === Aufgabe G4 === Für diese Aufgabe benötigst du Turtle graphics. Definiere folgende Funktionen: * quadrat(turtle, seitenlaenge, farbe, x, y) * dreieck(turtle, seitenlaenge, farbe, x, y) * kreis(turtle, radius, farbe, x, y) Ruft man z.B. die Funktion `dreieck(michelangelo, 100, "red", -200, 50)` auf, soll die Turtle namens //michelangelo// ein //rotes// Dreieck mit Seitenlänge //100// und Startpunkt //(-200,50)// zeichnen. **Wichtig:** Die Turtle muss zuerst erstellt werden (z.B.: ''michelangelo = Turtle()''), damit sie der Funktion übergeben werden kann. Zeichne mit diesen Funktionen ein Bild. Jede der drei Formen soll mindestens 3 mal vorkommen. Variiere die Farbe und Grösse der Formen. == Erweiterung (Optional) == Erstelle ein Python Modul: * Speichere die Geometrie-Funktionen in einer separaten Datei `geometrie.py`. * Erstelle eine zweite Datei `g4.py` im selben Ordner. * In `g4.py` importierst du das Geometrie-Modul mit `import geometrie`. * Die importierten Funktionen müssen zur Verwendung qualifiziert werden, z.B. `geometrie.dreieck(...)`. * Zeichne mit den Funktionen abstrakte Kunst (wie oben). <nodisp 1> ++++Lösung| <code python geometrie.py> def vieleck(turtle, ecken, seite, farbe, x,y): turtle.setpos(x,y) turtle.pencolor(farbe) # Aussenwinkel eines Vielecks summieren sich auf 360° # https://de.wikipedia.org/wiki/Aussenwinkel winkel = 360 / ecken repeat ecken: turtle.forward(seite) turtle.left(winkel) def quadrat(turtle, breite, farbe, x, y): vieleck(turtle, 4, breite, farbe, x, y) def dreieck(turtle, breite, farbe, x, y): vieleck(turtle, 3, breite, farbe, x, y) def kreis(turtle, radius, farbe, x, y): turtle.setPos(x,y) turtle.setPenColor(farbe) turtle.leftArc(radius, 360) </code> <code python kunst.py> import geometrie from turtle import * t = Turtle() t.hideturtle() geometrie.quadrat(t, 100, "red", 0, 0) geometrie.kreis(t, 50, "blue", 0, 50) geometrie.dreieck(t, 75, "green", -100, 100) </code> ++++ </nodisp> === Aufgabe G5 === Kennt man in einem rechtwinkligen Dreieck die beiden Katheten, so kann man mit dem Satz von Pythagoras die Hypothenuse bestimmen. Definiere eine Funktion mit Namen //pythagoras//. Als Argumente soll man die beiden Katheten eines rechtwinkligen Dreiecks eingeben. Die Funktion berechnet dann die Hypothenuse und gibt diese mit //return// zurück. //Tipp:// Die Wurzel einer Zahl ziehst du mit `sqrt(x)`, dazu musst du aber zuerst das math-Modul importieren: `import math`. //Kontrolle:// Für die Katheten 3 und 4 ist die Hypothenuse 5. Die Codezeile `print(pythagoras(3,4))` soll dann also `5.0` ausgeben. <nodisp 1> ++++Lösung| <code python> import math def pythagoras(a, b): return math.sqrt(a**2 + b**2) print(pythagoras(3,4)) </code> ++++ </nodisp> === Aufgabe G6 === Das Volumen einer Kugel mit Radius $R$ ist: $$V = \frac{4\pi}{3}\cdot R^3$$ Definiere eine Funktion //kugel//, der man als Argument den Radius übergibt und die dann das Volumen zurückgibt. Die Kreiszahl Pi ($\pi$) kannst du mit `math.pi` aufrufen, dazu muss aber auch wieder zuerst das math-Modul importiert werden (`import math`). <nodisp 1> ++++Lösung| <code python> import math def kugel_volumen(radius): return 4 * math.pi / 3 * radius**3 print kugel_volumen(2) </code> ++++ </nodisp> === Aufgabe G7 === Definiere eine Funktion //wuerfel//, welche einen Würfel simuliert, d.h. eine Zufallszahl zwischen 1 und 6 mit //return// zurückgibt. {{:gf_informatik:pasted:20230215-091017.png?150|}} <nodisp 1> ++++Lösung| <code python> import random def wuerfel(): return random.randint(1,6) print(wuerfel()) </code> ++++ </nodisp> == Challenge (optional) == Simuliere mit TurtleGraphics einen Würfel. ==== Aufgaben GA – Funktionen mit Algorithmen (ohne/mit Rückgabewert) ==== === Aufgabe GA1 – Fibonacci-Zahlen === Schreibe eine Funkton namens //fibonacci_numbers//, die beliebig viele Elemente der [[https://de.wikipedia.org/wiki/Fibonacci-Folge|Fibonacci-Folge]] ausgibt. Zum Beispiel soll ''fibonacci_numbers(8)'' die ersten acht Elemente der Fibonacci-Folge ausgeben, also 0, 1, 1, 2, 3, 5, 8, 13. Teste die Funktion, indem du sie mit unterschiedlichen Werten aufrufst. Tipp: Setze in der Funktion zuerst zwei Variablen a und b auf die ersten beiden Fibonacci-Zahlen (0 und 1) und gebe diese nacheinander aus. Erst jetzt beginnt eine sich wiederholende Abfolge von Code-Zeilen für die Ausgabe der weiteren Werte. <nodisp 1> ++++Lösung| <code python> def fibonacci_numbers(anz): a = 0 b = 1 print a print b repeat anz-2: c = a + b print c a = b b = c fibonacci_numbers(8) </code> ++++ </nodisp> === Aufgabe GA2 – Fibonacci-Muster === Schreibe eine Funkton namens //fibonacci_arcs//, die eine Spirale aus Viertel-Kreisen zeichnet, deren Radien gemäss der [[https://de.wikipedia.org/wiki/Fibonacci-Folge|Fibonacci-Folge]] zunehmen. Zum Beispiel soll ''fibonacci_arcs(8)'' acht Viertelkreise zeichnen. **Beachte Folgendes:** * Hier soll die Fibonacci-Folge nicht mit 0, sondern mit 1 beginnen (a = b = 1). * Multipliziere die Fibonacci-Zahlen mit einem Faktor, zum Beispiel 5, um den Radius zu erhalten. Teste die Funktion: ''fibonacci_arcs(9)'' sollte etwa folgendes Muster ergeben: {{:gf_informatik:pasted:20230214-194805.png?200|}} <nodisp 1> ++++Lösung| <code python> from turtle import * leonardo = Turtle() def fibonaci_arcs(n): a = b = 1 leonardo.circle(a*5, 180) # erste zwei Viertelkreise repeat n-2: c = a + b leonardo.circle(c*5, 90) a = b b = c fibonaci_arcs(9) </code> ++++ </nodisp> === Aufgabe GA3 – Fibonacci-Muster mit Zeitmessung === Erweitere die Funktion //fibonacci_arcs// so, dass sie die Zeit zum Zeichnen des Musters misst und diesen Wert zurückgibt. Importiere dazu das //time//-Modul (''import time'') und nutze die Funktion ''time()'', um einen Zeitstempel in Sekunden zu erhalten: <code python> import time time1 = time.time() ## some code that takes some time ## ... time2 = time.time() time_passed = time2 - time1 </code> Teste die Funktion zum Beispiel so: <code python> print(fibonacci_arcs(9)) </code> Damit sollte dein Code das Muster aus neun Viertelkreisen zeichnen und anschliessend die gemessene Anzahl Sekunden ausgeben. <nodisp 1> ++++Lösung| <code python> import time from turtle import * leonardo = Turtle() def fibonaci_arcs(n): start_time = time.time() a = b = 1 leonardo.circle(a*5, 180) # erste zwei Viertelkreise repeat n-2: c = a + b leonardo.circle(c*5, 90) a = b b = c return(time.time()-start_time) print(fibonaci_arcs(9)) </code> ++++ </nodisp> === Aufgabe GA4 === Schreibe eine Funktion //summe\_ungerade//, die die Summe aller ungeraden Zahlen von 0 bis n zurückgibt. Zum Beispiel soll ''summe\_ungerade(5)'' die Zahl 9 zurückgeben. Auch ''summe\_ungerade(6)'' soll natürlich 9 zurückgeben. //Tipp:// Verwende eine Zählvariable und eine While-Schleife. <nodisp 1> ++++Lösung| <code python> # Variante 1 def summe_ungerade1(n): i = 1 summe = 0 while i <= n: summe = summe + i i = i + 2 return summe # Variante 2 def summe_ungerade2(n): i = 0 summe = 0 while i <= n: if i % 2 != 0: summe = summe + i i = i + 1 return summe print(summe_ungerade1(7)) print(summe_ungerade2(7)) </code> ++++ </nodisp> === Aufgabe GA5 (Herausforderung) === Die Fakultät ist eine Funktion, welche jeder ganzen natürlichen Zahl das Produkt aller natürlichen Zahlen (ohne Null) kleiner und gleich dieser Zahl zuordnet. Sie wird mit einem Ausrufezeichen geschrieben. Als Beispiel: $5!=1 \cdot 2 \cdot 3 \cdot 4 \cdot 5 =120$. Schreibe eine Funktion //fakultaet//, welcher als Argument eine ganze Zahl übergeben wird und welche dir dann die Fakultät dieser Zahl zurückgibt. **Grosse Herausforderung**: Kannst du die Fakultät ganz ohne Schleife berechnen? Dann hast du das Prinzip der *Rekursion* (Selbst-Aufruf) entdeckt! <nodisp 1> ++++Lösung| <code python> def fakultaet(n): result = 1 i = 2 while i <= n: result = result * i i = i + 1 return result print(fakultaet(5)) </code> Rekursiv: <code python> def fakultaet(n): if n == 1: return 1 return n * fakultaet(n-1) print(fakultaet(5)) </code> Siehe [[https://youtu.be/DUC1qg7ZaRg|dieses Video]] zur Erklärung ++++ </nodisp> === Aufgabe GA6 (optional) === In [[https://sca.ksr.ch/doku.php?id=gf_informatik_1m_20_21:python_zusatzaufgaben#euklidischer_algorithmus|dieser Zusatzaufgabe]] wird der //euklidische Algorithmus// benutzt, um den ggT von zwei Zahlen zu berechnen. Schreibe zwei Funktionen //ggt// und //kgv//, welche als Argumente zwei Zahlen nehmen und daraus den grössten gemeinsamen Teiler bzw. das kleinste gemeinsame Vielfache berechnen. Das kGV zweier Zahlen erhältst du, indem du das Produkt dieser Zahlen durch den ggT der beiden Zahlen teilst. Es lohnt sich also, zuerst die Funktion //ggt// zu definieren, damit diese dann in der Definition der Funktion //kgv// aufgerufen werden kann. Wenn du das gemacht hast: Erstelle eine weitere Funktion //ggt_kgv//, welche als Argument zusätzlich einen String mit "ggt", bzw. "kgv" entgegennimmt und dann entweder den ggT bzw. das kgV ausgibt. gf_informatik/funktionen_2022.txt Zuletzt geändert: 2023-11-16 14:52von hof