Variables, Data Types & Basic Operations
2. Variables, Pointers, Memory Models & Primitive Data Types
2.1The Python Object Model: Variables as Nametags
In many old programming languages (like C), a variable is like a physical cardboard box in memory that holds a value inside it. In Python, variables do NOT hold values directly inside themselves! Instead, variables are nametags (pointers/references) stuck onto objects floating in memory (called the heap).
ANALOGY TIME
item_count and total_stock) can be stuck onto the exact same physical item!- You can inspect an object's unique memory address using the built-in
id()function. - You can check how many nametags are currently pointing to an object using
sys.getrefcount().
2.2CPython Memory Optimizations: Small Int Cache & String Interning
To keep your computer fast and avoid wasting memory, CPython uses two clever shortcuts:
- Small Integer Cache:
- Every integer between -5 and 256 is pre-created in memory when Python starts up. - If you assign a = 100 and b = 100, Python doesn't create a second number 100 in memory. Instead, both a and b point to the exact same pre-created number 100! Testing a is b returns True. - Analogy: Like a school board having a permanent set of printed number cards 1 through 256 in the teacher's drawer, rather than printing a new card every single time a student asks for a number.
- String Interning (`sys.intern`):
- Python automatically caches certain string identifiers (like variable names or short text strings). - Why? Comparing two strings character-by-character takes time ($O(n)$). But if both strings point to the exact same memory address, Python can compare them instantly ($O(1)$) just by checking if their memory addresses match!
2.3Core Primitives & Immutability Rules
Python comes with four fundamental primitive data types: integers (int), floating-point decimal numbers (float), text strings (str), and boolean true/false flags (bool).
- Primitives are Immutable:
- "Immutable" simply means cannot be changed in-place. Once a primitive object is created in memory, its value can never be altered. - When you run x = 5 and then x = x + 1, Python doesn't change the number 5 into 6. It creates a brand new number object 6 in memory and moves the x nametag to point to 6!
- Arbitrary-Precision Integers:
- In many languages, if an integer gets too big, it wraps around into negative numbers or causes a crash (integer overflow). Python automatically grows the memory size for integers as big as needed, so your numbers can have hundreds of digits without crashing!
- IEEE 754 Floating Point Precision:
- Computers store decimal numbers (float) in binary (base-2). Because some decimal fractions (like 0.1) cannot be represented perfectly in binary, small rounding discrepancies occur. For example, 0.1 + 0.2 evaluates to 0.30000000000000004! - Why this matters: In financial applications (like calculating money or invoice totals), float rounding errors can cause accounting bugs. Always use Python's built-in decimal.Decimal module for exact money math!
2.4Code Demo 1: Memory Address & Small Int Cache Testing
Let's see the small integer cache in action by checking memory addresses with id():
2.5Code Demo 2: Exact Financial Precision with decimal.Decimal
Compare standard float math with exact Decimal math:
GOTCHA 1
Attempting to concatenate strings and integers directly (e.g. 'Age: ' + 25) raises TypeError. Use f-strings (f'Age: {25}') or explicit str() casting.
GOTCHA 2
Comparing floats directly for exact equality (e.g. 0.1 + 0.2 == 0.3 evaluates to False due to binary IEEE 754 floating-point representation). Use math.isclose() or round values.
GOTCHA 3
Shadowing built-in function names by using variable names like type, str, int, list, or sum. This overwrites the built-in function in the current scope.
GOTCHA 4
Assuming integer division / returns an integer. In Python 3, / always yields a float (e.g. 4 / 2 is 2.0). Use integer floor division // for whole integers.
WHERE THIS SHOWS UP IN REAL CODE
Every application processes data: user profiles, shopping cart totals, database IDs, and configuration flags. In Python, variables act as labels bound to memory locations containing typed objects like strings, integers, floats, and booleans.
TRY THIS YOURSELF
Modify Demo 3 to calculate and display the error percentage (100 - success_rate) formatted to 3 decimal places.
Experiment by changing the quantities or tax rates to see how Python updates calculation outputs.
Demonstrate dynamic typing, variable memory references with id(), and f-string formatting.
Let's practice rectangle geometry using Python variables!
Steps to Complete:
- Create two variables:
width = 15andheight = 8. - Calculate the area (
width * height) and printArea: 120. - Calculate the perimeter (
2 * (width + height)) and printPerimeter: 46.
Input: None
Expected Output:
Let's build a formatted score card message for a user!
Steps to Complete:
- Define variables
user_name = 'DevUser'andscore = 94.5. - Print a single formatted line inserting these variables:
User DevUser achieved a score of 94.5%.
Input: user_name = 'DevUser', score = 94.5
Expected Output:
Let me help you calculate system uptime percentage!
Steps to Complete:
- Define
total_hours = 720anddowntime_hours = 1.8. - Print
Total Hours: 720. - Calculate uptime percentage as
((total_hours - downtime_hours) / total_hours) * 100and printUptime: 99.75%.
Input: None
Expected Output:
In Python, what happens when you reassign an integer variable `x = 5` to `x = 10`?
What is the return type of the division operator `/` in Python 3?
What is the result of `'Python' + 3`?
Why does `0.1 + 0.2 == 0.3` evaluate to `False` in Python?
Which function allows you to inspect the unique memory address of an object in CPython?
How do you format a float `val = 12.3456` to 2 decimal places using an f-string?
# comments · basics
- @priya · 2h ago
The typewriter hero is such a nice touch.
- @alex · 1h ago
Totally agree! Made it super engaging.
- @sam · 1d ago
Finally a course where I can run code without leaving the page.