Benutzerdefinierte Funktionen

Einführung

Programmierer können mit einigen ganz schön komplexen und abstrakten Probleme umgehen, aber ein Zug von guten Programmierern ist, dass sie faul sind. Sie wollen nur mit einer Sache gleichzeitig umgehen müssen. Also brauchst du einen Weg um Probleme in kleinere, abgesonderte Teile zu zerlegen, damit du dich auf nur einen Teil konzentrieren kannst.

Funktionen sind ein Weg um diese Abstraktion in Python abzubilden. Lass uns turtle.reset() betrachten. reset ist eine Funktion die wir auf unserer turtle aufrufen und es ist eigentlich eine Abstraktion für eine Vielzahl von Schritten, und zwar:

  • Lösche die Zeichenfläche.

  • Setze die Linienbreite und -Farbe zurück zu den Startwerten.

  • Bewege die Schildkröte in ihre Ausgangsposition zurück.

Aber weil all dieser Quelltext in der Funktion enthalten ist müssen wir uns keine Sorgen über die Details machen. Wir können die Funktion einfach ausführen und wissen, was sie für uns tun wird.

Also - wie schreiben wir unsere eigene?

Eine Funktion kann in Python mit dem Schlüsselwort def definiert werden:

def line_without_moving():
    turtle.forward(50)
    turtle.backward(50)

Diese von uns definierte Funktion heisst line_without_moving. Sie ist eine Abstraktion für zwei Bewegungen der Schildkröte - ein Schritt vorwärts und ein Schritt rückwärts.

Um sie zu benutzen (oder wie es häufig genannt wird, “sie aufzurufen”), schreib ihren Namen gefolgt von runden Klammern:

line_without_moving()
turtle.right(90)
line_without_moving()
turtle.right(90)
line_without_moving()
turtle.right(90)
line_without_moving()

Wir könnten mehr Funktionen implementieren, um einige der Wiederholungen loszuwerden:

def star_arm():
    line_without_moving()
    turtle.right(360 / 5)

for _ in range(5):
    star_arm()

Wichtig

Python benutzt Einrückung mit Leerzeichen um zusammengehörende Codeabschnitte zu kennzeichnen. Ein Block (wie die obige Funktion) wird in Python mit einem Doppelpunkt am Ende der Zeile und Einrückung der folgenden Zeilen — üblicherweise vier Leerzeichen — gekennzeichnet. Der Block endet sobald die Zeilen nicht mehr eingerückt sind.

Das ist ein Unterschied zu vielen anderen Programmiersprachen, die Sonderzeichen (etwa geschweifte Klammern {}) verwenden um Codeblöcke zu kennzeichnen.

Verwende niemals Tabulatoren um Codeblöcke einzurücken, nur Leerzeichen. Du kannst – und solltest – Deinen Editor so konfigurieren, dass er vier Leerzeichen einsetzt sobald Du die Tab-Taste drückst. Das Problem mit den Tabulatoren ist, dass andere Programmierer Leerzeichen verwenden, und falls beide in der gleichen Python-Datei verwendet werden, wird Python sie fehlerhaft interpretieren. Im besten Fall gibt es eine Fehlermeldung und im schlimmsten Fall tauchen undurchsichtige schwer zu findende Fehler auf.

Eine Funktion für ein Viereck

Übung

Schreibe eine Funktion die ein Viereck zeichnet. Kannst du diese Funktion benutzen um das Programm mit den gekippten Vierecken zu verbessern? Lässt es sich leichter mit dem Programm experimentieren wenn du Funktionen benutzt?

Lösung

def tilted_square():
  turtle.left(20)     # now we can change the angle only here
  for _ in range(4):
      turtle.forward(50)
      turtle.left(90)

tilted_square()
tilted_square()
tilted_square()

# bonus: you could have a separate function for drawing a square,
# which might be useful later:

def square():
  for _ in range(4):
      turtle.forward(50)
      turtle.left(90)

def tilted_square():
  turtle.left(20)
  square()

# etc

Eine Funktion für ein Hexagon

Übung

Schreibe eine Funktion die ein Hexagon zeichnet.

_images/hexagon.png

Jetzt kombiniere diese Funktion zu einer Honigwabe. Zeichne erst einmal nur eine einzige Ebene, ungefähr so:

_images/honeycomb.png

Probier es selbst!

Hinweis

Stell sicher das deine Hexagonfunktion die Schildkröte zu exakt derselben Position und Ausrichtung zurückkehren lässt bevor es das Hexagon gemalt hat. Das macht es einfacher darüber nachzudenken.

Lösung

def hexagon():
  for _ in range(6):
      turtle.forward(100)
      turtle.left(60)

for _ in range (6):
    hexagon()
    turtle.forward(100)
    turtle.right(60)

Du könntest auch die Befehle turtle.forward(100); turtle.right(60) in die Funktion stellen, aber in diesem Fall solltest Du die Funktion besser nicht hexagon nennen. Das wäre irreführend, da die Funktion dann nicht nur ein Sechseck zeichnen, sondern auch zur Position der nächsten Wabe vorrücken würde. Fall Du später die Funktion hexgon ausserhalb des Wabenprogramms verwenden möchtest wäre diese Namensgebung verwirrend.