1.1Variables, types & operators
The essentials in 30 seconds
- Variable = label on an object: age = 30 — Python infers the type (int, float, str, bool), and = copies the label, not always the object.
- Strong typing: convert explicitly: "3" + 4 fails — go through int(), float(), str(), and convert the text from input() before any computation.
- = assigns, == compares, is identifies: / gives a float, // the integer quotient, % the remainder, ** the power.
Running mini-case — Nabil, junior data analyst in Algiers
Nabil, a junior data analyst in Algiers, is preparing a survey-data cleanup: he stores the respondent's name, age and height in clear variables, then computes the birth year from an entered age. In a hurry, he writes print("I am " + age) and adds the text returned by input() to a number: TypeError, then a wrong total. He fixes it with an f-string and int(): the age becomes a real number, the report displays correctly. As a bonus, he discovers that a = b = [] shares a single list — from now on he will copy with list().
This same case returns in the lesson, diagram, script and 48h challenge — and continues in 1.2, 1.3, 1.4 and 1.5.
1. Label-variables & types
A variable is a label placed on a value: age = 30 sticks the label "age" onto the object 30. Python has dynamic typing (no prior declaration) but strong typing: "3" + 4 raises an error instead of converting silently. Four basic types: int (integer), float (decimal), str (text, immutable), bool (True/False, which drives conditions). type() reveals the type; name things in explicit snake_case (respondent_age rather than x).
Nabil stores name = "Yasmine", age = 30, height = 1.70: labels that say what they carry, re-read effortlessly when his manager asks for the report.
2. Conversions, input() and operators
You change type explicitly: int("30"), float("3.5"), str(30). Crucial: input() ALWAYS returns text — convert with int() or float() before computing. Operators: / divides into a float (7/2 = 3.5), // integer quotient (3), % remainder (7%2 = 1), ** power. And = assigns while == compares (is tests identity): confusing the two in a test is bug #1.
Nabil replaces his faulty concatenation with f"I am {age} years old" and converts the entry with int(input(...)): the birth year becomes correct, and the type error disappears.
🔎 Concrete example — 🔎 Concrete example — The two-labels trap
Understanding assignment, like Nabil with his lists.
a = []
b = a # same object!
a.append(1)
print(b) # [1]: a single list
b = a.copy() # real independent copy
print("3" + str(4)) # "34": explicit conversion
print(7 // 2, 7 % 2, 2 ** 10) # 3 1 1024
Reading: = copies the label, not the object — .copy() creates an independent list; str() makes concatenation possible.
Lesson: is tests identity, == equality; //, % and ** each have their own role.
Section vocabulary
- Variable
- Name that references a value in memory (a label on an object). Assignment with =: my_var = value.
Simple example: The name and age stored by Nabil for his survey.
What it is not: a box that would hold a copy on each assignment.
Reflex: think label, name in explicit snake_case.
- int / float
- Integers (int: 30) and decimals (float: 3.14). Division / always gives a float; // gives the integer quotient.
Simple example: The age (int) and height (float) of Nabil's respondents.
What it is not: expecting 3 from 10 / 3 (it is 3.333, a float).
Reflex: / for the real number, // for the quotient, % for the remainder.
- str (string)
- Text between single or double quotes: "Hello". Immutable (not modifiable in place); assembled with f-strings.
Simple example: The respondent's name displayed by Nabil in an f-string.
What it is not: adding "3" + 4 without conversion.
Reflex: text + number = convert first (or f-string).
- bool
- Boolean: True or False. Result of comparisons, basis of the next chapter's conditions.
Simple example: The adult = age >= 18 computed by Nabil.
What it is not: confusing = (assignment) and == (comparison).
Reflex: = assigns, == compares, is identifies.
- Conversion (casting)
- Changing type explicitly: int("30") gives 30; str(30) gives "30". Essential because input() always returns text.
Simple example: The age entry converted by Nabil with int().
What it is not: computing directly on the text from input().
Reflex: input() = text: int() or float() before computing.
In practice — In practice — Handling variables, types and conversions
- Create variables of each type: name = "Ada", age = 30, height = 1.70, adult = True. Display each with print() and its type with type(variable).
- Test the operators: 7 // 2 (integer division), 7 % 2 (remainder/modulo), 2 ** 10 (power). Predict the result before running.
- Trigger the classic error: print("I am " + age) → TypeError. Fix it with an f-string: print(f"I am {age} years old").
- Ask for the age with input(), convert it to a number (int(...)) and compute the birth year: see why conversion is essential.
Script ready to say — justifying explicit conversion (30 s)
"input() always returns text, so I convert with int() before computing: otherwise we add text and a number and it crashes — or worse, it gives a wrong result. Explicit conversion makes the intent visible and the computation reliable."
Say in code review; show the TypeError before/after.
Copy-paste template — variables, f-string and input() conversion
nom = "Nabil"
age = 30
taille = 1.70
majeur = age >= 18
print(f"{nom} is {age} years old, adult: {majeur}")
print(type(taille)) #
age_saisi = int(input("Age? "))
annee_naissance = 2026 - age_saisi
print(f"Birth year: {annee_naissance}")
print(7 // 2, 7 % 2, 2 ** 10)
Survey in Algiers
Like Nabil: variables named per respondent, f-string for the report — the manager re-reads a clean table, with no TypeError.
Entry to convert
Every input() goes through int() or float() before computing: the birth year is correct, the total too.
Targeted operators
// for integer quotas, % for remainders, ** for projections — each operator for its own job, no tinkering.
Doubt about an alias
A type(obj) or an is test settles it: the label is checked, not guessed — copy with list() if needed.
✓ Best practices
- Think label, not box — and name in explicit snake_case.
- Convert explicitly (int/float/str), especially the text from input().
- Distinguish = (assigns), == (compares) and is (identifies).
✗ Common pitfalls
- Writing a = b = [] then being surprised that both move together.
- Adding "3" + 4 without conversion (TypeError).
- Using = in an if instead of ==.
Key takeaways
- A variable is a name placed on a value (name = value); Python infers the type (dynamic) but never mixes types by itself (strong).
- Four basic types: int, float, str, bool — type() reveals, int()/str() convert.
- input() ALWAYS returns text: convert with int() or float() to compute.
- Useful operators: // (integer division), % (modulo), ** (power); = assigns, == compares, is identifies.
48h challenge — apply tomorrow
Take one of your scripts (template above): convert each input() to int()/float(), replace each + concatenation between text and numbers with an f-string, and rename a cryptic variable in snake_case. Run and check the display. 20 minutes is enough.
- I can explain the label, strong typing and explicit conversion.
- I convert input() to a number before any computation.
- I choose //, % and ** without hesitation, and I distinguish = from ==.
Frequently asked questions
Why does 10 / 3 give 3.333 and not 3?
In Python 3, the / operator always performs a "real" division and returns a float. To get the integer quotient (3), use integer division //; for the remainder, modulo %. It is a deliberate language choice: exact division by default, integers on explicit request.
What is the difference between = and ==?
A single = assigns a value to a variable (x = 5). Double == compares two values and returns True or False (x == 5). Confusing them is a very common beginner mistake — and is tests identity (same object), not just equality.
What does the input() function always return?