cat posts/en/python-lernen-02-werte-und-variablen.md
Learning Python (Part 2): Values and variables
Data types, variables, arithmetic, and f-strings: our adventurer gets hit points and gold, and the dungeon gets a proper status line.
In part 1, we installed Python, tried out the REPL, and wrote our first small program. The dungeon could ask for the adventurer's name and then greet them.
Today our adventurer gets a real state: hit points, gold, and other values that describe how things currently stand. We need to be able to store these values, print them, and change them over the course of the game.
For that, we need two basics: data types and variables.
What is state?
In programming, the term state refers to the current condition of a program or part of it.
Our adventurer's state includes, for example:
- their name
- their hit points
- their maximum hit points
- the number of their gold coins
State isn't a data type of its own in Python. The term only groups together the values that describe, at a given moment, what's currently going on in the program.
At the start, our adventurer's state could look like this:
name = "Karl"
hp = 100
max_hp = 100
gold = 50
If the adventurer gets hurt or finds gold later on, their state changes.
Values have data types
Every value in Python has a specific type. To start with, these four matter most:
"Karl" # str: a string
100 # int: an integer
3.5 # float: a floating-point number
True # bool: a truth value
A str is a string, meaning text. Strings go in quotation marks:
"Karl"
"You enter the dungeon."
"100"
An int is a whole number, an integer:
100
0
-25
A float is a floating-point number. Python code uses a period as the decimal
separator:
3.5
0.25
-12.75
A bool is a truth value, a Boolean, and it has two values:
True
False
We'll need Booleans in the next part, when our dungeon has to make decisions.
You can use type(...) in the REPL to check which data type a value has:
>>> type(100)
<class 'int'>
>>> type("100")
<class 'str'>
>>> type(3.5)
<class 'float'>
>>> type(True)
<class 'bool'>
Pay particular attention to the difference between 100 and "100":
100 # a number
"100" # a string
They look similar, but to Python they're completely different things. You can
calculate with the number 100. The string "100", on the other hand, is text
that happens to consist of three digits.
This difference is a common source of bugs once input comes into play.
Variables: values with names
Put simply, a variable is a name that refers to a value. You can use that name to get back to the value later:
name = "Karl"
hp = 100
gold = 0
In Python, the equals sign (=) doesn't mean a mathematical equation. It's an
assignment.
The statement
hp = 100
means, roughly:
Assign the value
100to the namehp.
The name can later be bound to a different value:
hp = 100
hp = hp - 25
Python evaluates the right-hand side first. At this point, hp stands for
100, so
hp - 25
results in 75. Then hp is assigned this new value.
So after both statements, hp has the value 75.
Variable names
Variable names should describe as clearly as possible what they stand for:
name = "Karl"
gold = 50
max_hp = 100
verbleibende_hp = 75
A name like x tells you little about its content. With verbleibende_hp
(German for remaining HP), on the other hand, it's immediately clear what's
meant.
A few rules apply to variable names:
- They can't start with a digit.
- They can't contain spaces or hyphens.
- Digits are allowed, as long as the name doesn't start with one.
- Names are case-sensitive.
- Reserved Python keywords such as
class,if, orforcan't be used as variable names.
Multiple words are usually separated with underscores. This style is called snake_case:
max_hp = 100
gefundenes_gold = 10
verbleibende_hp = 75
These names, however, don't work:
2gold
my gold
max-hp
class
Python would interpret the minus sign in max-hp, for example, as the
subtraction operator.
Also, gold, Gold, and GOLD are three different names to Python.
Calculating with numbers
Python has the usual arithmetic operators. You can try them out directly in the REPL:
>>> 10 + 3
13
>>> 10 - 3
7
>>> 10 * 3
30
>>> 10 / 3
3.3333333333333335
>>> 10 // 3
3
>>> 10 % 3
1
>>> 2 ** 10
1024
The operators mean the following:
| Operator | Meaning | Example |
|---|---|---|
+ |
Addition | 10 + 3 gives 13 |
- |
Subtraction | 10 - 3 gives 7 |
* |
Multiplication | 10 * 3 gives 30 |
/ |
Division | 10 / 3 gives about 3.33 |
// |
Floor division | 10 // 3 gives 3 |
% |
Remainder of a division | 10 % 3 gives 1 |
** |
Exponentiation | 2 ** 10 gives 1024 |
With these numbers, a regular division with / returns a float. That's true
even when the division comes out even:
>>> 9 / 3
3.0
Floor division // returns the quotient rounded down:
>>> 10 // 3
3
With positive numbers, this looks at first as if Python just cuts off the decimal places. With negative results, you can see the difference:
>>> -10 // 3
-4
The mathematical result is about -3.33. Rounded down, that becomes -4, not
-3.
The modulo operator % returns the remainder of a division:
>>> 10 % 3
1
3 goes into 10 three whole times. That leaves a remainder of 1.
f-strings: putting values into text
In part 1, we joined strings and variables with the plus sign:
print("Welcome, " + name + "!")
An f-string is more readable. You put an f directly before the opening
quotation mark. Then you can insert values and expressions into the string in
curly braces:
name = "Karl"
hp = 75
print(f"{name} has {hp} hit points left.")
The output is:
Karl has 75 hit points left.
You can use multiple values in one f-string:
hp = 75
max_hp = 100
gold = 50
print(f"HP: {hp}/{max_hp} | Gold: {gold}")
The output is:
HP: 75/100 | Gold: 50
The curly braces can also contain calculations:
hp = 75
print(f"Half of your hit points is {hp / 2}.")
The output is:
Half of your hit points is 37.5.
f-strings are a very handy way to combine text and other values into one piece of output. From now on, we'll use them regularly.
Converting input to a number
The input(...) function always returns a string, even when the player types a
number:
gold = input("How many gold coins are you bringing? ")
If the player types 50, gold then contains the string "50", not the
number 50.
You can check that with type(...) in the REPL:
>>> gold = input("How many gold coins are you bringing? ")
How many gold coins are you bringing? 50
>>> type(gold)
<class 'str'>
Before you can calculate with it, you have to convert the string to an integer
with int(...):
gold = input("How many gold coins are you bringing? ")
gold = int(gold)
After that, gold contains the value 50 of type int.
You can also combine both steps:
gold = int(input("How many gold coins are you bringing? "))
Python works from the inside out here:
input(...)reads the input.int(...)converts the string to an integer.- The result is assigned to
gold.
Without this conversion, you can get surprising results:
>>> "50" * 2
'5050'
Here, Python repeats the string "50" twice. No mathematical multiplication
takes place.
Other combinations lead straight to an error:
>>> "50" + 10
Traceback (most recent call last):
...
TypeError: can only concatenate str (not "int") to str
If the player types something that can't be interpreted as an integer, you get a
ValueError instead:
>>> int("fifty")
Traceback (most recent call last):
...
ValueError: invalid literal for int() with base 10: 'fifty'
We'll cover how to catch errors like this and ask the player again for valid input later in this series.
The dungeon, step 2
Our adventurer now gets their first real state. Open the dungeon.py file from
part 1 and replace its content with the following code:
# Dungeon—Part 2: Player state
print("You stand before the rusty gate of a forgotten dungeon.")
print("A cold draft blows toward you.")
name = input("What's your name, adventurer? ")
gold = int(input("How many gold coins are you bringing? "))
hp = 100
max_hp = 100
print()
print(f"Welcome, {name}!")
print(f"HP: {hp}/{max_hp} | Gold: {gold}")
# A trap injures the adventurer
schaden = 25
hp = hp - schaden
print()
print("Barely three steps in—and a trap snaps shut!")
print(f"You lose {schaden} hit points.")
print(f"HP: {hp}/{max_hp} | Gold: {gold}")
# The adventurer finds gold
gefundenes_gold = 10
gold = gold + gefundenes_gold
print()
print(f"Between the stones, you find {gefundenes_gold} gold coins.")
print(f"HP: {hp}/{max_hp} | Gold: {gold}")
The abbreviation hp stands for hit points. In max_hp, we store the
maximum. So the adventurer starts at 100 out of a maximum of 100 hit points.
The German names schaden and gefundenes_gold mean damage and found gold.
The values behind the names
name
hp
max_hp
gold
together make up the current player state.
The empty print() produces a blank line and separates the individual sections
of the output.
After the trap, we subtract the damage from the hit points:
hp = hp - schaden
100 hit points become 75.
When the adventurer finds gold, we add the amount found to the gold they already have:
gold = gold + gefundenes_gold
If the player had 50 gold coins before, they now have 60.
Run the program:
python dungeon.py
With the inputs Karl and 50, the output looks something like this:
You stand before the rusty gate of a forgotten dungeon.
A cold draft blows toward you.
What's your name, adventurer? Karl
How many gold coins are you bringing? 50
Welcome, Karl!
HP: 100/100 | Gold: 50
Barely three steps in—and a trap snaps shut!
You lose 25 hit points.
HP: 75/100 | Gold: 50
Between the stones, you find 10 gold coins.
HP: 75/100 | Gold: 60
The dungeon can now store values, change them, and print them as part of its state.
So far, though, the program runs the same way from top to bottom every time. Regardless of the input, the same trap snaps shut, and then the same gold always turns up between the stones.
In the next part, we'll teach the dungeon to make decisions and respond to the player's input.
Pitfalls
-
Calculating with a string as if it were a number.
input(...)always returns a string. So if you want to calculate with integers the player types, convert them withint(...). -
Entering invalid input.
int("three")andint("3.5")lead to aValueError. For input like"3.5", you needfloat(...)instead. -
Using a comma as the decimal separator. For number literals and for a direct conversion with
float(...), Python expects a period:3.5, not3,5. -
Forgetting the
fbefore an f-string.print("{name}")prints{name}literally. Onlyprint(f"{name}")inserts the variable's value. -
Mixing up uppercase and lowercase. To Python,
gold,Gold, andGOLDare three different names. -
Appending a number to a string with
+."Gold: " + golddoesn't work ifgoldis anint. With an f-string, it works without any trouble:f"Gold: {gold}".
Exercises
1. Calculate the approximate year of birth
Also ask for the adventurer's age and calculate roughly which year they were
born in. For this exercise, use 2026 as the current year.
Solution
aktuelles_jahr = 2026
alter = int(input("How old are you? "))
geburtsjahr = aktuelles_jahr - alter
print(f"You were born around {geburtsjahr}.")
2. Use a healing potion
The adventurer has 75 hit points left and finds a healing potion that restores
30 hit points. Their hit points can't go above max_hp.
Use the min(...) function for this:
min(a, b)
The function returns the smaller of the two values.
Solution
hp = 75
max_hp = 100
heilung = 30
hp = min(hp + heilung, max_hp)
print(f"HP: {hp}/{max_hp}")
3. Extend the player state
Also give the adventurer a level variable. They start at level 1. Then print
the complete state on one line:
Karl | Level: 1 | HP: 100/100 | Gold: 50
Solution
name = "Karl"
level = 1
hp = 100
max_hp = 100
gold = 50
print(f"{name} | Level: {level} | HP: {hp}/{max_hp} | Gold: {gold}")
Going deeper
f-strings can do a lot more than insert variables and calculations. Among other things, they let you align numbers, limit decimal places, and format values in different ways:
Next up
The dungeon can store and change values, but it can't make decisions yet. In part 3, we add decisions and loops.
With if and else, the game responds to different situations. Then we build
a game loop that lets the dungeon listen to the player's commands over and over.
Keyboard shortcuts
- j k
- scroll down / up
- n p
- next / previous section
- g G
- start / end of the article
- t
- show outline
- ?
- show this help
- Esc
- close
0 comments
No comments yet. Be the first!
Sign in to leave a comment.