Data Types and Variables
Introduction
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.
Learning Objectives
By the end of this reading, you will be able to:
- Identify and use primitive data types
- Declare and assign variables
- Understand type systems (static vs dynamic)
- Perform type conversions
- Work with strings effectively
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