Data Types and Variables
Every piece of data in a program has a type. Understanding data types is fundamental - they determine what operations are valid, how data is stored in memory, and how much space it requires.
1. What are Data Types?
A data type defines:
- What values a piece of data can hold
- What operations can be performed on it
- How it's represented in memory
Why Types Matter
# These look similar but behave differently
a = "5" # String
b = 5 # Integer
print(a + a) # "55" (string concatenation)
print(b + b) # 10 (addition)
2. Primitive Data Types
Primitive types are the basic building blocks provided by a language.
Integers
Whole numbers (positive, negative, or zero).
age = 25
temperature = -10
count = 0
# Python has arbitrary precision integers
big_number = 12345678901234567890
print(big_number * 2) # Works perfectly!
Common operations:
a = 10
b = 3
print(a + b) # 13 (addition)
print(a - b) # 7 (subtraction)
print(a * b) # 30 (multiplication)
print(a / b) # 3.333... (true division)
print(a // b) # 3 (floor division)
print(a % b) # 1 (modulo - remainder)
print(a ** b) # 1000 (exponentiation)
Floating-Point Numbers
Numbers with decimal points.
pi = 3.14159
price = 19.99
scientific = 6.022e23 # 6.022 × 10²³
Important: Floating-point has precision limits!
print(0.1 + 0.2) # 0.30000000000000004 (not exactly 0.3!)
# Why? Binary can't represent 0.1 exactly, just like
# decimal can't represent 1/3 exactly (0.333...)
# For money, use integers (cents) or Decimal
from decimal import Decimal
print(Decimal('0.1') + Decimal('0.2')) # 0.3 (exact)
Booleans
True or False values.
is_student = True
is_employed = False
# Boolean operations
print(True and False) # False
print(True or False) # True
print(not True) # False
# Comparison operators return booleans
print(5 > 3) # True
print(5 == 5) # True
print(5 != 3) # True
None / Null
Represents the absence of a value.
result = None
if result is None:
print("No result yet")
3. Strings
Strings are sequences of characters.
name = "Alice"
message = 'Hello, World!'
multiline = """This is a
multi-line string"""
# Empty string
empty = ""
String Operations
first = "Hello"
last = "World"
# Concatenation
full = first + " " + last # "Hello World"
# Repetition
laugh = "ha" * 3 # "hahaha"
# Length
print(len(first)) # 5
# Indexing (0-based)
print(first[0]) # "H"
print(first[-1]) # "o" (last character)
# Slicing
print(first[1:4]) # "ell"
print(first[:3]) # "Hel" (first 3)
print(first[2:]) # "llo" (from index 2)
String Methods
text = " Hello, World! "
print(text.lower()) # " hello, world! "
print(text.upper()) # " HELLO, WORLD! "
print(text.strip()) # "Hello, World!" (remove whitespace)
print(text.replace("World", "Python")) # " Hello, Python! "
print(text.split(",")) # [" Hello", " World! "]
# Checking content
print("Hello" in text) # True
print(text.startswith(" H")) # True
print(text.isdigit()) # False
String Formatting
name = "Alice"
age = 25
# f-strings (Python 3.6+, recommended)
message = f"My name is {name} and I am {age} years old"
# format method
message = "My name is {} and I am {} years old".format(name, age)
# % formatting (older style)
message = "My name is %s and I am %d years old" % (name, age)
# Formatting numbers
pi = 3.14159
print(f"Pi is approximately {pi:.2f}") # "Pi is approximately 3.14"
price = 1234.5
print(f"Price: ${price:,.2f}") # "Price: $1,234.50"
Strings are Immutable
s = "Hello"
# s[0] = "h" # Error! Can't modify strings
# Create a new string instead
s = "h" + s[1:] # "hello"
4. Variables
A variable is a named reference to a value stored in memory.
Declaration and Assignment
# Python infers the type
x = 10 # x is an integer
x = "hello" # Now x is a string (Python allows this)
# Multiple assignment
a, b, c = 1, 2, 3
# Swap values
a, b = b, a
Naming Rules and Conventions
Rules (must follow):
- Start with letter or underscore
- Contain only letters, numbers, underscores
- Case-sensitive (
name≠Name) - Cannot be a reserved keyword
Conventions (should follow):
# Variables: snake_case
user_name = "alice"
total_count = 100
# Constants: UPPER_SNAKE_CASE
MAX_SIZE = 1000
PI = 3.14159
# Private (by convention): leading underscore
_internal_value = 42
# Avoid:
l = 1 # Looks like 1
O = 0 # Looks like 0
Scope
Variables have a scope - where they can be accessed.
global_var = "I'm global"
def my_function():
local_var = "I'm local"
print(global_var) # Can access global
print(local_var) # Can access local
my_function()
print(global_var) # Works
# print(local_var) # Error! local_var doesn't exist here
5. Type Systems
Static vs Dynamic Typing
Static typing: Types checked at compile time
// Java (static)
int x = 5;
x = "hello"; // Compile error!
Dynamic typing: Types checked at runtime
# Python (dynamic)
x = 5
x = "hello" # Fine! x is now a string
Strong vs Weak Typing
Strong typing: Limited implicit conversions
# Python is strongly typed
x = "5" + 3 # Error! Can't add string and int
Weak typing: More implicit conversions
// JavaScript is weakly typed
x = "5" + 3 // "53" (3 becomes "3")
Type Hints in Python
Python 3.5+ supports optional type hints:
def greet(name: str) -> str:
return f"Hello, {name}"
age: int = 25
names: list[str] = ["Alice", "Bob"]
Type hints are not enforced at runtime but help with documentation and can be checked with tools like mypy.
6. Type Conversion
Implicit Conversion
Python automatically converts in some cases:
x = 5 # int
y = 2.0 # float
z = x + y # 7.0 (int promoted to float)
Explicit Conversion (Casting)
# To integer
int("42") # 42
int(3.7) # 3 (truncates, doesn't round)
int("3.7") # Error! Can't parse directly
# To float
float("3.14") # 3.14
float(42) # 42.0
# To string
str(42) # "42"
str(3.14) # "3.14"
str(True) # "True"
# To boolean
bool(0) # False
bool(42) # True (any non-zero is True)
bool("") # False (empty string)
bool("hello") # True (non-empty string)
bool([]) # False (empty list)
bool([1,2]) # True (non-empty list)
7. Composite Types Preview
Beyond primitives, languages offer ways to group data:
Lists (Arrays)
Ordered, mutable collections:
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True]
print(numbers[0]) # 1
numbers.append(6) # [1, 2, 3, 4, 5, 6]
numbers[0] = 10 # [10, 2, 3, 4, 5, 6]
Tuples
Ordered, immutable collections:
point = (3, 4)
rgb = (255, 128, 0)
x, y = point # Unpacking
# point[0] = 5 # Error! Tuples are immutable
Dictionaries (Maps)
Key-value pairs:
person = {
"name": "Alice",
"age": 25,
"city": "Boston"
}
print(person["name"]) # "Alice"
person["age"] = 26 # Update value
person["job"] = "Engineer" # Add new key
Sets
Unordered collections of unique elements:
numbers = {1, 2, 3, 2, 1} # {1, 2, 3}
print(2 in numbers) # True
a = {1, 2, 3}
b = {2, 3, 4}
print(a | b) # Union: {1, 2, 3, 4}
print(a & b) # Intersection: {2, 3}
8. Memory and References
How Variables Work
Variables in Python are references to objects in memory:
a = [1, 2, 3]
b = a # b refers to the SAME list
b.append(4)
print(a) # [1, 2, 3, 4] - a is affected!
# To make a copy:
c = a.copy() # or list(a) or a[:]
c.append(5)
print(a) # [1, 2, 3, 4] - a is NOT affected
Identity vs Equality
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True (same value)
print(a is b) # False (different objects)
print(a is c) # True (same object)
# id() shows memory address
print(id(a)) # e.g., 140234567890
print(id(c)) # Same as above
print(id(b)) # Different
Small Integer Caching
Python caches small integers (-5 to 256):
a = 100
b = 100
print(a is b) # True (same cached object)
a = 1000
b = 1000
print(a is b) # False (different objects)
Exercises
Basic
- What is the type of each variable?
a = 42
b = 3.14
c = "hello"
d = True
e = None
f = [1, 2, 3]
- What does each expression evaluate to?
10 + 3
10 - 3
10 * 3
10 / 3
10 // 3
10 % 3
10 ** 3
- Fix the errors:
print("The answer is " + 42)
name = "Alice
age = twenty-five
Intermediate
Write code that:
- Takes a temperature in Celsius
- Converts it to Fahrenheit: F = C × 9/5 + 32
- Prints the result formatted to 1 decimal place
What happens with each conversion? Predict, then test:
int(3.9)
int("3.9")
float("hello")
bool([])
bool([0])
str([1, 2, 3])
- Explain why this happens:
a = [1, 2, 3]
b = a
b.append(4)
print(a) # What prints?
Advanced
Research: What is the largest integer Python can handle? What about floats?
Investigate floating-point issues:
# Why do these give different results?
sum([0.1] * 10)
0.1 * 10
- Create a simple program that:
- Stores person data in a dictionary
- Has at least 4 fields (name, age, height, is_student)
- Prints a formatted summary
Summary
- Data types determine what values and operations are valid
- Primitive types: integers, floats, booleans, None
- Strings are immutable sequences of characters
- Variables are references to values in memory
- Python is dynamically typed (types checked at runtime)
- Python is strongly typed (limited implicit conversions)
- Use explicit conversion (casting) when needed
- Collections (lists, tuples, dicts, sets) group data together