Back to Home
    PythonPython 3.12Beginner

    Python

    Python syntax, data structures, comprehensions, OOP, error handling, and standard library essentials.

    12 min read
    pythonscriptingdata-sciencebackend

    Basics

    2 topics

    Variables & Types

    python
    # Basic types
    name: str = "Alice"
    age: int = 30
    price: float = 9.99
    is_active: bool = True
    none_val = None
    
    # Type checking
    type(name)        # <class 'str'>
    isinstance(age, int)  # True
    
    # String formatting
    f"Hello, {name}!"     # f-string (preferred)
    "Hello, {}!".format(name)
    "%s is %d" % (name, age)

    💡 Use f-strings for formatting — they're fastest and most readable

    Data Structures

    python
    # List (mutable, ordered)
    fruits = ["apple", "banana", "cherry"]
    fruits.append("date")
    fruits[0]          # "apple"
    fruits[-1]         # "date"
    fruits[1:3]        # ["banana", "cherry"]
    
    # Tuple (immutable)
    coords = (10, 20)
    
    # Dict
    user = {"name": "Alice", "age": 30}
    user["email"] = "[email protected]"
    user.get("phone", "N/A")   # Safe access
    
    # Set
    tags = {"python", "web", "python"}  # {"python", "web"}

    💡 Use dict.get() to avoid KeyError

    ⚡ Sets automatically deduplicate values

    Core Syntax and Flow

    3 topics

    Variables, Types, and f-Strings

    Use Python’s dynamic typing for fast development, and f-strings for readable runtime values in logs and reports.

    python
    app_name = "inventory-service"
    version = 3
    is_active = True
    latency_ms = 18.73
    
    status_line = f"{app_name} v{version} active={is_active} latency={latency_ms:.1f}ms"
    print(status_line)
    
    # Type conversion (common with env vars / user input)
    port = int("8080")
    timeout = float("2.5")

    Prefer f-strings over string concatenation for clarity.

    Convert external input explicitly with int(), float(), bool-like checks.

    basicsstringstypes

    Conditionals and Structural Pattern Matching

    Branch logic clearly with if/elif and match/case (Python 3.10+) for command handling or event routing.

    python
    def handle_event(event: dict) -> str:
        if not event.get("type"):
            return "invalid"
    
        match event["type"]:
            case "user_created":
                return f"welcome:{event['user_id']}"
            case "payment_failed":
                return f"retry:{event['invoice_id']}"
            case _:
                return "ignored"
    
    print(handle_event({"type": "payment_failed", "invoice_id": "INV-102"}))

    Use a default case (_) in match for unknown payloads.

    Validate required keys before branching.

    control-flowmatch-case

    Loops, Comprehensions, and Enumerate

    Write concise transformations and indexed iteration for common tasks like data cleanup and report generation.

    python
    prices = [19.99, 5.0, 13.49, 0.0]
    nonzero_prices = [p for p in prices if p > 0]
    with_tax = [round(p * 1.2, 2) for p in nonzero_prices]
    
    for idx, price in enumerate(with_tax, start=1):
        print(f"#{idx}: ${price}")
    
    # Fast membership checks with set
    allowed_roles = {"admin", "editor", "viewer"}
    print("admin" in allowed_roles)

    Use comprehensions for simple transforms; switch to loops for complex logic.

    Use set for fast membership checks.

    loopscomprehensioncollections

    Functions and Data Models

    3 topics

    Functions with Type Hints and Defaults

    Build reusable business logic with explicit interfaces for better editor support and fewer runtime mistakes.

    python
    from typing import Iterable
    
    def calculate_total(amounts: Iterable[float], discount: float = 0.0) -> float:
        subtotal = sum(amounts)
        discount = min(max(discount, 0.0), 1.0)
        return round(subtotal * (1 - discount), 2)
    
    print(calculate_total([10.0, 20.0, 5.0], discount=0.1))

    Keep functions focused on one responsibility.

    Use type hints even when not enforced at runtime.

    functionstyping

    Dataclasses for Structured Data

    Represent domain entities (users, orders, configs) with less boilerplate than manual classes.

    python
    from dataclasses import dataclass, field
    from datetime import datetime
    
    @dataclass
    class Order:
        id: str
        customer_email: str
        amount: float
        created_at: datetime = field(default_factory=datetime.utcnow)
    
    order = Order(id="ORD-1", customer_email="[email protected]", amount=49.99)
    print(order)

    Use default_factory for mutable/default dynamic values.

    Dataclasses are ideal for DTOs and config objects.

    dataclassoop

    Error Handling and Custom Exceptions

    Catch expected failures (I/O, validation, network) and raise domain-specific exceptions for cleaner APIs.

    python
    class PaymentError(Exception):
        pass
    
    def charge(amount: float) -> str:
        if amount <= 0:
            raise PaymentError("Amount must be positive")
        return "charged"
    
    try:
        result = charge(-10)
    except PaymentError as exc:
        print(f"Payment failed: {exc}
    ")
    else:
        print(result)
    finally:
        print("Audit log written")

    Catch specific exceptions, not bare except.

    Use finally for cleanup/audit actions.

    exceptionsreliability

    Control Flow

    2 topics

    Conditionals & Loops

    python
    # Conditional
    if x > 0:
        print("positive")
    elif x == 0:
        print("zero")
    else:
        print("negative")
    
    # Ternary
    result = "yes" if condition else "no"
    
    # For loop
    for i in range(10):
        print(i)
    
    for i, val in enumerate(["a", "b", "c"]):
        print(i, val)
    
    for k, v in user.items():
        print(k, v)
    
    # While
    while count > 0:
        count -= 1

    💡 enumerate() is preferred over range(len(list))

    Comprehensions

    python
    # List comprehension
    squares = [x**2 for x in range(10)]
    evens = [x for x in range(20) if x % 2 == 0]
    
    # Dict comprehension
    word_len = {word: len(word) for word in words}
    
    # Set comprehension
    unique_lengths = {len(w) for w in words}
    
    # Generator (lazy — saves memory)
    sum_sq = sum(x**2 for x in range(1_000_000))

    ⚡ Use generators instead of list comprehensions for large datasets

    Files, JSON, and HTTP

    3 topics

    Pathlib and Safe File I/O

    Use pathlib for cross-platform paths and context managers for safe file handling.

    python
    from pathlib import Path
    
    log_dir = Path("logs")
    log_dir.mkdir(exist_ok=True)
    log_file = log_dir / "app.log"
    
    with log_file.open("a", encoding="utf-8") as f:
        f.write("service started\n")
    
    print(log_file.resolve())

    Always open text files with explicit encoding.

    Use with to avoid leaked file handles.

    filesystempathlib

    JSON Read/Write for APIs and Config

    Serialize and parse JSON payloads for REST APIs, config files, and message queues.

    python
    import json
    from pathlib import Path
    
    config = {
        "env": "prod",
        "retries": 3,
        "features": ["search", "alerts"]
    }
    
    Path("config.json").write_text(json.dumps(config, indent=2), encoding="utf-8")
    loaded = json.loads(Path("config.json").read_text(encoding="utf-8"))
    print(loaded["env"])

    Use indent for human-readable config files.

    Validate expected keys before using parsed JSON.

    jsonconfig

    Calling HTTP APIs with requests

    Fetch external data with timeout and status checks to avoid hanging or silent failures.

    python
    import requests
    
    url = "https://api.github.com/repos/python/cpython"
    resp = requests.get(url, timeout=10)
    resp.raise_for_status()
    repo = resp.json()
    
    print({
        "name": repo["name"],
        "stars": repo["stargazers_count"]
    })

    Always set timeout on network calls.

    Use raise_for_status() before parsing JSON.

    httpapirequests

    Functions

    1 topic

    Defining Functions

    python
    # Basic
    def greet(name: str, greeting: str = "Hello") -> str:
        return f"{greeting}, {name}!"
    
    # *args and **kwargs
    def log(*args, **kwargs):
        print(args, kwargs)
    
    log(1, 2, 3, level="info")  # (1,2,3) {'level': 'info'}
    
    # Lambda
    double = lambda x: x * 2
    
    # Type hints (Python 3.9+)
    def process(items: list[int]) -> dict[str, int]:
        return {"sum": sum(items), "count": len(items)}

    💡 Type hints improve readability and IDE support without enforcing at runtime

    OOP

    1 topic

    Classes

    python
    from dataclasses import dataclass
    
    @dataclass
    class Point:
        x: float
        y: float
    
        def distance(self) -> float:
            return (self.x**2 + self.y**2) ** 0.5
    
    # Traditional class
    class Animal:
        def __init__(self, name: str):
            self.name = name
    
        def speak(self) -> str:
            raise NotImplementedError
    
    class Dog(Animal):
        def speak(self) -> str:
            return f"{self.name} says Woof!"
    
    dog = Dog("Rex")
    dog.speak()  # "Rex says Woof!"

    💡 Use @dataclass for simple data containers — less boilerplate than full classes

    Testing and Code Quality

    3 topics

    pytest Basics

    Write fast unit tests for core logic so refactors are safe and regressions are caught early.

    python
    def normalize_email(email: str) -> str:
        return email.strip().lower()
    
    def test_normalize_email():
        assert normalize_email("  [email protected] ") == "[email protected]"

    Name test files like test_*.py for auto-discovery.

    Keep unit tests deterministic and isolated.

    testingpytest

    Mocking External Calls

    Mock HTTP/database dependencies to test behavior without hitting real services.

    python
    from unittest.mock import patch
    import requests
    
    def fetch_status(url: str) -> int:
        r = requests.get(url, timeout=5)
        return r.status_code
    
    @patch("requests.get")
    def test_fetch_status(mock_get):
        mock_get.return_value.status_code = 200
        assert fetch_status("https://example.com") == 200

    Mock at the boundary where external dependency is called.

    Avoid over-mocking internal implementation details.

    mockingunit-test

    Linting and Formatting

    Automate style and quality checks in CI to keep code readable and consistent across teams.

    python
    # Install tools
    # pip install ruff black
    
    # Format code
    # black .
    
    # Lint and auto-fix simple issues
    # ruff check . --fix

    Run formatters before commit using pre-commit hooks.

    Treat lint warnings as actionable quality feedback.

    lintformattingci

    Environment and Packaging

    2 topics

    Virtual Environments and Dependencies

    Isolate project dependencies to avoid version conflicts across apps.

    python
    # Create and activate venv
    # python -m venv .venv
    # source .venv/bin/activate  # Linux/macOS
    # .venv\Scripts\activate     # Windows
    
    # Install deps
    # pip install requests pytest
    
    # Freeze exact versions
    # pip freeze > requirements.txt

    Commit requirements.txt (or lock file) for reproducible installs.

    Use one venv per project.

    venvpipdependencies

    Project Entry Point (CLI Script)

    Expose scripts for operations tasks, batch jobs, or developer tooling.

    python
    import argparse
    
    def main():
        parser = argparse.ArgumentParser()
        parser.add_argument("--name", default="world")
        args = parser.parse_args()
        print(f"Hello, {args.name}!")
    
    if __name__ == "__main__":
        main()

    Keep CLI parsing in main(); keep business logic in separate functions.

    Return non-zero exit codes for failures in automation scripts.

    cliargparse

    Error Handling

    1 topic

    Exceptions

    python
    try:
        result = 10 / 0
    except ZeroDivisionError as e:
        print(f"Error: {e}")
    except (TypeError, ValueError) as e:
        print(f"Type/Value error: {e}")
    else:
        print("No error")     # Runs if no exception
    finally:
        print("Always runs")  # Cleanup code
    
    # Raise custom exception
    class ValidationError(Exception):
        pass
    
    raise ValidationError("Invalid input")
    
    # Context manager
    with open("file.txt") as f:
        data = f.read()        # File auto-closed

    💡 Always use specific exception types — never bare except:

    ⚡ Use context managers (with) for resources like files and DB connections

    Related Articles

    Background reading and deeper explanations for this sheet.

    Intro to FastAPI: Build a Production-Ready Python API with Real Examples

    FastAPI is one of the fastest ways to build modern APIs in Python without sacrificing code quality or developer experience. In this practical, beginner-friendly guide, you’ll learn how to create endpoints, validate data, handle errors, connect a database, secure routes, and prepare your FastAPI app for real-world deployment.

    keyword overlap

    GenAI SaaS Architecture: A Practical Blueprint for Building, Scaling, and Securing AI Products

    Designing a SaaS product on top of GenAI is more than calling an LLM API—it requires thoughtful architecture across product, data, safety, and operations. This practical guide walks you through a beginner-friendly yet deep system blueprint, with real-world patterns, code snippets, and deployment strategies you can use immediately.

    keyword overlap

    Python GIL and Async Programming: A Practical Cheat Sheet for Real Apps

    Confused about when Python threads help and when they hurt? This beginner-friendly, practical guide explains the GIL and async programming with real examples, so you can choose the right concurrency model for APIs, data pipelines, and background jobs.

    keyword overlap

    Python Stack vs Heap Memory: A Simple, Practical Guide for Developers

    Confused about where Python stores function calls, variables, and real objects? This guide breaks down stack vs heap memory in plain English, with clear examples showing local references on the stack and actual objects on the heap. You’ll learn how this impacts performance, debugging, and writing cleaner Python code.

    keyword overlap