Zum Inhalt springen

cat posts/python-lernen-02-werte-und-variablen.md

Python lernen (Teil 2): Werte und Variablen

Datentypen, Variablen, Rechnen und f-Strings – damit unser Abenteurer Lebenspunkte und Gold bekommt und der Dungeon eine ordentliche Statuszeile.

Python lernen (Teil 2): Werte und Variablen

In Teil 1 haben wir Python installiert, die REPL ausprobiert und unser erstes kleines Programm geschrieben. Der Dungeon konnte den Namen des Abenteurers abfragen und ihn anschließend begrüßen.

Heute bekommt unser Abenteurer einen richtigen State: Lebenspunkte, Gold und weitere Werte, die beschreiben, wie es gerade um ihn steht. Diese Werte müssen wir speichern, ausgeben und im Laufe des Spiels verändern können.

Dafür brauchen wir zwei Grundlagen: Datentypen und Variablen.

Was ist ein State?

Der Begriff State bezeichnet in der Programmierung den aktuellen Zustand eines Programms oder eines Teils davon.

Zum State unseres Abenteurers gehören beispielsweise:

  • sein Name
  • seine Lebenspunkte
  • seine maximalen Lebenspunkte
  • die Anzahl seiner Goldmünzen

State ist dabei kein eigener Datentyp in Python. Der Begriff fasst lediglich die Werte zusammen, die zu einem bestimmten Zeitpunkt beschreiben, was gerade im Programm los ist.

Zu Beginn könnte der State unseres Abenteurers so aussehen:

name = "Karl"
hp = 100
max_hp = 100
gold = 50

Wird der Abenteurer später verletzt oder findet Gold, verändert sich sein State.

Werte haben Datentypen

Jeder Wert in Python hat einen bestimmten Typ. Für den Anfang sind vor allem diese vier wichtig:

"Karl"  # str: ein String
100     # int: eine Ganzzahl
3.5     # float: eine Gleitkommazahl
True    # bool: ein Wahrheitswert

Ein str ist ein String, also Text. Strings stehen in Anführungszeichen:

"Karl"
"Du betrittst den Dungeon."
"100"

Ein int ist eine Ganzzahl (Integer):

100
0
-25

Ein float ist eine Gleitkommazahl (Float). Im Python-Code wird dabei ein Punkt als Dezimaltrennzeichen verwendet:

3.5
0.25
-12.75

Ein bool ist ein Wahrheitswert (Boolean) und kennt zwei Werte:

True
False

Booleans brauchen wir im nächsten Teil, wenn unser Dungeon Entscheidungen treffen soll.

Mit type(...) kannst Du in der REPL prüfen, welchen Datentyp ein Wert hat:

>>> type(100)
<class 'int'>
>>> type("100")
<class 'str'>
>>> type(3.5)
<class 'float'>
>>> type(True)
<class 'bool'>

Achte besonders auf den Unterschied zwischen 100 und "100":

100    # eine Zahl
"100"  # ein String

Beides sieht ähnlich aus, ist für Python aber etwas völlig anderes. Mit der Zahl 100 kannst Du rechnen. Der String "100" ist dagegen Text, der lediglich aus drei Ziffern besteht.

Dieser Unterschied ist eine häufige Ursache für Fehler, wenn Eingaben ins Spiel kommen.

Variablen: Werte mit Namen

Eine Variable ist vereinfacht gesagt ein Name, der auf einen Wert verweist. Über diesen Namen kannst Du später wieder auf den Wert zugreifen:

name = "Karl"
hp = 100
gold = 0

Das Gleichheitszeichen (=) bedeutet in Python keine mathematische Gleichung, sondern eine Zuweisung.

Die Anweisung

hp = 100

bedeutet sinngemäß:

Weise dem Namen hp den Wert 100 zu.

Der Name kann später an einen anderen Wert gebunden werden:

hp = 100
hp = hp - 25

Python wertet dabei zuerst die rechte Seite aus. hp steht zu diesem Zeitpunkt für 100, also ergibt

hp - 25

den Wert 75. Anschließend wird hp dieser neue Wert zugewiesen.

Nach den beiden Anweisungen hat hp also den Wert 75.

Variablennamen

Variablennamen sollten möglichst deutlich beschreiben, wofür sie stehen:

name = "Karl"
gold = 50
max_hp = 100
verbleibende_hp = 75

Ein Name wie x verrät wenig über seinen Inhalt. Bei verbleibende_hp ist dagegen sofort erkennbar, was gemeint ist.

Für Variablennamen gelten einige Regeln:

  • Sie dürfen nicht mit einer Zahl beginnen.
  • Sie dürfen keine Leerzeichen oder Bindestriche enthalten.
  • Zahlen sind erlaubt, solange der Name nicht damit beginnt.
  • Groß- und Kleinschreibung werden unterschieden.
  • Reservierte Python-Keywords wie class, if oder for dürfen nicht als Variablennamen verwendet werden.

Mehrere Wörter werden üblicherweise mit Unterstrichen getrennt. Diese Schreibweise nennt sich snake_case:

max_hp = 100
gefundenes_gold = 10
verbleibende_hp = 75

Diese Namen funktionieren dagegen nicht:

2gold
mein gold
max-hp
class

Das Minuszeichen in max-hp würde Python beispielsweise als Subtraktionsoperator interpretieren.

Außerdem sind gold, Gold und GOLD für Python drei unterschiedliche Namen.

Mit Zahlen rechnen

Python kennt die üblichen Rechenoperatoren. Du kannst sie direkt in der REPL ausprobieren:

>>> 10 + 3
13
>>> 10 - 3
7
>>> 10 * 3
30
>>> 10 / 3
3.3333333333333335
>>> 10 // 3
3
>>> 10 % 3
1
>>> 2 ** 10
1024

Die Operatoren haben folgende Bedeutung:

Operator Bedeutung Beispiel
+ Addition 10 + 3 ergibt 13
- Subtraktion 10 - 3 ergibt 7
* Multiplikation 10 * 3 ergibt 30
/ Division 10 / 3 ergibt ungefähr 3.33
// Ganzzahldivision 10 // 3 ergibt 3
% Rest einer Division 10 % 3 ergibt 1
** Potenzierung 2 ** 10 ergibt 1024

Eine normale Division mit / liefert bei diesen Zahlen einen float. Das gilt auch dann, wenn die Rechnung ohne Rest aufgeht:

>>> 9 / 3
3.0

Die Ganzzahldivision // liefert den abgerundeten Quotienten:

>>> 10 // 3
3

Mit positiven Zahlen wirkt das zunächst so, als würde Python einfach die Nachkommastellen abschneiden. Bei negativen Ergebnissen sieht man den Unterschied:

>>> -10 // 3
-4

Das mathematische Ergebnis liegt bei ungefähr -3.33. Abgerundet wird daraus -4, nicht -3.

Der Modulo-Operator % liefert den Rest einer Division:

>>> 10 % 3
1

Die Zahl 10 lässt sich dreimal vollständig durch 3 teilen. Dabei bleibt ein Rest von 1.

f-Strings: Werte in Text einbauen

In Teil 1 haben wir Strings und Variablen mit dem Pluszeichen verbunden:

print("Willkommen, " + name + "!")

Lesbarer geht es mit einem f-String. Dabei steht direkt vor dem öffnenden Anführungszeichen ein f. Werte und Ausdrücke lassen sich anschließend in geschweiften Klammern in den String einsetzen:

name = "Karl"
hp = 75

print(f"{name} hat noch {hp} Lebenspunkte.")

Die Ausgabe lautet:

Karl hat noch 75 Lebenspunkte.

Du kannst mehrere Werte in einem f-String verwenden:

hp = 75
max_hp = 100
gold = 50

print(f"HP: {hp}/{max_hp} | Gold: {gold}")

Die Ausgabe lautet:

HP: 75/100 | Gold: 50

Innerhalb der geschweiften Klammern können auch Berechnungen stehen:

hp = 75

print(f"Die Hälfte Deiner Lebenspunkte beträgt {hp / 2}.")

Die Ausgabe lautet:

Die Hälfte Deiner Lebenspunkte beträgt 37.5.

f-Strings sind eine sehr praktische Möglichkeit, Text und andere Werte zu einer Ausgabe zusammenzusetzen. Wir werden sie ab jetzt regelmäßig verwenden.

Input in eine Zahl umwandeln

Die Funktion input(...) liefert immer einen String zurück – selbst dann, wenn der Spieler eine Zahl eingibt:

gold = input("Wie viele Goldmünzen bringst Du mit? ")

Gibt der Spieler 50 ein, enthält gold anschließend nicht die Zahl 50, sondern den String "50".

Mit type(...) kannst Du das in der REPL überprüfen:

>>> gold = input("Wie viele Goldmünzen bringst Du mit? ")
Wie viele Goldmünzen bringst Du mit? 50
>>> type(gold)
<class 'str'>

Bevor Du damit rechnen kannst, musst Du den String mit int(...) in einen Integer umwandeln:

gold = input("Wie viele Goldmünzen bringst Du mit? ")
gold = int(gold)

Danach enthält gold den Wert 50 vom Typ int.

Beide Schritte lassen sich auch miteinander verbinden:

gold = int(input("Wie viele Goldmünzen bringst Du mit? "))

Python arbeitet hier von innen nach außen:

  1. input(...) liest die Eingabe ein.
  2. int(...) wandelt den String in einen Integer um.
  3. Das Ergebnis wird gold zugewiesen.

Ohne diese Umwandlung können überraschende Ergebnisse entstehen:

>>> "50" * 2
'5050'

Python wiederholt hier den String "50" zweimal. Es findet keine mathematische Multiplikation statt.

Andere Kombinationen führen direkt zu einem Fehler:

>>> "50" + 10
Traceback (most recent call last):
  ...
TypeError: can only concatenate str (not "int") to str

Gibt der Spieler etwas ein, das sich nicht als Integer interpretieren lässt, entsteht stattdessen ein ValueError:

>>> int("fünfzig")
Traceback (most recent call last):
  ...
ValueError: invalid literal for int() with base 10: 'fünfzig'

Wie wir solche Fehler abfangen und den Spieler erneut nach einer gültigen Eingabe fragen, behandeln wir später in dieser Serie.

Der Dungeon, Schritt 2

Unser Abenteurer bekommt nun seinen ersten richtigen State. Öffne die Datei dungeon.py aus Teil 1 und ersetze ihren Inhalt durch folgenden Code:

# Dungeon – Teil 2: Player State
print("Du stehst vor dem rostigen Tor eines vergessenen Verlieses.")
print("Ein kalter Luftzug weht Dir entgegen.")

name = input("Wie heißt Du, Abenteurer? ")
gold = int(input("Wie viele Goldmünzen bringst Du mit? "))

hp = 100
max_hp = 100

print()
print(f"Willkommen, {name}!")
print(f"HP: {hp}/{max_hp} | Gold: {gold}")

# Eine Falle verletzt den Abenteurer
schaden = 25
hp = hp - schaden

print()
print("Kaum drei Schritte – da schnappt eine Falle zu!")
print(f"Du verlierst {schaden} Lebenspunkte.")
print(f"HP: {hp}/{max_hp} | Gold: {gold}")

# Der Abenteurer findet Gold
gefundenes_gold = 10
gold = gold + gefundenes_gold

print()
print(f"Zwischen den Steinen findest Du {gefundenes_gold} Goldmünzen.")
print(f"HP: {hp}/{max_hp} | Gold: {gold}")

Die Abkürzung hp steht für Hit Points, also Lebenspunkte. In max_hp speichern wir die maximale Anzahl. Der Abenteurer startet damit bei 100 von maximal 100 Lebenspunkten.

Die Werte hinter den Namen

name
hp
max_hp
gold

bilden gemeinsam den aktuellen Player State.

Das leere print() erzeugt eine Leerzeile und trennt die einzelnen Abschnitte der Ausgabe voneinander.

Nach der Falle ziehen wir den Schaden von den Lebenspunkten ab:

hp = hp - schaden

Aus 100 Lebenspunkten werden 75.

Beim Goldfund addieren wir den gefundenen Betrag zum bisherigen Gold:

gold = gold + gefundenes_gold

Hatte der Spieler vorher 50 Goldmünzen, besitzt er anschließend 60.

Führe das Programm aus:

python dungeon.py

Mit den Eingaben Karl und 50 sieht die Ausgabe beispielsweise so aus:

Du stehst vor dem rostigen Tor eines vergessenen Verlieses.
Ein kalter Luftzug weht Dir entgegen.
Wie heißt Du, Abenteurer? Karl
Wie viele Goldmünzen bringst Du mit? 50

Willkommen, Karl!
HP: 100/100 | Gold: 50

Kaum drei Schritte – da schnappt eine Falle zu!
Du verlierst 25 Lebenspunkte.
HP: 75/100 | Gold: 50

Zwischen den Steinen findest Du 10 Goldmünzen.
HP: 75/100 | Gold: 60

Der Dungeon kann jetzt Werte speichern, verändern und als Teil seines States ausgeben.

Noch läuft das Programm allerdings jedes Mal gleich von oben nach unten durch. Unabhängig von der Eingabe schnappt dieselbe Falle zu und anschließend liegt immer dasselbe Gold zwischen den Steinen.

Im nächsten Teil bringen wir dem Dungeon bei, Entscheidungen zu treffen und auf die Eingaben des Spielers zu reagieren.

Stolperfallen

  • Mit einem String wie mit einer Zahl rechnen. input(...) liefert immer einen String. Wandle eingegebene Integer deshalb mit int(...) um, wenn Du damit rechnen möchtest.

  • Ungültigen Input eingeben. int("drei") und int("3.5") führen zu einem ValueError. Für eine Eingabe wie "3.5" benötigst Du stattdessen float(...).

  • Ein Komma als Dezimaltrennzeichen verwenden. Python erwartet bei Zahlenliteralen und bei einer direkten Umwandlung mit float(...) einen Punkt: 3.5 statt 3,5.

  • Das f vor einem f-String vergessen. print("{name}") gibt wörtlich {name} aus. Erst print(f"{name}") setzt den Wert der Variablen ein.

  • Groß- und Kleinschreibung verwechseln. Für Python sind gold, Gold und GOLD drei unterschiedliche Namen.

  • Einen String mit + an eine Zahl hängen. "Gold: " + gold funktioniert nicht, wenn gold ein int ist. Mit einem f-String geht es problemlos: f"Gold: {gold}".

Übungen

1. Das ungefähre Geburtsjahr berechnen

Frage zusätzlich nach dem Alter des Abenteurers und berechne, in welchem Jahr er ungefähr geboren wurde. Verwende für diese Übung 2026 als aktuelles Jahr.

Lösung
aktuelles_jahr = 2026
alter = int(input("Wie alt bist Du? "))

geburtsjahr = aktuelles_jahr - alter

print(f"Du wurdest ungefähr im Jahr {geburtsjahr} geboren.")
Das Ergebnis ist nur ungefähr, weil wir nicht prüfen, ob der Geburtstag in diesem Jahr bereits stattgefunden hat.

2. Einen Heiltrank verwenden

Der Abenteurer besitzt noch 75 Lebenspunkte und findet einen Heiltrank, der 30 Lebenspunkte wiederherstellt. Seine Lebenspunkte dürfen dabei nicht über max_hp steigen.

Verwende dafür die Funktion min(...):

min(a, b)

Die Funktion gibt den kleineren der beiden Werte zurück.

Lösung
hp = 75
max_hp = 100
heilung = 30

hp = min(hp + heilung, max_hp)

print(f"HP: {hp}/{max_hp}")
Ohne Begrenzung ergäbe `75 + 30` insgesamt `105` Lebenspunkte. Da `min(105, 100)` den kleineren Wert zurückgibt, wird `hp` auf `100` begrenzt.

3. Den Player State erweitern

Füge dem Abenteurer zusätzlich die Variable level hinzu. Er beginnt auf Level 1. Gib anschließend den vollständigen State in einer Zeile aus:

Karl | Level: 1 | HP: 100/100 | Gold: 50
Lösung
name = "Karl"
level = 1
hp = 100
max_hp = 100
gold = 50

print(f"{name} | Level: {level} | HP: {hp}/{max_hp} | Gold: {gold}")

Vertiefung

f-Strings können deutlich mehr als Variablen und Berechnungen einzusetzen. Mit ihnen lassen sich unter anderem Zahlen ausrichten, Nachkommastellen begrenzen und Werte auf unterschiedliche Arten formatieren:

f-Strings bis zum Anschlag

Im nächsten Teil

Der Dungeon kann Werte speichern und verändern, aber noch keine Entscheidungen treffen. In Teil 3 kommen Entscheidungen und Schleifen hinzu.

Mit if und else reagiert das Spiel auf unterschiedliche Situationen. Anschließend bauen wir einen Game-Loop, durch den der Dungeon wiederholt auf die Befehle des Spielers hören kann.

0 Kommentare

Noch keine Kommentare. Sei der/die Erste!