Chapter 04

Variables and types — how a program remembers

Storing values in variables, the rules for naming them, and the four basic types — int, float, str, bool — plus the error beginners hit most often.

30 minPython 3.12
  1. 1Encounter
  2. 2Understand
  3. 3Worked
  4. 4Predict
  5. 5Apply
  6. 6Stretch

The problem we are solving

So far our programs could remember nothing. Whatever was printed was gone.

Real work does not happen that way. In a billing program a price is calculated once and needed in three places. In a report a total has to be worked out first and used later. The program has to remember.

And there is a second problem alongside it. In the last mission "2" + "3" gave 23 while 2 + 3 gave 5 — the same symbol, two behaviours. That is because in Python's eyes those two things are of different kinds. The kind is called a type, and the largest share of a beginner's errors come from here.

By the end of this mission you can

  • Store a value in a variable and change it later
  • Choose names Python accepts, and that a human can read
  • Recognise the four basic types: int, float, str, bool
  • Inspect any value's type with type()
  • Read a TypeError and tell exactly what it is complaining about

Prerequisites: Seeing with print, explaining with comments.


A variable is a name

python
city_count = 4

Read that line right to left: the value 4 came into existence, and the label city_count was attached to it. From now on, writing city_count hands you that value.

python
city_count = 4
print("Cities:", city_count)
print("Double:", city_count * 2)
text
Cities: 4
Double: 8
= does not mean equals. In mathematics x = 4 is a claim: x and 4 are the same. In Python = is an instruction: "store this value under that name." Which is why total = total + 5 — impossible as mathematics — is perfectly ordinary Python. It means "take what total holds now, add 5, and put the result back in total." Checking whether two things are equal has its own symbol, ==, which we will meet later.

Changing a value

Assigning a new value to a variable leaves nothing of the old one:

python
stock = 20
print("Before:", stock)

stock = stock - 3
print("After:", stock)
text
Before: 20
After: 17

One thing worth pinning down — the value is copied; the two labels do not stay wired together:

python
a = 10
b = a
a = 99
print(a, b)
text
99 10

On the line b = a, b received whatever a held at that moment, namely 10. Changing a afterwards does not change b — b was never watching a, it received a value.

Rules for names

What Python will not accept:

  • Starting with a digit: 2nd_price is out, price_2 is fine
  • A dash in the middle: total-price is out, Python reads it as subtraction
  • A space in the middle: total price is out
  • Python's reserved words: class, for, if, import, return, None cannot be used as names

What Python accepts but you should not write:

python
x1 = 4500           # clear today, meaningless in three weeks
Total_Price = 4500  # legal Python, but not the Python convention
l = 4500            # lowercase L and the digit one look almost identical

The professional Python convention is snake_case — lowercase, with underscores between words:

python
total_price = 4500
customer_name = "Rafi"
items_in_cart = 3

Fussing over names can feel like wasted time, but code is written once or twice and read twenty times. A name that explains itself does the work of a comment.

The four basic types

python
items = 7        # int   — a whole number
price = 249.50   # float — a number with a decimal point
name = "Rafi"    # str   — text, inside quotes
is_paid = True   # bool  — only True or False

print(type(items))
print(type(price))
print(type(name))
print(type(is_paid))
text
<class 'int'>
<class 'float'>
<class 'str'>
<class 'bool'>

type() is your instrument for settling doubt. When a variable behaves strangely, the first move is to print its type. Most of the time the answer is right there.

Two small but important notes:

True and False start with a capital letter. Write true and Python treats it as a variable name and reports that it does not know it.

"7" and 7 are not the same thing. The first is text, the second is a number. They look alike and are completely distinct to Python:

python
a = 7
b = "7"
print(type(a), type(b))
print(a * 3)
print(b * 3)
text
<class 'int'> <class 'str'>
21
777

The error everyone gets

python
age = "22"
print(age + 1)
text
Traceback (most recent call last):
  File "D:\python-lab\lesson-04\demo.py", line 2, in <module>
    print(age + 1)
          ~~~~^~~
TypeError: can only concatenate str (not "int") to str

The message looks intimidating and is in fact precise: only a str can be joined to a str, not an int. Python cannot tell whether you meant to add or to join — so rather than guess, it stopped.

Read error messages from the bottom up. The last line says what is wrong; the line above it says where. Beginners often panic at the sight of a traceback and skip it entirely, but Python's error messages are the most helpful text on your screen.

The fix is to make the number a number:

python
age = "22"
print(int(age) + 1)
text
23

int() converts text to a whole number. When that works and when it collapses is covered properly in the mission on input(), because there this problem arrives every single time.


A complete example

invoice.py:

python
# Invoice for a single order, all figures in one place
customer_name = "Rafi"
unit_price = 249.50
quantity = 3
is_member = True

subtotal = unit_price * quantity
discount = 50.0
total = subtotal - discount

print("Customer  :", customer_name)
print("Quantity  :", quantity)
print("Subtotal  :", subtotal)
print("Discount  :", discount)
print("Total     :", total)
print("Member    :", is_member)
text
Customer  : Rafi
Quantity  : 3
Subtotal  : 748.5
Discount  : 50.0
Total     : 698.5
Member    : True

Notice where the real benefit is: to change the price you edit the unit_price line only, and every calculation below corrects itself. Had the numbers been typed straight into the print calls, you would have to hunt down every occurrence each time — and missing one makes the report wrong.


When it breaks

NameError: name 'total' is not defined The name you used has not been given a value yet, or it is misspelled. Python treats total and totl as two different names. Note that case matters too: Total is not total.

TypeError: can only concatenate str (not "int") to str You tried to join a number onto text. Either convert with int(), or use a comma — print("Age:", age) — because print handles mixed types itself.

SyntaxError: invalid syntax — a dash in a name On the line total-price = 5, Python sees an attempt to subtract price from total. Use an underscore: total_price.

SyntaxError: cannot assign to keyword You tried to use one of Python's reserved words as a name, such as class = 10. Pick another: class_name, grade.

NameError: name 'true' is not defined True and False start with a capital letter.