Level 01: Typen zum Rechnen

Level 1: Typen, mit denen du rechnen kannst #

Dieses Kapitel findest du auch etwas interaktiver unter https://programmieren.tigyog.app/level-1-1.

42 ist das beste Programmiereralter. Warum? »42« ist die Antwort auf die Frage nach dem Leben, dem Universum, und allem… wenigstens, wenn wir Douglas Adams’ Per Anhalter durch die Galaxis vertrauen. Und viele Programmiererinnen und Programmierer haben einen Narren an diesem Buch gefressen…

Wäre es also nicht gut, zu wissen, wie lange es noch dauert, bis du 42 Jahre alt bist?

Als ich diesen Text schrieb, war ich 42

Das Programm #

Das Programm, das du gerade geschrieben hast, eignet sich wunderbar, in diese Richtung erweitert zu werden – immerhin wird neben dem Namen auch das Alter abgefragt, und damit sollte sich die Zeit bis zum 42. Geburtstag doch gut ausrechnen lassen!

Versuchen wir es also einmal hiermit:

# Hier wird begrüßt
name = input('Wie heißt Du? ')
print('Hallo', name)

# Jetzt fragen wir nach dem Alter und rechnen die Wartezeit aus
alter = input('Wie alt bist du? ')
zeit_bis_42 = 42 - alter

# Schließlich geben wir einen informativen Satz aus
print(name + ' muss noch ' + zeit_bis_42 + ' Jahre warten.')

Kommentare können Code lesbarer machen

Hinweis zur Einordnung

Sobald deine Programme länger und komplizierter werden, wirst du eine Erfahrung machen, die ausnahmslos alle Programmiererinnen und Programmierer machen: du wirst deinen eigenen Code vergessen!

Nach einiger Zeit wird es schwierig sein, den eigenen Code zu verstehen, und du wirst dich neu hineindenken müssen.

Dabei können Code-Kommentare helfen – diese werden vom Python-Interpreter nicht ausgeführt und sind nur für Menschen, die den Code lesen bestimmt. In Python starten sie mit dem Zeichen #, so wie oben im Codebeispiel zu sehen.

Doch wenn du dieses Programm laufen lässt, wird folgendes ausgegeben; dabei sollte doch alles klar sein, oder?

Wie heißt Du? Jan
Hallo Jan
Wie alt bist du? 42
Traceback (most recent call last):
  File "/home/jan/typenzumrechnen.py", line 7, in <module>
    zeit_bis_42 = 42 - alter
TypeError: unsupported operand type(s) for -: 'int' and 'str'

Was ist hier los? #

Offensichtlich funktioniert irgendetwas nicht. Zum Glück kann uns die Fehlermeldung weiterhelfen! Wenn du genau hinsiehst, ist von »line 7« die Rede; das ist die siebte Zeile. Die ist sogar angegeben: in zeit_bis_42 = 42 - alter hat irgendetwas nicht geklappt.

Neben dem Ort erhalten wir außerdem noch Informationen über die Art des Fehlers, auch wenn dir die jetzt vielleicht noch nicht viel helfen. In der letzten Zeile steht, ein »TypeError« sei passiert, und das irgendetwas mit dem Minuszeichen nicht stimme. Kannst du das soweit erkennen?

Um genau zu verstehen, was hier nicht klappt, wechseln wir in den REPL und sehen uns genau an, was es hier mit der Zahl 42 und unserer Variable alter auf sich hat. Wenn du das Programm gerade hast laufen lassen, lässt sich in Thonnys REPL noch die Variable alter ausgeben:

>>> alter
'42'

Je nachdem, welches Alter du angegeben hast, steht hier eine andere Zahl, doch die Ausgabe sollte ähnlich aussehen. Gib jetzt nur die Zahl 42 ein, und vergleiche die Ausgabe:

>>> 42
42

Fällt dir der Unterschied auf? Einmal sehen wir die Zahl mit, und einmal ohne Anführungszeichen! Das liegt daran, dass wir es mit verschiedenen Typen von Werten zu tun haben! Was bedeutet das?

Eingaben, die wir auf der Konsole machen, werden zunächst immer als Zeichenkette eingelesen. Wenn wir einer Funktion eine Zeichenkette übergeben, müssen wir sie immer in Anführungszeichen schreiben – das weißt du schon. (Denk’ z.B. zurück an die print()-Funktion.) Der Inhalt der Variable alter wird ebenfalls in Anführungszeichen angezeigt – das deutet darauf hin, dass es sich um eine solche Zeichenkette handelt. Wir können das auch im REPL überprüfen, und zwar so:

>>> type(alter)
<class 'str'>

Was Klassen sind, wirst du später lernen. 'str' steht allerdings für String, und dieses Wort lässt sich neben »Schnur« oder »Saite« auch als »Zeichenkette« übersetzen. String ist hier der so genannte Datentyp.

Jetzt fehlt noch die Zahl 42. Auch sie können wir uns genau ansehen:

>>> type(42)
<class 'int'>

'int' steht für Integer, und das lässt sich mit Ganzzahl übersetzen.

Offensichtlich unterscheidet Python zwischen Zeichenketten (Strings) und Ganzzahlen (Integern), und weigert sich, beide voneinander abzuziehen. Warum das so ist, wird vielleicht anschaulich, wenn wir versuchen, die gleiche Fehlermeldung noch einmal zu provozieren:

>>> 42 - 'zweiundvierzig'
Traceback (most recent call last):
  File "<pyshell>", line 1, in <module>
TypeError: unsupported operand type(s) for -: 'int' and 'str'

Solange die Eingabe, die von der Konsole gelesen wurde, nicht als Zahl behandelt wird, lässt sich auch nicht mit ihr rechnen. Sobald nur Zahlen im Spiel sind, benimmt sich Python hingegen wie ein ganz normaler Taschenrechner:

>>> 42 - 11
31

Was ist zu tun? #

Zum Glück lässt sich Abhilfe schaffen: wir können eine Zeichenkette, die Zahlen enthält, in eine Ganzzahl umwandeln, und zwar mit der eingebauten Funktion int():

>>> int('42')
42

Das geht nur dann schief, wenn die Zeichenkette etwas anderes als Zahlen enthält:

>>> int('zwei')
Traceback (most recent call last):
  File "<pyshell>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'zwei'

Wenn du nun also das Programm an der entscheidenden Stelle erweiterst, können wir ausrechnen lassen, wie lange du noch bis zum 42. Lebensjahr warten musst:

# Hier wird begrüßt
name = input('Wie heißt Du? ')
print('Hallo', name)

# Jetzt fragen wir nach dem Alter und rechnen die Wartezeit aus
alter = input('Wie alt bist du? ')
alter_als_zahl = int(alter)
zeit_bis_42 = 42 - alter_als_zahl

# Schließlich geben wir einen informativen Satz aus
print(name + ' muss noch ' + zeit_bis_42 + ' Jahre warten.')

Doch halt, was ist das? Schon wieder ein Fehler!

Wie heißt Du? Jan
Hallo Jan
Wie alt bist du? 42
Traceback (most recent call last):
  File "…/typenzumrechnen.py", line 11, in <module>
    print(name + ' muss noch ' + zeit_bis_42 + ' Jahre warten.')
TypeError: can only concatenate str (not "int") to str

Zum Glück kennst du dich inzwischen mit Fehlermeldungen aus! Jetzt ist Zeile 11 betroffen, und den Fehler verstehen wir auch schon… die letzten Englisch-Kenntnisse zusammengekratzt, und wir übersetzen: »can only concatenate str (not “int”) to str« heißt so viel wie »Ich kann nur zusammenhängen Zeichenkette (nicht Integer) mit Zeichenkette«. Noch Fragen?

Und auch für die Umwandlung von Zahlen in Zeichenketten gibt es eine eingebaute Funktion, und die heißt – wer hätte das gedacht? – str(). Wir testen…

>>> str(42)
'42'

…und fügen an der richtigen Stelle noch ein str(zeit_bis_42) ein. Übrigens kann der Zwischenschritt von vorhin, bei dem wir eine eigene Variable für die Umwandlung zur Zahl eingeführt haben, auch weggelassen werden. Kürzer sieht das Programm also nun so aus:

# Hier wird begrüßt
name = input('Wie heißt Du? ')
print('Hallo', name)

# Jetzt fragen wir nach dem Alter und rechnen die Wartezeit aus
alter = input('Wie alt bist du? ')
zeit_bis_42 = 42 - int(alter)

# Schließlich geben wir einen informativen Satz aus
print(name + ' muss noch ' + str(zeit_bis_42) + ' Jahre warten.')

Lass nun das Programm laufen, und du solltest eine Ausgabe erhalten, die so ähnlich aussieht wir hier:

Wie heißt Du? Jan
Hallo Jan
Wie alt bist du? 42
Jan muss noch 0 Jahre warten.

Wir nennen »Fehler« lieber »Lerner«!

Hinweis zur Einordnung

Ein großer Teil des Programmierens ist die Fehlersuche, und die kann manchmal sehr frustrierend sein. Fehlermeldungen helfen uns dabei, Programmfehler zu finden. Diesen Vorgang nennt man auch Debuggen.

Debuggen gehört zum Programmieren wie ein Löffel zum Suppe-Essen, ein Lenker zum Fahrrad oder ein Handtuch zum Badeurlaub – es ist einfach unverzichtbar. Dabei muss auch Debuggen gelernt werden.

Als erstes solltest du versuchen zu verstehen, was genau dein Programm macht, und warum das vielleicht nicht das ist, was du vom Programm möchtest. Fehlermeldungen können dabei sehr hilfreich sein! Mach dir immer klar: eine Fehlermeldung ist nichts schlimmes, und wenn du den Fehler irgendwann entdeckt haben wirst, wird dir das Problem nicht mehr so groß vorkommen.

Die Entwicklerin Julia Evans hat das Thema in ihrem Blog mehr als einmal aufgenommen. Wenn Du keine Angst vor Englisch hast, sieh’ Dir ihre Tricks doch einmal an!

Übung #

David kommentiert: Wahnsinn! 32 Tore!

Dein Kumpel David jobbt als Sportreporter in der Kreisliga, und er hat ein Programm geschrieben, das ihm helfen soll, seine Sache gut zu machen. Leider produziert es ganz unsinnige Ergebnisse, und am letzten Spieltag hat David sich ganz furchtbar blamiert… Kannst du ihm helfen?

tore_heim = input('Wie viele Tore erzielte die Heimmannschaft? ')
tore_ausw = input('Wie viele Tore erzielte die Auswärtsmannschaft? ')

tore_insgesamt = tore_heim + tore_ausw

print('Es wurden insgesamt ' + tore_insgesamt + ' Tore erzielt.')

Siehst du schon jetzt, was hier falsch läuft? Falls nicht, lass das Programm laufen und mache einige Testeingaben! Finde den Fehler und behebe ihn!

Lösungsvorschlag
tore_heim = input('Wie viele Tore erzielte die Heimmannschaft? ')
tore_ausw = input('Wie viele Tore erzielte die Auswärtsmannschaft? ')

# Ohne die Typumwandlung würden wir die Zeichenketten aneinanderhängen.
tore_insgesamt = int(tore_heim) + int(tore_ausw)

# Um die Tore auszugeben, musst du sie in eine Zeichenkette zurückverwandeln.
print('Es wurden insgesamt ' + str(tore_insgesamt) + ' Tore erzielt.')

Fehlertypen

Hinweis zur Einordnung

Auf bei Fehlern lassen sich verschiedene Typen unterscheiden. Wenn ein Programm mit Fehlern abbricht, können Syntaxfehler oder logische Fehler die Ursache sein. Syntax ist so etwas ähnliches wie Grammatik, und Logik ist Logik. Logischerweise lässt sich z.B. keine Zahl von einem Wort (einer Zeichenkette) abziehen… Auf der anderen Seite kann ein Programm laufen und unsinnige Ergebnisse produzieren: dann sprechen wir von einem semantischen Fehler. (Semantik beschäftigt sich mit der Bedeutung von Dingen.)

Zurück Weiter