With the environment up and running, it's time to learn the rules of the game: how Python code is structured (indentation, comments) and what basic materials it works with (numbers, texts, booleans). You'll also meet the operators to combine them, learn how to convert one type into another, and pick up a tool you'll use every day: f-strings. This lesson is the foundation on which absolutely everything else is built, so take it slowly and try every example in the REPL or in a script.

Contents

  1. Indentation: how Python organizes blocks
  2. Comments
  3. Basic data types: int, float, str, bool and None
  4. Arithmetic operators
  5. Comparison operators
  6. Logical operators
  7. Type conversion
  8. f-strings: text with embedded values

Indentation: how Python organizes blocks

In many languages, code blocks are delimited with braces { }. Python made a different and very distinctive decision: blocks are delimited by indentation, that is, by the spaces at the beginning of each line.

Look at this snippet (it uses an if condition; we'll study them in depth in module 2 — here we only care about the shape):

stock = 5

if stock > 0:
    print("Copies available")
    print("You can sell it")
print("End of program")
  • The two indented lines (shifted 4 spaces to the right) form the block that depends on the if: they only run if the condition is met.
  • The last line, not indented, is outside the block: it always runs.
  • The colon : at the end of the if announces that an indented block comes next.

Golden rules:

  • Use 4 spaces per indentation level (it's the official convention, set out in the PEP 8 style guide).
  • Don't mix tabs and spaces: it causes errors that are hard to spot. Configure your editor so the Tab key inserts 4 spaces (VS Code does this by default in Python files).
  • Indentation is not decorative: changing it changes the meaning of the program.
if stock > 0:
print("Copies available")   # IndentationError: the indentation is missing

This code doesn't run: Python expects an indented block after the : and doesn't find one. The positive consequence of this design is that all the Python code in the world has a uniform, readable look.

Comments

A comment is text that Python ignores completely; it exists only for the humans reading the code. It's written with the # symbol: everything from # to the end of the line is a comment.

# This script calculates the value of Papyrus's new releases shelf
price = 15.90        # price in euros of one copy
copies = 3           # units on the shelf

# The total is price times units
print(price * copies)

Good practices:

  • Comment the why, not the obvious what. # adds 1 to x next to x = x + 1 adds nothing; # the order includes one free copy does.
  • Keep comments up to date: a comment that lies is worse than none.
  • To temporarily "disable" a line of code while testing, put a # in front of it (this is what's called commenting out code).

Basic data types: int, float, str, bool and None

Every value in Python has a type, which determines what it is and what can be done with it. The five fundamental ones:

Type Name What it represents Examples
int Integer Numbers without decimals 42, -3, 0, 2500
float Floating point Numbers with decimals 15.90, -0.5, 3.0
str String Text "Papyrus", 'The Odyssey'
bool Boolean True or false True, False
NoneType Nothing Absence of a value None

You can ask for the type of any value with the type() function:

>>> type(42)
<class 'int'>
>>> type(15.90)
<class 'float'>
>>> type("Papyrus")
<class 'str'>
>>> type(True)
<class 'bool'>

Integers (int)

Numbers without a decimal part: units in stock, number of customers, year of publication. In Python they can be arbitrarily large (there's no practical size limit).

>>> 120 + 35          # total copies on two shelves
155

Decimals (float)

Numbers with a decimal part, written with a point (not a comma): 15.90, not 15,90. They're the natural choice for Papyrus's prices.

One important detail: float values are stored in binary and sometimes produce tiny inaccuracies:

>>> 0.1 + 0.2
0.30000000000000004

It's not a Python bug (it happens in almost every language), but a limitation of binary representation. For this course it's enough to know that it exists and that when displaying prices it's best to round (f-strings, at the end of this lesson, solve it elegantly).

Strings (str)

Text delimited by double quotes "..." or single quotes '...' — both are valid; pick one and be consistent. If the text contains a quote, use the other kind on the outside:

store = "Papyrus"
slogan = 'The "good old" bookshop in your neighbourhood'

Some basic operations with strings:

>>> "Papyrus" + " " + "Books"      # concatenation (joining texts)
'Papyrus Books'
>>> "=" * 20                       # repetition
'===================='
>>> len("The Odyssey")             # length: number of characters
11

Strings have much more to offer (methods, slicing, etc.); we'll cover them in depth in module 4. For now, creating, joining and measuring is enough.

Booleans (bool)

Only two possible values: True and False, with a capital initial letter. They answer yes-or-no questions: is it in stock? does the customer get a discount?

in_stock = True
out_of_print = False

Booleans come into their own with the conditional statements of module 2; here we'll learn to produce them with the comparison operators.

None: the absence of a value

None represents "nothing" or "no value yet". It's useful, for example, to indicate that we don't know a piece of data yet:

return_date = None   # the book isn't on loan to anyone

It's not 0 nor an empty string: it's a type of its own, and it literally means absence of a value.

Arithmetic operators

Python includes the usual mathematical operators and a few more:

Operator Operation Example Result
+ Addition 15.90 + 12.50 28.4
- Subtraction 20 - 3 17
* Multiplication 15.90 * 3 47.7
/ Division (always yields float) 10 / 4 2.5
// Integer division (discards decimals) 10 // 4 2
% Modulo (remainder of the division) 10 % 4 2
** Power 2 ** 10 1024

An example applied to Papyrus:

# Ana wants to split 10 new copies into boxes of 4
copies = 10
per_box = 4

print(copies // per_box)   # 2  -> full boxes
print(copies % per_box)    # 2  -> loose copies left over
  • // answers "how many full boxes can I fill?"
  • % answers "how many copies are left out?"

Precedence follows the mathematical rules (first **, then * / // %, then + -). When in doubt, use parentheses: (15.90 + 12.50) * 2 is clearer and avoids surprises.

Comparison operators

They compare two values and always return a boolean (True or False):

Operator Meaning Example Result
== Equal to 5 == 5 True
!= Not equal to 5 != 3 True
> Greater than 10 > 20 False
< Less than 10 < 20 True
>= Greater than or equal 5 >= 5 True
<= Less than or equal 4 <= 3 False
>>> stock = 0
>>> stock > 0            # is there any copy left?
False
>>> price = 15.90
>>> price <= 20          # does it fit Luis's budget?
True
>>> "Hamlet" == "hamlet" # capitalization matters in texts
False

Watch out: == (compare) and = (assign, which we'll see in the next lesson) are different things. Confusing them is one of the most classic beginner mistakes.

Logical operators

They combine booleans to express compound conditions:

Operator Returns True when... Example
and both operands are True True and FalseFalse
or at least one is True True or FalseTrue
not inverts the value not TrueFalse

Example: Luis wants a book that is available and costs less than 20 euros:

stock = 3
price = 15.90

in_stock = stock > 0
is_affordable = price < 20

print(in_stock and is_affordable)   # True  -> both conditions are met
print(not in_stock)                 # False -> it is in stock
print(stock == 0 or price > 50)     # False -> neither condition holds

Summary truth table for and and or:

A B A and B A or B
True True True True
True False False True
False True False True
False False False False

Type conversion

You often need to transform a value from one type to another. Python offers functions named after the target type:

Function Converts to... Example Result
int(x) Integer int("42"), int(3.99) 42, 3 (truncates, doesn't round)
float(x) Decimal float("15.90"), float(7) 15.9, 7.0
str(x) String str(15.90) "15.9"
bool(x) Boolean bool(0), bool("hello") False, True
>>> int("120")        # from text to integer: perfect for quantities
120
>>> float("15.90")    # from text to decimal: perfect for prices
15.9
>>> str(2026) + " will be a great year for Papyrus"
'2026 will be a great year for Papyrus'
>>> int("fifteen")    # this CANNOT be converted
ValueError: invalid literal for int() with base 10: 'fifteen'

Important observations:

  • int(3.99) gives 3: it truncates (cuts off the decimals), it doesn't round. To round there's round(3.99)4.
  • Converting text to a number only works if the text looks like a number; otherwise you get a ValueError (you'll learn to handle it in module 7).
  • You can't concatenate text and a number directly: "Total: " + 42 fails. You must convert: "Total: " + str(42)... or better, use f-strings, which we'll see next.
  • In bool(x), zero, the empty string "" and None are considered False; almost everything else is True.

This conversion will be vital in lesson 01-05, because everything the user types arrives as text and will need converting.

f-strings: text with embedded values

f-strings (formatted strings) are the modern, recommended way to build texts that mix literals and values. You write them by putting an f before the quotes, and inside you embed expressions between braces { }:

title = "The Odyssey"
price = 12.50
stock = 4

print(f"{title} costs {price} euros and there are {stock} copies left")
The Odyssey costs 12.5 euros and there are 4 copies left

Advantages over concatenation with +:

  • You don't have to convert numbers with str(): the f-string does it by itself.
  • The text reads at a glance, with the values in their place.
  • Any expression fits inside the braces, not just variables:
>>> print(f"Two copies: {12.50 * 2} euros")
Two copies: 25.0 euros

A useful preview: you can control the decimals with :.2f (two fixed decimals), ideal for prices:

>>> price = 12.5
>>> print(f"Price: {price:.2f} euros")
Price: 12.50 euros

In lesson 01-05 we'll explore formatting in more detail (alignment, column widths). For now, get used to using f-strings whenever you need to mix text and values.

Common Mistakes and Tips

  • IndentationError: almost always caused by forgetting to indent after :, indenting where you shouldn't, or mixing tabs with spaces. Configure your editor to 4 spaces and be consistent.
  • Using a decimal comma: 15,90 is not a float in Python (in fact it creates something else: a tuple, which you'll see in module 4). Decimals go with a point: 15.90.
  • Confusing = with ==: = assigns, == compares. If Python gives you a SyntaxError in a comparison, check this first.
  • Writing true/false in lowercase: in Python they are True and False. In lowercase you'll get a NameError.
  • Adding text and a number: "Total: " + 5 throws a TypeError. Quick fix: str(5). Elegant fix: f"Total: {5}".
  • Forgetting the f of the f-string: print("{title}") without the f literally prints {title}, braces included. If you see the braces in the output, you're missing the f.
  • Tip: whenever you're unsure about types, ask the REPL with type(). It's free and clears up a lot of confusion.

Exercises

Exercise 1

Without running the code, state the type (int, float, str or bool) and the resulting value of each expression. Then check it in the REPL:

  1. 7 / 2
  2. 7 // 2
  3. 7 % 2
  4. "7" + "2"
  5. 7 > 2
  6. int("7") + 2

Exercise 2

Papyrus sells Hamlet at 9.95 euros. A customer buys 3 copies and pays with a 50 euro note. Write a script that calculates and displays, with an f-string (and two decimals), the purchase total and the change to give back.

Exercise 3

Write a script that, given these variables, calculates a boolean recommended that is True only if the book is in stock (more than 0 units) and its price is less than or equal to 15 euros, and displays it with an f-string:

title = "The Odyssey"
price = 12.50
stock = 4

Afterwards, try changing stock to 0 and check that the result changes.

Solutions

Solution 1

  1. 7 / 23.5, type float (the / division always returns float).
  2. 7 // 23, type int (integer division: it discards the decimals).
  3. 7 % 21, type int (remainder of dividing 7 by 2).
  4. "7" + "2""72", type str (with strings, + concatenates, it doesn't add).
  5. 7 > 2True, type bool (comparisons return booleans).
  6. int("7") + 29, type int (first we convert the text to an integer, then we add).

Solution 2

# hamlet_purchase.py
price = 9.95
units = 3
payment = 50

total = price * units
change = payment - total

print(f"Purchase total: {total:.2f} euros")
print(f"Change due: {change:.2f} euros")
Purchase total: 29.85 euros
Change due: 20.15 euros

The :.2f format guarantees exactly two decimals, essential when displaying money (and it also hides the tiny inaccuracies of float values).

Solution 3

# recommended.py
title = "The Odyssey"
price = 12.50
stock = 4

recommended = stock > 0 and price <= 15

print(f"Recommend {title}? {recommended}")
Recommend The Odyssey? True

With stock = 0, the first condition (stock > 0) becomes False, and since and requires both to be true, recommended becomes False.

Conclusion

You now know Python's essential grammar: blocks are defined by indentation of 4 spaces, comments with #, and data is classified into types (int, float, str, bool, None). You know how to combine them with arithmetic, comparison and logical operators, convert between types and build clean messages with f-strings. Papyrus can now calculate totals and change, and decide whether a book is worth recommending.

You'll have noticed that throughout the lesson we've been storing values under names like price or stock without formally explaining what they are. That is precisely the topic of the next lesson: Variables and Constants — how they're assigned, how to name them well according to PEP 8, and what exactly happens when you reassign a value.

Python Programming Course

Module 1: Introduction to Python

Module 2: Control Structures

Module 3: Functions and Modules

Module 4: Data Structures

Module 5: Object-Oriented Programming

Module 6: File Handling

Module 7: Error and Exception Handling

Module 8: Advanced Topics

Module 9: Testing and Debugging

Module 10: Web Development with Python

Module 11: Data Science with Python

Module 12: Final Project

© Copyright 2026. All rights reserved