Welcome to Day 4! Today is all about clean architecture, dependency isolation, and modern Python tooling. You will learn how to structure your files, control execution flows, use modern tools like uv to manage virtual environments at lightning speed, and organize a codebase like a professional software engineer. 🚀
1. Modules & Packages 📦
-
Module: A single
.pyfile containing variables, functions, or classes you want to reuse. - Package: A directory of modules.
-
__init__.py: Runs automatically when a package is imported, allowing you to expose a clean top-level API and hide internal folder nesting. -
Absolute Import: Imports specifying the full path from the project root (
from app.core import analyze). Preferred by PEP 8. -
Relative Import: Imports relative to the current file using dots (
from .utils import clean). Single dot.is current folder; double dot..is parent folder.
A. Core Modules & Packages
🌱 Easy Starter Example
Creating a basic module and importing it:
# file: calculator.py (Our module)
def add(a, b):
return a + b
# file: main.py (Importing our module)
import calculator
print(calculator.add(5, 3)) # Output: 8
🏛️ Real-World Example: Database Package API
Exposing internal package functions cleanly using __init__.py:
# Project Layout:
database/
├── __init__.py
├── auth.py (defines login_user())
└── query.py (defines fetch_data())
# database/__init__.py
# Expose functions relative to this folder so users don't need deep imports
from .auth import login_user
from .query import fetch_data
# main.py
# Clean absolute package import for the end-user
from database import login_user, fetch_data
login_user("admin", "password123")
B. Built-In vs. Third-Party Modules
-
Built-In: Included with Python out-of-the-box (e.g.,
os,sys,json). -
Third-Party: Built by the community and installed from PyPI (e.g.,
requests,rich).
🌱 Easy Starter Example
import math # Built-in math operations
print(math.sqrt(25)) # Output: 5.0
# import requests # Third-party (Will fail until installed!)
🏛️ Real-World Example: System Health Report
Combining built-ins with third-party styling packages to log environmental diagnostics:
import os
import sys
import json
# from rich import print # Third-party library for colorized terminal output
def generate_report():
sys_info = {
"os_name": os.name,
"python_ver": sys.version.split()[0],
"current_directory": os.getcwd()
}
# Convert Python dictionary to formatted JSON string using built-in library
json_report = json.dumps(sys_info, indent=2)
print(json_report)
generate_report()
2. Special Variables & Entry Points 🪄
Python tracks a hidden string variable named __name__ for every file.
- If you run a file directly,
__name__evaluates to"__main__". - If a file is imported,
__name__evaluates to its actual filename.
The Entry Point Pattern (if __name__ == "__main__":) acts as a safety guardrail. It prevents script logic from running automatically when a module is imported.
🌱 Easy Starter Example
# file: greeter.py
def hello():
print("Hello from greeter!")
# Direct run safety guard
if __name__ == "__main__":
print("This runs ONLY when executing greeter.py directly.")
hello()
🏛️ Real-World Example: Database Seeder Script
A script that imports utility functions, but includes local testing/seeding operations that should never run during production imports.
# file: db_migrator.py
def run_migrations():
print("Applying schema updates to database...")
if __name__ == "__main__":
# Local CLI testing execution block. Safe from running on production imports!
print("--- Local Debug Mode: Initializing Test Seeder ---")
run_migrations()
print("Test migrations complete.")
3. Modern Project Structure 🏛️
For professional applications, organizing your project elements systematically keeps your codebase scalable, deployable, and testable.
🌱 Easy Starter Example
A basic folder layout for a small personal script:
my_script_project/
├── .gitignore
├── README.md
├── main.py
└── utils.py
🏛️ Real-World Example: Enterprise Layout
A highly structured layout for a production microservice:
my_project/
├── .git/ # Git Version Control
├── .gitignore # Excludes build caches and virtual environments
├── README.md # Setup guide and API documentation
├── pyproject.toml # Unified project metadata and dependencies (PEP 621)
├── uv.lock # Pinned reproducible environment version lockfile
├── main.py # Main application entry point
├── app/ # Core application package folder
│ ├── __init__.py
│ ├── core.py
│ └── utils.py
└── tests/ # Automated test suite
└── test_core.py
4. Virtual Environments & Package Management 🌐
Virtual Environments (.venv) act as isolated sandboxes. If Project A needs Django v4.0 and Project B needs Django v5.0, global installations will break one of them. Environments keep their setups completely separate.
While classic Python uses pip, uv (written in Rust) acts as the modern industry gold standard—performing setup, installation, and compilation tasks 10–100x faster.
Pip vs. UV Commands Reference
| Action | Classic pip + venv Way |
Modern uv Way |
|---|---|---|
| Initialize Workspace | (Manual directory config) | uv init my_project |
Create .venv Room |
python -m venv .venv |
uv venv |
| Activate Env (Mac/Linux) | source .venv/bin/activate |
source .venv/bin/activate |
| Activate Env (Windows) | .venv\Scripts\activate |
.venv\Scripts\activate |
| Install Package | pip install requests |
uv add requests |
| Upgrade Package | pip install --upgrade requests |
uv add requests --upgrade |
| Uninstall Package | pip uninstall requests |
uv remove requests |
| Lock Environment | pip freeze > requirements.txt |
(Auto-tracked in pyproject.toml / uv.lock) |
| Sync Environment | pip install -r requirements.txt |
uv sync |
| Run Script |
python main.py (Requires activation)
|
uv run main.py (Auto-manages active env)
|
🌱 Easy Starter Example: Isolate a package with pip
# Classic manual setup
python -m venv .venv
source .venv/bin/activate
pip install requests
python -c "import requests; print(requests.__version__)"
🏛️ Real-World Example: Modernized uv workflow
# Initialize a modern template in one command
uv init my_app && cd my_app
# Add dependencies instantly to local metadata & venv
uv add requests
# Run your application immediately (uv auto-manages the environment)
uv run hello.py
5. Practice Challenge: Create a Modern Modular Project 🏋️
Let's build a structured, modular Text Processor App under Git version control using uv.
Step 1: Initialize Workspace Layout
Open your terminal and build your project architecture:
uv init text_utility_app && cd text_utility_app
git init
mkdir app tests
touch app/__init__.py app/core.py app/utils.py tests/test_core.py
Step 2: Establish the Project Ignore Bounds
Prevent tracking compiled cache databases or workspace binaries in Git:
# Create a .gitignore file in the root directory
# .gitignore
.venv/
__pycache__/
*.pyc
.uv/
Step 3: Implement Code Base
Create your utility parsing module:
# app/utils.py
def clean_whitespace(text: str) -> str:
"""Strips extra outer spaces and condenses internal gaps."""
return " ".join(text.split())
Create your analysis core, calling your sibling utility relative to its position:
# app/core.py
import json # Built-in module dependency
from .utils import clean_whitespace # Relative package import
def analyze_to_json(text: str) -> str:
"""Cleans text and packs word counts into a JSON string."""
cleaned = clean_whitespace(text)
metrics = {
"original_text": text,
"cleaned_text": cleaned,
"word_count": len(cleaned.split()) if text.strip() else 0
}
return json.dumps(metrics)
Map imports inside your package initialization gateway:
# app/__init__.py
# Expose functions directly to package consumers
from .core import analyze_to_json
Create the application entry point using a third-party styling package:
# main.py
from app import analyze_to_json # Custom package import
from rich import print # Third-party style library
if __name__ == "__main__":
raw_payload = " Day 4 Modules System Activated "
json_result = analyze_to_json(raw_payload)
print("[bold cyan]=== Processing Dashboard ===[/bold cyan]")
print(json_result)
Create local verification assertions:
# tests/test_core.py
from app.utils import clean_whitespace # Absolute project import
def test_string_cleaner():
assert clean_whitespace(" too many spaces ") == "too many spaces"
print("✓ Unit test diagnostics passed.")
if __name__ == "__main__":
test_string_cleaner()
Step 4: Resolve, Execute, and Save
Let uv handle installation, compile configurations, and build synchronization.
# Add third-party styling to pyproject.toml and env automatically
uv add rich
# Run the execution pipeline instantly
uv run main.py
# Run unit verification tests
uv run python tests/test_core.py
# Commit progress to Git
git add .
git commit -m "Feat: Complete modular project using uv and app package"
Top comments (0)