K103: Ausgabe (Schreiben) in Turtle Graphics

In diesem Themenblock lernst du, wie man in Python Texte auf unseren Turtle Graphics Bildschirm schreiben kann. 

Inhaltsverzeichnis

Dieser Blog wird vom IAIP gratis zur Verfügung gestellt. Der Blog ist ein  Bestandteil des Kurses K103 «Programmieren mit Turtle Graphics» und gehört zur Lektion 6, Themenblock 2 (L6T2).

Der Kurs führt dich durch die einzelnen Blogs, enthält Zusatzmaterialien, Videos, Lösungen zu den Aufgaben und Quizze zur Lernkontrolle. Der Kurs hat eine Kursgebühr von CHF 50.- Mit dem Einschreiben zum Kurs hilfst du mit, dass solche Blogs auch zukünftig noch gratis zur Verfügung gestellt werden können.

Einordnung

In diesem Kurs beschäftigen wir uns mit der Ausgabe von Daten auf dem Bildschirm (Monitor). Eine spezielle Form der Ausgabe, nämlich einfache graphische Zeichnungen mittels forward()circle(), etc. , haben wir bereits kennengelernt. Im Folgenden soll es nun um die Ausgabe von Texten gehen.

Allgemeines zum Thema "Ausgabe"

Für fortgeschrittene Kursteilnehmer: Ausgabegeräte, GUI und Möglichkeiten

Neben dem Empfangen und Verarbeiten von Eingaben müssen Programme in aller Regel auch wieder etwas ausgeben können. Ausgeben bedeutet dabei, eine Information über ein passendes Gerät dem Benutzer (der Aussenwelt) zugänglich machen. Die Information kann in unserem Beispiel ein Satz, eine Zahl oder eben auch eine gezeichnete Figur sein. Das klassische Ausgabegerät ist natürlich der Bildschirm. Daneben gibt es aber auch weitere Ausgabegeräte wie Drucker, Speichermedien, Lautsprecher & Kopfhörer, und viele mehr. 

Auf dem modernen PC Bildschirm siehst du meist mehrere Programme. Diese haben in der Regel eigene Fenster (Screens). Die einzelnen Fenster verkörpern dabei eine Art grafische Interaktionsschnittstelle (engl.: GUI Graphical User Interface) zum Benutzer. Hier «interagiert» der Benutzer mit dem Programm. Soll heissen, hier werden auszugebende Informationen angezeigt und auch die Eingaben des Benutzers (z.B. Tastatureingaben) werden hier wiedergegeben. Wir haben bereits zwei unterschiedliche Ausgabefenster kennengelernt: das Python Shell und unser Ausgabefenster für die Zeichnungen. 

Die Ausgabemöglichkeiten, also das was man alles darstellen kann,  hängen als erstes jeweils von der Hardware (insbesondere dem Monitor mit seiner verwendeten Technologie) ab. Auf gewissen Geräten kann man nur Zahlen oder einfache Buchstaben darstellen (siehe Taschenrechner rechts im Bild), auf anderen Geräten Linienzüge (siehe Taschenrechner mit Kurven) bis hin zu Bildern mit mehreren Millionen Farben (siehe PC Bildschirm).

Zusätzlich hängen die Ausgabemöglichkeiten auch noch von der hinter dem GUI bzw. den Fenstern hängenden Software ab. Es gibt, auch wenn wir einen noch so modernen Bildschirm haben, Fenster wie unser Python Shell, welche fast nur Texte darstellen können. Und dann gibt es Fenster wie unsere speziellen Fenster für Turtle Graphics Zeichnungen, welche alle möglichen Figuren und Farben anzeigen.

Warum ist dies hier entscheidend? Weil unterschiedliche Fenster jeweils anders «funktionieren», benötigen wir unterschiedliche Anweisungen, um in den Fenstern etwas anzeigen zu lassen. In unserem Fall gilt:

Screen (Interface) Eingabe Ausgabe von Text Ausgabe Grafiken

Python Shell

(gilt auch für Spyder Shell, trinket.io Shell, repl.it Shell etc.)</p)

input()
print()
-- nicht möglich --
Turtle Graphics Fenster (tkinter)
numinput()
textinput()
(eigenes Fenster)

write()

forward(), circle(), dot(), ...

Zur Ausgabe von Texten in unserem Turtle Graphics Fenster werden wir im folgenden die write() Anweisung nutzen. Wenn du Python (ohne Turtle Graphics) lernst, dann wirst du als erstes die Ausgabefunktion print() kennen lernen. Diese nutzte ein anderes Ausgabefenster (andere Interaktionsschnittstelle). Die Ausgabe erfolgt hier direkt in der Shell, welches ja quasi die Python Standard- Interaktionsschnittstelle zum Benutzer ist.

Ausgabe von Zeichenfolgen mittels write()

Damit kommen wir zum eigentlichen Thema: die Ausgabe von Texten auf dem Bildschirm. Die Anweisung write() (von engl. «write»: «schreiben» ) schreibt einen Text auf unseren Bildschirm. Sie hat hat die folgende Syntax:

turtle.write(arg, move=False, align=»left», font=(«Arial», 8, «normal»))

Die Anweisung hat mehrere Parameter. Zwingend ist eine Angabe für den Parameter arg:

  • arg: das, was geschrieben werden soll.

Daneben hat die write() Funktion aber noch drei optionale Parameter:

  • move: der Parameter hat die 2 möglichen Werte True (wahr) oder False (falsch) und gibt an, ob sich die Turtle beim Schreiben des Texts bewegt. Ist der Wert True, so wird die Turtle zum rechten unteren Ende des Textes bewegt.
  • align: Dieser Parameter bestimmt die Ausrichtung der Zeichenfolge. Möglich sind die Werte «left» (linksbündig), «center» (mittig zentriert) oder «right» (rechtsbündig).
  • font: Dieser Wert besteht seinerseits aus 3 Elementen (es ist ein Dreiertupel) zur Beschreibung der Schriftart

Wir werden die einzelnen Parameter gleich erläutern und ihre Funktionsweise anhand einiger Beispiele demonstrieren. Vorab aber ein Hinweis: Es gibt, abgesehen von den einzelnen Parametern, drei wichtige Unterschiede zu unseren Eingabefunktionen numinput() und textinput() aus dem letzten Themenblock:

Parameter arg​

Der erste Parameter ist wie erwähnt zwingend. Es macht ja wenig Sinn, etwas zu schreiben, ohne dass man sagt, was geschrieben werden soll. Hierzu ein kleines Beispiel:

from turtle import *

goto(-100, 100)
write("Guten Tag")

exitonclick()

Das Programm führt zu folgender Ausgabe:

Als erstes haben wir über die goto() Anweisung in Zeile 3 unsere Schildkröte an jenen Ort gebracht, wo wir unseren Text geschrieben haben wollen. Wir müssen also zuerst stets unseren Cursor (unsere Schildkröte) an den richtigen Ort fahren, so dass Python weiss, wo der Text hingeschrieben werden soll. In den folgenden Beispielprogrammen werden wir dann jeweils zuerst den Stift anheben, so dass die im Bild gezeichnete diagonale Linie nach links oben entfällt. Zum Anheben des Stifts kannst du einfach die bereits bekannte Anweisung penup() nutzen.

Anschliessend haben wir über die Anweisung write(«Guten Tag») unseren Text schreiben lassen (Zeile 4). Der Text ist hier eine sogenannte Zeichenfolge (Datentyp str). Zeichenfolgen werde in Python immer zwischen einfache ‹ ‹ oder doppelte » » Anführungs- und Schlusszeichen gesetzt. Wir können also nicht einfach nur write(Guten Tag) schreiben!

Hinweis für fortgeschrittene Kursteilnehmer:

Unsere write() Anweisung ist insofern besonders flexibel, als sie nicht nur Zeichenfolgen (Datentyp str) verarbeiten kann. Haben wir einen anderen Datentyp, beispielsweise eine Ganzzahl, Kommazahl, ein Tuple oder eine Liste, so können wir auch diesen als Parameterwert übergeben. Es gilt:

Datentyp Beispiel

Zeichenfolge (str)

write("Guten Tag")

Ganzzahl (Datentyp int)

write(5)

Gleitkommazahl (Datentyp float)

write(5.678)

Tupel (Datentyp tuple)

write((100,200))

Liste (Datentyp list)

write(["red", "blue", "green"])

Parameter move

Damit kommen wir bereits zu den drei optionalen Parametern. Betrachten wir als erstes den Parameter move, wiederum mit einem kleinen Beispielprogramm:

from turtle import *

penup()
goto(-100, 100)
write("Guten Tag", move=True)
write("wie geht es dir?", move=True)

goto(-100, 50)
write("Guten Tag", move=False)
write("wie geht es dir?")

goto(-100, 0)
pendown()
write("Schildkröte fährt mit", move=True)

exitonclick()

Das Programm führt zu folgender Ausgabe:

Als erstes haben wir wiederum unsere Schildkröte an die Position (-100, 100) bewegt. Dieses Mal haben wir allerdings vorab den Zeichenstift angehoben (Zeile 3), so dass der eher störende diagonale Strich entfällt.

Anschliessend haben wir zwei Zeichenfolgen schreiben lassen (Zeilen 5 & 6), wobei der Wert des Parameters move auf True (wahr) gesetzt wurde. move = True bewirkt, dass sich unsere Schildkröte mit dem Text bewegt. Weshalb das manchmal notwendig ist, sehen wir an der zweiten Ausgabezeile, wo die zwei Texte «Guten Tag» und «wie geht es dir?» offenbar übereinander geschrieben wurden.

Zur Demonstration haben wir also in der Programmzeile 8 unsere Schildkröte an die neue Position (-100, 50) verschoben und dieselben zwei write() Anweisungen nochmals erteilt (Zeile 9 und 10), diesmal allerdings mit move = false. Was ist passiert? In Zeile 9 weisen wir Python an, den Text «Guten Tag» auf den Bildschirm zu schreiben. Weil sich unsere Schildkröte dabei allerdings nicht mitbewegt, bleibt sie an Ort und Stelle stehen. In Zeile 10 schreiben wir dann «wie geht es dir» ausgehend von derselben Position, wie schon in Zeile 9! Aus diesem Grund werden die Texte übereinander geschrieben.

Ist dir aufgefallen, dass Python den Text auch dann schreibt, wenn der Zeichenstift oben ist? Die Ausgabe einer Zeichenfolge auf dem Bildschirm wird von der Anweisung penup() nicht beeinflusst.

Als letztes haben wir in unserem Programm den Stift wieder gesenkt und nochmals eine write() Anweisung mit move=True erteilt. Am Strich sieht man nun sehr gut, wie die Schildkröte mit dem Text «mitgeht».

Parameter align

from turtle import *

penup()
goto(-150, 100)
write("normal", move=True, align="left")

goto(-150, 50)
write("normal", move=True, align="center")

goto(-150, 0)
write("normal", move=True, align="right")

exitonclick()

Parameter font

Als letztes kann man noch über den Parameter font die Schrift definieren. Der Parameter besteht seinerseits aus drei Angaben. Die erste definiert die Schriftart, die zweite die Schriftgrösse und die dritte den Stil. Also Beispielsweise so:

write("mein Satz", move=True, font=("Arial", 12, "normal"))

Es handelt sich genau genommen um ein Tupel mit drei Werten, weshalb man die drei Angaben zwischen () Klammern schreiben muss. Wie es genau funktioniert, sieht man wiederum am besten anhand eines Beispielprogramms und dessen Ausgabe.

from turtle import *

penup()
goto(-150, 100)
write("normal", move=True, font=("Arial", 12, "normal"))
forward(10)
write("kursiv", move=True, font=("Arial", 12, "italic"))
forward(10)
write("fett", move=True, font=("Arial", 12, "bold"))
forward(10)
write("unterstrichen", move=True, font=("Arial", 12, "underline"))
forward(10)
write("durchstrichen", move=True, font=("Arial", 12, "overstrike"))

goto(-150, 50)
write("Arial 8", move=True, font=("Arial", 8, "normal"))
forward(10)
write("Arial 12", move=True, font=("Arial", 12, "normal"))
forward(10)
write("Arial 16", move=True, font=("Arial", 16, "normal"))
forward(10)
write("Arial 20", move=True, font=("Arial", 20, "normal"))

goto(-150, 0)
write("Arial", move=True, font=("Arial", 12, "normal"))
forward(10)
write("Courier", move=True, font=("Courier", 12, "normal"))
forward(10)
write("Times", move=True, font=("Times", 12, "normal"))
forward(10)
write("Verdana", move=True, font=("Verdana", 12, "normal"))
forward(10)
write("Comic", move=True, font=("Comic Sans MS", 12, "normal"))
forward(10)
write("Sans Serif", move=True, font=("MS Sans Serif", 12, "normal"))
forward(10)
write("Symbol", move=True, font=("Symbol", 12, "normal"))

exitonclick()

Das Programm führt zu folgender Ausgabe:

Für fortgeschrittene Kursteilnehmer: verfügbare Fonts:

Welche Fonts (Schriftarten) stehen zur Verfügung? Da das turtle  Module auf tkinter basiert bzw. tkinter nutzt, stammen auch die verfügbaren Fonts letztlich aus tkinter. Das Modul tkinter.font stellt die Font Klasse bereit, mit welcher sich Schriftarten generieren und abrufen lassen. Wir können die verfügbaren Fonts wie folgt abfragen:

from tkinter import Tk
import tkinter.font
Tk()
for name in sorted(tkinter.font.families()):
    print(name)

Achtung: die verwendete Ausgabeanweisung print() nutzt die Python Shell zur Ausgabe der Namen.

Exkurs: ANSI Escape Codes

Ergänzung für fortgeschrittene Kursteilnehmer:

Eine Escape-Sequenz ist eine Zeichenkombination, die sich zwar in einer Zeichenkette befindet, jedoch keinen eigentlichen Text repräsentiert. Sie wird vom Interpreter abgefangen (von engl. «escape»: «entkommen») und anstelle dessen wird eine Sonderfunktion ausgeführt.

Escape Codes kommen klassischerweise bei Terminals zur Anwendung. Bei einem Bildschirmterminal (bzw. unserer Shell) kann die über den Code ausgelöste Sonderfunktion beispielsweise die Cursor-Positionierung steuern, spezielle Zeichen darstellen oder gar die Textformatierung ändern. Immer vorausgesetzt, dass das GUI auch in der Lage ist, die entsprechende Formatierung darzustellen. Sprich der Text kann nur rot angezeigt werden, wenn das Terminal auch farbigen Text anzeigen kann.

In Python (und vielen anderen Programmiersprachen) werden Escape Sequenzen durch einen Backslash \ eingeleitet. Eine Auflistung zahlreicher nützlicher Escape Sequenzen findet sich im Anhang. Die an dieser Stelle speziell hervorzuhebenden und in den folgenden Beispielcodes teilweise verwendeten Escape Codes sind:

Steuerung des Cursors:

 \n                       Neue Zeile (Zeilenumbruch)

 \t                        Tabulator

Sonderzeichen:

 \\                        einen Backslash machen (ohne dass dieser weggelassen wird)

 \ »                       ein Anführungs- bzw. Schlusszeichen als Teil des Textes machen

Formatierung:

 \033[4m           underline (unterstreichen) starten

 \033[0m           Formatierung zurückstellen (beenden)

Bei den Sonderzeichen nutzt man Escape Codes, dass der Interpreter beispielsweise das » Zeichen nicht irrtümlicherweise als Schluss der Zeichenkette interpretiert. Es gibt aber noch andere Möglichkeiten, um » bzw. ‘ Zeichen korrekt darzustellen. Beispielsweise kann man das jeweils andere Zeichen innerhalb der Zeichenkette verwenden. Alternativ kann man sog. lange Zeichenketten benutzen. Diese beginnen und enden mit jeweils drei Anführungszeichen. Innerhalb dieser dürfen dieselben Anführungszeichen stehen (und auch Zeilenumbrüche etc. sind möglich – was va. bei der Programmierung innerhalb der interaktiven Shell sinnvoll sein kann).

Übungsaufgaben

Nachfolgend findest Du ein paar Übungsaufgaben. 

Lösungen zu den Aufgaben findest du im Kurs K103 «Programmieren mit Turtle Graphics «: 
Lektion 6, Themenblock 2 (L6T2)

Aufgabe 1: Hallo Welt

Schreibe ein Programm, welches die drei Zeichenfolgen (Texte, Sätze) «Hallo Welt.», «Ich bin dein Computer!» und «Das war es auch schon» auf den Bildschirm schreibt.

Nutze zum verschieben des Cursors die Anweisungen right() und forward()

Hinweis: Die Position der Schildkröte (der Cursor) bestimmt die Position, an welche geschrieben werden soll. Die Ausrichtung der Schildkröte ist egal.

Aufgabe 2: Hallo Welt II

Wir schreiben nun nochmals denselben Text. Dieses mal wollen wir aber, dass die Schildkröte beim Verschieben keinen Strich zieht (Anweiung penup())

Nutze zum verschieben des Cursors dieses Mal die Anweisungen goto()

Hinweis: Die goto() Anweisung verändert nur die Position, nicht aber die Ausrichtung der Schildkröte. Deshalb schaut die Schildkröte im Bild nach rechts. In unserem Fall spielt dies hier aber keine Rolle. Wie du schon in Aufgabe 1 gesehen hast, hat die Ausrichtung der Schildkröte so oder so keinen Einfluss auf die Ausrichtung des Texts. 

Aufgabe 3: Willkommen zum Spiel

Frage nun den Benutzer zuerst nach seinem Namen. Nutze hierzu die Anweisung textinput().

Anschliessend gibst du die rechts abgebildeten Sätze auf dem Bildschirm aus. Der eingegebene Namen soll nach dem «Hallo» des ersten Satzes kommen.

Hinweis: Für die weiteren Aufgaben ist es egal, ob man den Cursor mit forward() oder goto() verschiebt. Zur besseren Darstellung wird jeweils der Stift mit penup() angehoben und die Schildröte mit hideturtle() verborgen.

Aufgabe 4: Willkommen zum Spiel II

Basis bildet Aufgabe 3. Nun soll im ersten Satz am Ende noch ein Ausrufezeichen «!» kommen.

Hinweis: Es gibt verschiedene Möglichkeiten, um das Problem zu lösen. Beispielsweise:

  • Parameter move=True setzen
  • manuelles Verschieben
  • Verketten von Zeichenketten

Wie funktionieren sie? Was sind die Vor- & Nachteile?

Aufgabe 5: Willkommen zum Spiel III

Versuche die rechts abgebildete Begrüssung nachzustellen. 

Hinweis: Am einfachsten geht es, wenn man die zwei Ausgaben mittig ausrichtet. Nutze hierzu den Parameter align

Aufgabe 6: Willkommen zum Spiel IV

Versuche die rechts abgebildete Begrüssung nachzustellen.

Kombiniere hier Aufgabe 4 und 5: Der User kann anfangs seinen Namen eingeben, die Ausgabe ist mittig zentriert. 

Aufgabe 7: Willkommen zum Spiel V

Versuche die rechts abgebildete Begrüssung nachzustellen. Als erstes wird der Titel des Spiels (hier: Turtle Invaders) angezeit. Er hat eine höhere Schriftgrösse. Anschliessend wird man nach dem Namen gefragt und die sieht die Begrüssung aus Aufgabe 6.

Aufgabe 8: Taschenrechner

Als erstes wird der Titel «Rechenmaschine» geschrieben. Anschliessend wird der Benutzer 2x nach einer Zahl gefragt. Sobald diese eingegeben wurden, sieht man die Zahlen und das Resultat einer Multiplikation beider.

Im Beispiel rechts wurden die zwei Zahlen 1234 und 7654 eingegeben. 

Comments