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.

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 geben wir unserem Abenteurer einen richtigen State: Lebenspunkte, Gold und weitere Werte, die seinen aktuellen Zustand im Spiel beschreiben. Diese Werte müssen wir speichern, ausgeben und während des Spiels verändern können.

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

Was ist ein State?

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

In unserem Dungeon gehören zum State des Abenteurers beispielsweise:

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

Der State ist dabei kein eigener Datentyp in Python. Es ist ein Sammelbegriff für die Werte, die zu einem bestimmten Zeitpunkt beschreiben, was gerade im Programm los ist.

Zu Beginn könnte der State unseres Abenteurers beispielsweise 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 besitzt einen bestimmten Typ. Für den Anfang sind vor allem diese vier Datentypen wichtig:

"Karl"  # str: ein String
100     # int: eine Ganzzahl
3.5     # float: eine Zahl mit Nachkommastellen
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:

100
0
-25

Ein float ist eine Zahl mit Nachkommastellen. Python verwendet dafür einen Punkt statt eines Kommas:

3.5
0.25
-12.75

Ein bool kann nur einen von zwei Werten besitzen:

True
False

Booleans benötigen wir im nächsten Teil, wenn unser Dungeon Entscheidungen treffen soll.

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

>>> 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

Beide sehen ähnlich aus, sind für Python aber grundverschieden. Mit der Zahl 100 kannst Du rechnen. Der String "100" ist dagegen Text, der lediglich aus drei Ziffern besteht.

Diese Unterscheidung ist die Ursache vieler typischer Anfängerfehler.

Variablen: Werte mit Namen

Eine Variable ist ein Name, unter dem Du einen Wert speicherst. Über diesen Namen kannst Du später wieder auf den Wert zugreifen:

name = "Karl"
hp = 100
gold = 0

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

Die Anweisung

hp = 100

bedeutet:

Speichere den Wert 100 unter dem Namen hp.

Der gespeicherte Wert kann später verändert werden:

hp = 100
hp = hp - 25

Python wertet dabei zuerst die rechte Seite aus. Da hp zunächst den Wert 100 enthält, ergibt

hp - 25

den Wert 75. Dieses Ergebnis wird anschließend wieder unter dem Namen hp gespeichert. Der bisherige Wert wird dadurch ersetzt.

Nach den beiden Anweisungen enthält hp also den Wert 75.

Variablennamen

Variablennamen sollten möglichst deutlich beschreiben, welchen Wert sie enthalten:

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

Ein Name wie x sagt wenig über seinen Inhalt aus. Bei verbleibende_hp ist dagegen sofort erkennbar, welcher Wert gemeint ist.

Für Variablennamen gelten einige Regeln:

  • Sie dürfen nicht mit einer Zahl beginnen.
  • Sie dürfen keine Leerzeichen enthalten.
  • Sie dürfen Buchstaben, Zahlen und Unterstriche enthalten.
  • Groß- und Kleinschreibung werden unterschieden.
  • Mehrere Wörter werden üblicherweise mit Unterstrichen getrennt.

Diese Schreibweise wird snake_case genannt:

max_hp = 100
gefundenes_gold = 10
verbleibende_hp = 75

Diese Namen sind dagegen ungültig:

2gold
mein gold
max-hp

Das Minuszeichen in max-hp würde Python als Subtraktion verstehen.

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

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 immer einen float. Das gilt auch dann, wenn die Rechnung ohne Rest aufgeht:

>>> 9 / 3
3.0

Die Ganzzahldivision mit // rundet das Ergebnis nach unten:

>>> 10 // 3
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. Variablen können anschließend in geschweiften Klammern in den String eingesetzt werden:

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 dürfen 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 der übliche Weg, Strings und andere Werte zu einer gemeinsamen 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 die Variable 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 eine Ganzzahl umwandeln:

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

Nach der Umwandlung 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 führt die Funktionen dabei von innen nach außen aus:

  1. input(...) fragt den Input ab.
  2. int(...) wandelt den eingegebenen String in eine Ganzzahl um.
  3. Das Ergebnis wird unter dem Namen gold gespeichert.

Ohne die Umwandlung können unerwartete Ergebnisse entstehen:

>>> "50" * 2
'5050'

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

Andere Rechnungen führen zu einem TypeError:

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

Gibt der Spieler etwas ein, das sich nicht in eine Ganzzahl umwandeln 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 ungültigen Input abfangen und das Programm nach einem Fehler weiterlaufen lassen, behandeln wir später in dieser Serie.

Der Dungeon, Schritt 2

Unser Abenteurer erhält 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 an Lebenspunkten. Der Abenteurer beginnt daher mit 100 von maximal 100 Lebenspunkten.

Die Variablen

name
hp
max_hp
gold

bilden gemeinsam den aktuellen Player State.

Das leere print() erzeugt eine Leerzeile. Dadurch werden die einzelnen Abschnitte des Outputs besser voneinander getrennt.

Nach der Falle wird der Schaden von den Lebenspunkten abgezogen:

hp = hp - schaden

Aus 100 Lebenspunkten werden dadurch 75.

Beim Goldfund wird der neue Wert dagegen zum bisherigen Gold addiert:

gold = gold + gefundenes_gold

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

Führe das Programm aus:

python dungeon.py

Mit den Inputs Karl und 50 sieht der Output 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 des aktuellen States ausgeben.

Noch läuft das Programm allerdings immer gleich von oben nach unten durch. Unabhängig vom Input schnappt jedes Mal dieselbe Falle zu und anschließend wird immer dasselbe Gold gefunden.

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

Stolperfallen

  • Mit einem String wie mit einer Zahl rechnen. input(...) liefert immer einen String. Wandle eingegebene Ganzzahlen deshalb mit int(...) um.

  • Ungültigen Input eingeben. int("drei") und int("3.5") führen zu einem ValueError. Für Zahlen mit Nachkommastellen benötigst Du float(...).

  • Ein Komma als Dezimaltrennzeichen verwenden. Python erwartet bei float-Werten 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 Variablennamen.

  • 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 nicht nur Variablen und Berechnungen einsetzen. Mit ihnen lassen sich unter anderem Zahlen ausrichten, Nachkommastellen begrenzen und Strings 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 Eingaben. 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!