Variables and Data Types in Python

In Python, every value has a type, and variables are simply labels that point to values. Unlike JavaScript’s let, const, and var, Python has no variable declaration keyword โ€” you assign a value and the variable exists. Python is dynamically typed: the type is determined by the value, not by the variable name, and you can reassign a variable to a completely different type at any time. This flexibility is powerful, but the addition of type hints (covered in Chapter 12) lets you add type safety when working on larger projects like a FastAPI application.

Creating Variables

# Assign a value โ€” no keyword needed
name     = "Alice"
age      = 30
height   = 5.7
is_admin = True
nothing  = None

# Python naming convention: snake_case (not camelCase)
# Good:  user_name, post_count, is_active
# Bad:   userName, postCount, isActive  โ† JavaScript style

# Variables are case-sensitive
Name = "Bob"   # different variable from 'name'

# Multiple assignment on one line
x = y = z = 0

# Swap two variables (no temp variable needed)
a, b = 1, 2
a, b = b, a   # a = 2, b = 1
print(a, b)   # 2 1
Note: Python naming convention is snake_case โ€” words separated by underscores, all lowercase. This applies to variables, functions, and module names. Class names use PascalCase. Constants (values that should not change) are written in ALL_CAPS_WITH_UNDERSCORES. These are conventions, not enforced by the language, but all Python code you encounter โ€” including FastAPI and SQLAlchemy โ€” follows them.
Tip: Use the type() built-in function to inspect the type of any value. In the Python interactive shell (python3), you can type type(42) and immediately see <class 'int'>. This is invaluable when debugging type-related bugs โ€” especially when working with data returned from PostgreSQL or parsed from JSON, where types may not be what you expect.
Warning: Python’s dynamic typing means there is no compiler to catch type errors before runtime. The code result = "5" + 5 raises a TypeError at runtime โ€” Python does not automatically convert between strings and numbers the way JavaScript does. This is by design โ€” Python is explicit about type conversions โ€” but it means you must be deliberate about types when building FastAPI endpoints that receive user data.

Python’s Five Primitive Types

# 1. int โ€” whole numbers (unlimited size in Python)
population = 8_000_000_000   # underscores improve readability
hex_val    = 0xFF             # hexadecimal literal = 255
bin_val    = 0b1010           # binary literal = 10

# 2. float โ€” decimal numbers (64-bit double precision)
price    = 19.99
pi       = 3.14159
sci      = 1.5e10             # scientific notation = 15000000000.0

# 3. str โ€” text (immutable, Unicode by default)
first_name = "Alice"
last_name  = 'Smith'          # single or double quotes โ€” same thing
full_name  = first_name + " " + last_name   # concatenation

# 4. bool โ€” True or False (capitalised)
is_published = True
has_premium  = False

# 5. NoneType โ€” the absence of a value (equivalent to null in SQL/JS)
result = None
print(type(result))   # <class 'NoneType'>

# Check the type of any value
print(type(42))        # <class 'int'>
print(type(3.14))      # <class 'float'>
print(type("hello"))   # <class 'str'>
print(type(True))      # <class 'bool'>

Type Conversion

# Explicit type conversion (casting)
int("42")          # โ†’ 42        (string to int)
int(3.9)           # โ†’ 3         (float to int โ€” truncates, does NOT round)
float("3.14")      # โ†’ 3.14      (string to float)
str(100)           # โ†’ "100"     (int to string)
bool(0)            # โ†’ False     (0 is falsy)
bool(1)            # โ†’ True      (any non-zero int is truthy)
bool("")           # โ†’ False     (empty string is falsy)
bool("hello")      # โ†’ True      (non-empty string is truthy)
bool(None)         # โ†’ False     (None is falsy)

# Python does NOT auto-convert โ€” this raises TypeError:
# "5" + 5   โ†’ TypeError: can only concatenate str (not "int") to str

# Correct:
str(5) + " items"   # โ†’ "5 items"  โœ“
5 + int("3")        # โ†’ 8          โœ“

# Checking for numeric string before converting
user_input = "42"
if user_input.isdigit():
    number = int(user_input)
    print(number + 1)   # 43

The isinstance() Function

# isinstance() checks if a value is of a specific type
# More reliable than type() for type checking

age = 25

isinstance(age, int)          # True
isinstance(age, float)        # False
isinstance(age, (int, float)) # True โ€” check against multiple types

name = "Alice"
isinstance(name, str)         # True

# Useful for input validation in FastAPI:
def process_age(age):
    if not isinstance(age, int):
        raise ValueError(f"Expected int, got {type(age).__name__}")
    return age

Python Truthiness Rules

Value Truthy? Notes
True Yes โ€”
False No โ€”
None No Like null in JS
0, 0.0 No Zero values are falsy
"" No Empty string is falsy
[], {}, () No Empty collections are falsy
Any non-zero number Yes -1, 42, 0.1 all truthy
Non-empty string Yes "0", "False" โ€” truthy!
Non-empty list/dict Yes [0], {"a": 1} truthy

Common Mistakes

Mistake 1 โ€” Using camelCase instead of snake_case

โŒ Wrong โ€” JavaScript naming in Python:

firstName = "Alice"   # works but violates PEP 8 convention
postCount = 42        # Python community will flag this in code review

โœ… Correct โ€” snake_case for variables and functions:

first_name = "Alice"   # โœ“
post_count = 42        # โœ“

Mistake 2 โ€” Expecting automatic type coercion

โŒ Wrong โ€” assuming Python converts types like JavaScript:

result = "Count: " + 5   # TypeError! No auto-conversion

โœ… Correct โ€” convert explicitly:

result = "Count: " + str(5)   # "Count: 5" โœ“
result = f"Count: {5}"        # f-string โœ“

Mistake 3 โ€” int() truncates, not rounds

โŒ Wrong โ€” assuming int() rounds:

int(3.9)   # โ†’ 3 (not 4!) โ€” truncates toward zero

โœ… Correct โ€” use round() if you want rounding:

round(3.9)   # โ†’ 4 โœ“
round(3.5)   # โ†’ 4 (banker's rounding)

Quick Reference

Task Code
Check type type(value)
Check instance isinstance(value, int)
String to int int("42")
Int to string str(42)
Float to int int(3.9) โ†’ 3 (truncates)
Round float round(3.9) โ†’ 4
Swap variables a, b = b, a
Multiple assignment x, y, z = 1, 2, 3

🧠 Test Yourself

What is the output of print(type(True)) in Python?