Variables & Data Types

Understanding Python variables, data types, and type conversion fundamentals

Overview

Variables are containers for storing data values. Python is dynamically typed, meaning you don't need to declare variable types explicitly.

Variable Declaration

PYTHON
# Simple variable assignments
name = "Python"
age = 30
pi = 3.14159
is_active = True

# Multiple assignment
x, y, z = 1, 2, 3

# Same value to multiple variables
a = b = c = 100

Data Types

Basic Data Types

PYTHON
# Integer
count = 42
binary = 0b1010  # Binary
octal = 0o52     # Octal
hexa = 0x2A      # Hexadecimal

# Float
price = 19.99
scientific = 1.5e3  # 1500.0

# String
single = 'Hello'
double = "World"
multi = """Multi
line string"""

# Boolean
is_valid = True
is_empty = False

# None
result = None

Type Checking

PYTHON
# Check variable type
x = 42
print(type(x))  # <class 'int'>

# Instance checking
print(isinstance(x, int))  # True
print(isinstance(x, (int, float)))  # True

Type Conversion

PYTHON
# String to number
num_str = "123"
num = int(num_str)  # 123
float_num = float(num_str)  # 123.0

# Number to string
value = 42
str_value = str(value)  # "42"

# Boolean conversion
print(bool(0))  # False
print(bool(1))  # True
print(bool(""))  # False
print(bool("text"))  # True

Variable Naming Rules

PYTHON
# Valid names
my_variable = 1
_private = 2
userName = 3
user_name = 4
USER_CONSTANT = 5

# Invalid names (will cause errors)
# 2variable = 1  # Cannot start with number
# my-var = 2     # No hyphens allowed
# class = 3      # Reserved keyword

Variable Scope

PYTHON
# Global variable
global_var = "I'm global"

def my_function():
    # Local variable
    local_var = "I'm local"
    
    # Access global
    print(global_var)
    
    # Modify global
    global global_var
    global_var = "Modified"

my_function()
# print(local_var)  # Error: not defined

Constants

PYTHON
# Python doesn't have true constants
# Convention: use UPPERCASE
PI = 3.14159
MAX_SIZE = 100
DEFAULT_COLOR = "blue"

# Using Enum for constants
from enum import Enum

class Status(Enum):
    PENDING = 1
    APPROVED = 2
    REJECTED = 3

Memory Management

PYTHON
# Variables are references
a = [1, 2, 3]
b = a  # b references same list
b.append(4)
print(a)  # [1, 2, 3, 4]

# Create copy
c = a.copy()  # or a[:]
c.append(5)
print(a)  # [1, 2, 3, 4]
print(c)  # [1, 2, 3, 4, 5]

# Check identity
print(a is b)  # True
print(a is c)  # False
print(a == c)  # False

Best Practices

1. Use descriptive names: user_age instead of a 2. Follow naming conventions: snake_case for variables 3. Initialize variables: Avoid using undefined variables 4. Use type hints (Python 3.5+):

PYTHON
   name: str = "John"
   age: int = 30
   scores: list[int] = [90, 85, 88]
   

Common Pitfalls

PYTHON
# Mutable default arguments
def add_item(item, list=[]):  # Bad!
    list.append(item)
    return list

# Better approach
def add_item(item, list=None):
    if list is None:
        list = []
    list.append(item)
    return list

# Integer caching
a = 256
b = 256
print(a is b)  # True (cached)

x = 257
y = 257
print(x is y)  # May be False

Real-World Examples

Example 1: Configuration Management

PYTHON
# Application configuration using constants and type hints
from typing import Final, Dict, Any
from dataclasses import dataclass

# Constants for configuration
APP_NAME: Final[str] = "DataProcessor"
MAX_RETRIES: Final[int] = 3
TIMEOUT_SECONDS: Final[float] = 30.0
DEBUG_MODE: Final[bool] = False

@dataclass
class DatabaseConfig:
    """Database configuration with type safety"""
    host: str = "localhost"
    port: int = 5432
    database: str = "myapp"
    user: str = "admin"
    password: str = ""  # Load from environment
    
    def connection_string(self) -> str:
        return f"postgresql://{self.user}:{self.password}@{self.host}:{self.port}/{self.database}"

# Usage
config = DatabaseConfig()
config.port = 3306  # MySQL port
print(config.connection_string())

Example 2: Data Validation

PYTHON
# User input validation with type conversion
from typing import Optional, Union

def get_validated_age() -> Optional[int]:
    """Get and validate user age input"""
    while True:
        try:
            age_input = input("Enter your age: ")
            age = int(age_input)
            
            if age < 0:
                print("Age cannot be negative")
                continue
            elif age > 150:
                print("Please enter a valid age")
                continue
                
            return age
            
        except ValueError:
            print("Please enter a valid number")
            retry = input("Try again? (y/n): ").lower()
            if retry != 'y':
                return None

def calculate_price(base_price: float, quantity: int, discount: float = 0.0) -> float:
    """Calculate total price with optional discount"""
    if not isinstance(base_price, (int, float)):
        raise TypeError(f"base_price must be numeric, got {type(base_price)}")
    
    if quantity <= 0:
        raise ValueError("Quantity must be positive")
    
    subtotal = base_price * quantity
    discount_amount = subtotal * (discount / 100)
    return round(subtotal - discount_amount, 2)

# Usage
price = calculate_price(19.99, 3, 10)  # 10% discount
print(f"Total: ${price}")

Example 3: Dynamic Variable Management

PYTHON
# Managing application state with proper scoping
class ApplicationState:
    """Manage global application state safely"""
    _instance = None
    _state: Dict[str, Any] = {}
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def set(self, key: str, value: Any) -> None:
        """Set a state variable"""
        self._state[key] = value
        print(f"State updated: {key} = {value}")
    
    def get(self, key: str, default: Any = None) -> Any:
        """Get a state variable with optional default"""
        return self._state.get(key, default)
    
    def delete(self, key: str) -> bool:
        """Remove a state variable"""
        if key in self._state:
            del self._state[key]
            return True
        return False
    
    def clear(self) -> None:
        """Clear all state variables"""
        self._state.clear()

# Usage - Singleton pattern ensures single instance
app_state = ApplicationState()
app_state.set('user_id', 12345)
app_state.set('session_token', 'abc123xyz')
app_state.set('preferences', {'theme': 'dark', 'language': 'en'})

# Access from anywhere in the application
state2 = ApplicationState()  # Same instance
user_id = state2.get('user_id')
print(f"Current user: {user_id}")

Practice Exercises

Exercise 1: Variable Type Detective

PYTHON
# TODO: Complete this function
def analyze_variable(var):
    """
    Analyze a variable and return a dictionary with:
    - type: the type name
    - value: the actual value
    - is_numeric: True if int or float
    - is_iterable: True if can be iterated
    - length: length if applicable, else None
    """
    # Your code here
    pass

# Test cases
test_vars = [42, 3.14, "hello", [1,2,3], {"a": 1}, None, True]
for var in test_vars:
    print(analyze_variable(var))

Exercise 2: Smart Calculator

PYTHON
# TODO: Create a calculator that handles different numeric types
def smart_calculate(a, b, operation):
    """
    Perform calculation handling type conversion smartly:
    - Convert strings to numbers if possible
    - Handle mixed int/float operations
    - Return appropriate type (int for integer results, float otherwise)
    Operations: '+', '-', '*', '/', '//', '**', '%'
    """
    # Your code here
    pass

# Test cases
print(smart_calculate("10", 3, "+"))      # Should return 13
print(smart_calculate(10.5, "2", "*"))    # Should return 21.0
print(smart_calculate("100", "3", "//"))  # Should return 33

Exercise 3: Variable Memory Manager

PYTHON
# TODO: Implement a class that tracks variable usage
class VariableTracker:
    """
    Track variable assignments and provide statistics:
    - Count number of assignments per variable name
    - Track type changes
    - Identify most frequently updated variables
    """
    def __init__(self):
        # Your initialization here
        pass
    
    def track(self, var_name, value):
        """Record a variable assignment"""
        # Your code here
        pass
    
    def get_stats(self, var_name):
        """Get statistics for a specific variable"""
        # Your code here
        pass
    
    def report(self):
        """Generate a report of all tracked variables"""
        # Your code here
        pass

# Usage example
tracker = VariableTracker()
tracker.track('counter', 0)
tracker.track('counter', 1)
tracker.track('counter', 2)
tracker.track('name', 'Alice')
tracker.track('name', 'Bob')
tracker.report()

Quick Reference Card

PYTHON
# Variable Declaration Patterns
single_value = 42                    # Single assignment
x, y, z = 1, 2, 3                    # Multiple assignment
a = b = c = 0                        # Chain assignment
first, *rest = [1, 2, 3, 4]        # Unpacking with rest

# Type Checking Patterns
isinstance(x, int)                   # Check single type
isinstance(x, (int, float))         # Check multiple types
type(x).__name__                    # Get type name as string
hasattr(obj, 'attribute')           # Check attribute existence

# Type Conversion Patterns
int("123")                          # String to integer
float("3.14")                       # String to float
str(42)                             # Number to string
bool(value)                         # Truthy/falsy check
list("abc")                         # String to list of chars

# Memory Management Patterns
import sys
sys.getsizeof(variable)            # Get memory size
id(variable)                        # Get memory address
variable is other                  # Identity check
variable == other                   # Equality check
del variable                        # Delete variable

# Best Practice Patterns
MY_CONSTANT: Final[int] = 100      # Type-hinted constant
result: Optional[str] = None       # Optional type hint
data: list[int] = []                # Generic type hint
config: dict[str, Any] = {}        # Dictionary type hint