Phase 1 · FoundationsModule 2~38 min read

Variables, Data Types & Operators

Store and manipulate data with Python's dynamic typing, numeric types, and every operator the language offers.

What you'll learn

Every program is really just data being stored, changed, and combined. In this module you'll learn how Python holds data in variables, the types that data can take, and the operators you use to calculate and compare — including a few Python surprises.

By the end you'll be able to:

  • Create variables and understand Python's dynamic typing
  • Work with the core types: int, float, str, bool, and None
  • Convert between types safely with int(), float(), and str()
  • Use arithmetic operators — including Python's special /, //, and **
  • Apply comparison, logical, and bitwise operators
  • Predict results using operator precedence

Variables & dynamic typing

A variable is a name that refers to a value. Creating one couldn't be simpler — you just assign with =. There's no type declaration and no special keyword; Python figures out the type from the value:

variables.py
age = 25            # an int
price = 19.99       # a float
name = "Sara"       # a str
is_student = True   # a bool

print(age)
print(name, "-", price)

Python is dynamically typed: a variable is really just a label attached to an object, and you can re-attach that label to a value of a different type at any time. Use the built-in type() function to ask what type a value currently is:

A name is just a label
x = 5x──▶5 : int
x = "hi"x──▶'hi' : str
x = [1, 2, 3]x──▶[1, 2, 3] : list

The name x is just a label — it can point to a value of any type, and you can re-point it whenever you like.

dynamic.py
x = 5
print(type(x))          # <class 'int'>

x = "now I'm a string"  # totally fine — x can change type
print(type(x))          # <class 'str'>

x = [1, 2, 3]
print(type(x))          # <class 'list'>

Dynamic, but still strongly typed

"Dynamic" means you don't declare types and can rebind names freely. But Python is also strongly typed — it won't silently mix types. "5" + 5 is an error, not "55" or 10. You must convert explicitly (next section).

Tip

Name variables in snake_case (lowercase words joined by underscores) — it's the Python convention. Choose names that describe the meaning (total_price), not the type.

The core data types

You'll meet many types, but a handful cover almost everything you do early on:

Python's everyday types

int

42

Whole numbers — no size limit!

float

3.14

Numbers with decimals

str

"hello"

Text (a string)

bool

True

True or False

complex

2 + 3j

Complex numbers

NoneType

None

The absence of a value

numbers.py
whole = 42
pi = 3.14159
big = 1_000_000        # underscores just aid readability
c = 2 + 3j             # a complex number

print(type(whole), type(pi))
print(big)
print(2 ** 100)        # Python ints never overflow!

Python ints never overflow

Unlike many languages (Java included), Python integers have unlimited precision — they grow as large as your memory allows. 2 ** 100 is a perfectly ordinary calculation. No overflow, no wrap-around, ever.

Type conversion

Because Python won't mix types automatically, you convert values yourself using the type's name as a function: int(), float(), str(), bool(). This matters constantly — input() (Module 4) always gives you a str, so you must convert it before doing maths:

convert.py
# input() always returns a str — convert it to do maths
age_text = "25"
age = int(age_text)
print(age + 5)          # 30

print(float("19.99"))   # 19.99
print("Count: " + str(42))   # str() to join with text
print(int(3.9))         # 3  (truncates — does NOT round)
print(bool(0), bool(1)) # False True

int() truncates, it doesn't round

int(3.9) is 3, not 4 — it chops off the decimal part. Use round(3.9) if you actually want rounding. And note what's falsy: 0, 0.0, "", None, and empty collections all convert to False.

Arithmetic operators

The maths operators look familiar, but Python has three worth special attention — and the first one trips up newcomers from other languages:

OperatorMeaningExample → result
+Addition17 + 5 → 22
-Subtraction17 - 5 → 12
*Multiplication17 * 5 → 85
/True division (always float)17 / 5 → 3.4
//Floor division (rounds down)17 // 5 → 3
%Modulo (remainder)17 % 5 → 2
**Exponent (power)2 ** 5 → 32
arithmetic.py
a, b = 17, 5

print(a + b)     # 22
print(a - b)     # 12
print(a * b)     # 85
print(a / b)     # 3.4    <- true division ALWAYS gives a float
print(a // b)    # 3      <- floor (integer) division
print(a % b)     # 2      <- remainder (modulo)
print(a ** b)    # 1419857 <- 17 to the power of 5

/ always gives a float

This is a big difference from languages like Java or C. In Python, 10 / 2 is 5.0 (a float), never 5. If you want whole-number division, use floor division //: 10 // 3 is 3.

Comparison & logical operators

Comparison operators ask a yes/no question and produce a bool, while logical operators combine those booleans. Python has a lovely feature here — you can chain comparisons the way you would in maths:

ComparisonMeaningLogicalMeaning
==equal toandboth are true
!=not equal tooreither is true
>greater thannotflips true/false
>=greater or equal
<less than
<=less or equal
logic.py
age = 20

print(age >= 18)             # True
print(13 <= age <= 19)       # False  (chained comparison!)
print(age > 0 and age < 100) # True
print(not age == 21)         # True

Chained comparisons

13 <= age <= 19 reads exactly like maths and means "is age between 13 and 19?". Most languages don't allow this — in Python it's idiomatic and clear.

Bitwise operators

For working with the individual bits of integers — useful for flags, low-level code, and some algorithms — Python offers bitwise operators:

OperatorMeaning
&AND
|OR
^XOR
~NOT (invert bits)
<<left shift
>>right shift
bitwise.py
print(5 & 3)    # 1   bitwise AND
print(5 | 3)    # 7   bitwise OR
print(5 ^ 3)    # 6   bitwise XOR
print(1 << 4)   # 16  left shift (1 * 2**4)

Operator precedence

When several operators appear together, precedence decides who goes first — just like maths, where * beats +. From highest to lowest, simplified:

LevelOperatorsGroup
1()Parentheses
2**Exponent
3* / // %Multiplicative
4+ -Additive
5< <= > >= == !=Comparisons
6not → and → orLogical
When in doubt, add parentheses — they make intent obvious and cost nothing.

Tip

Don't memorise the whole table. Just remember: ** is highest, *// beat +/-, comparisons beat logic, and parentheses beat everything.

Recap & quick check

Key takeaways

  • Variables are labels created with =, with no type declaration — Python is dynamically (but strongly) typed.
  • Core types: int (no overflow!), float, str, bool, and None. Use type() to inspect.
  • Convert explicitly with int(), float(), str() — Python never mixes types silently.
  • / always returns a float; use // for floor division and ** for powers.
  • Comparisons give booleans and can be chained (13 <= age <= 19); parentheses beat all precedence.

Quick check

1. What is the result of 10 / 2 in Python?

2. How do you do whole-number (floor) division?

3. What does int(3.9) return?

4. Is '5' + 5 valid in Python?

5. What does ** do?

Great work — you can now store and manipulate data with confidence. Next up: Module 3 — Strings & Formatting, where you'll master Python's powerful text type.