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
- Indentation: how Python organizes blocks
- Comments
- Basic data types:
int,float,str,boolandNone - Arithmetic operators
- Comparison operators
- Logical operators
- Type conversion
- 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):
- 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 theifannounces 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.
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 xnext tox = x + 1adds nothing;# the order includes one free copydoes. - 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).
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:
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:
Some basic operations with strings:
>>> "Papyrus" + " " + "Books" # concatenation (joining texts)
'Papyrus Books'
>>> "=" * 20 # repetition
'===================='
>>> len("The Odyssey") # length: number of characters
11Strings 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?
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:
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
FalseWatch 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 False → False |
or |
at least one is True |
True or False → True |
not |
inverts the value | not True → False |
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 holdsSummary 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)gives3: it truncates (cuts off the decimals), it doesn't round. To round there'sround(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: " + 42fails. You must convert:"Total: " + str(42)... or better, use f-strings, which we'll see next. - In
bool(x), zero, the empty string""andNoneare consideredFalse; almost everything else isTrue.
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")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:
A useful preview: you can control the decimals with :.2f (two fixed decimals), ideal for prices:
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,90is not afloatin 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 aSyntaxErrorin a comparison, check this first. - Writing
true/falsein lowercase: in Python they areTrueandFalse. In lowercase you'll get aNameError. - Adding text and a number:
"Total: " + 5throws aTypeError. Quick fix:str(5). Elegant fix:f"Total: {5}". - Forgetting the
fof the f-string:print("{title}")without thefliterally prints{title}, braces included. If you see the braces in the output, you're missing thef. - 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:
7 / 27 // 27 % 2"7" + "2"7 > 2int("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:
Afterwards, try changing stock to 0 and check that the result changes.
Solutions
Solution 1
7 / 2→3.5, typefloat(the/division always returnsfloat).7 // 2→3, typeint(integer division: it discards the decimals).7 % 2→1, typeint(remainder of dividing 7 by 2)."7" + "2"→"72", typestr(with strings,+concatenates, it doesn't add).7 > 2→True, typebool(comparisons return booleans).int("7") + 2→9, typeint(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")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}")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
- Introduction to Python
- Setting Up the Development Environment
- Python Syntax and Basic Data Types
- Variables and Constants
- Basic Input and Output
- Virtual Environments and Package Management
Module 2: Control Structures
Module 3: Functions and Modules
- Defining Functions
- Function Arguments
- Lambda Functions
- Modules and Packages
- Standard Library Overview
Module 4: Data Structures
Module 5: Object-Oriented Programming
Module 6: File Handling
Module 7: Error and Exception Handling
- Introduction to Exceptions
- Handling Exceptions
- Raising Exceptions
- Custom Exceptions
- Best Practices and Error Logging
Module 8: Advanced Topics
- Type Hints
- Decorators
- Generators
- Context Managers
- Concurrency: Threads and Processes
- Asyncio for Asynchronous Programming
Module 9: Testing and Debugging
- Introduction to Testing
- Unit Testing with unittest
- Testing with pytest
- Test-Driven Development
- Debugging Techniques
- Using pdb for Debugging
Module 10: Web Development with Python
- Introduction to Web Development
- Flask Framework Fundamentals
- Building REST APIs with Flask
- Introduction to Django
- Building Web Applications with Django
Module 11: Data Science with Python
- Introduction to Data Science
- NumPy for Numerical Computing
- Pandas for Data Manipulation
- Matplotlib for Data Visualization
- Introduction to Machine Learning with scikit-learn
