Skip to content

Constants & Configuration Management Guide

Professional Handling of Magic Numbers and Strings in Python Projects


Table of Contents

  1. What Are Magic Numbers/Strings?
  2. Constants Hierarchy
  3. Project Organization
  4. Application Constants
  5. Enumerations (Enums)
  6. Configuration Management
  7. User-Facing Strings (i18n)
  8. Environment-Specific Values
  9. PySide6-Specific Patterns
  10. Best Practices
  11. Refactoring Strategy

What Are Magic Numbers/Strings?

The Problem

# BAD - Magic numbers and strings everywhere
def calculate_price(quantity):
    if quantity > 100:
        return quantity * 9.99 * 0.9  # What does 0.9 mean?
    return quantity * 9.99

def send_notification(user):
    if user.status == "premium":  # String duplicated everywhere
        send_email(user.email, "New Feature Available")

def validate_input(value):
    if len(value) < 8:  # Why 8?
        return False
    if value == "admin":  # Hardcoded admin
        return True

Problems: - Meaning unclear (what is 0.9? Why 8?) - Duplication (same values in many places) - Hard to change (find and update all occurrences) - Error-prone (typo: "premum" instead of "premium") - Not testable (values cannot be easily mocked)

The Solution

# GOOD - Named constants
from myapp.constants import (
    BULK_DISCOUNT_THRESHOLD,
    BULK_DISCOUNT_RATE,
    UNIT_PRICE,
    MIN_PASSWORD_LENGTH,
    ADMIN_USERNAME,
)
from myapp.constants import UserStatus, NotificationTemplate

def calculate_price(quantity: int) -> float:
    """Calculate price with bulk discount."""
    if quantity > BULK_DISCOUNT_THRESHOLD:
        return quantity * UNIT_PRICE * (1 - BULK_DISCOUNT_RATE)
    return quantity * UNIT_PRICE

def send_notification(user: User) -> None:
    """Send notification based on user status."""
    if user.status == UserStatus.PREMIUM:
        send_email(user.email, NotificationTemplate.NEW_FEATURE)

def validate_input(value: str) -> bool:
    """Validate user input."""
    if len(value) < MIN_PASSWORD_LENGTH:
        return False
    if value == ADMIN_USERNAME:
        return True
    return True

Benefits: - Self-documenting - Centrally managed - Easy to change - Type-safe (with Enums) - Testable


Constants Hierarchy

Overview: When to Use Which Solution?

+-------------------------------------------------------------+
|                    CONSTANTS HIERARCHY                        |
+-------------------------------------------------------------+
|                                                               |
|  1. HARDCODED VALUES (in code)                               |
|     - Python built-ins (True, False, None)                   |
|     - Obvious numbers (0, 1, -1)                             |
|     - One-time local calculations                            |
|                                                               |
|  2. MODULE CONSTANTS (constants.py)                          |
|     - Business logic constants                               |
|     - Numeric thresholds                                     |
|     - Format strings                                         |
|     - System-wide defaults                                   |
|                                                               |
|  3. ENUMERATIONS (enums.py)                                  |
|     - State values (state machine)                           |
|     - Categories/types                                       |
|     - Options/choices                                        |
|     - Type-safe string alternatives                          |
|                                                               |
|  4. CONFIGURATION (config.py + files)                        |
|     - Environment-dependent (dev/prod)                       |
|     - Deployment-specific                                    |
|     - User-configurable                                      |
|     - Runtime-changeable                                     |
|                                                               |
|  5. USER-FACING STRINGS (messages.py + i18n)                 |
|     - UI text                                                |
|     - Error messages                                         |
|     - Notifications                                          |
|     - Translatable text                                      |
|                                                               |
|  6. ENVIRONMENT VARIABLES (.env)                             |
|     - Secrets (API keys, passwords)                          |
|     - URLs (APIs, databases)                                 |
|     - Feature flags                                          |
|     - Deployment configuration                               |
|                                                               |
+-------------------------------------------------------------+

Project Organization

myproject/
├── src/
│   └── myapp/
│       ├── __init__.py
│       │
│       ├── constants/              # Konstanten-Package
│       │   ├── __init__.py         # Public API exports
│       │   ├── app.py              # Application constants
│       │   ├── business.py         # Business logic constants
│       │   ├── ui.py               # UI-related constants
│       │   ├── files.py            # File paths, extensions
│       │   └── defaults.py         # Default values
│       │
│       ├── enums/                  # Enumerations
│       │   ├── __init__.py
│       │   ├── user.py             # User-related enums
│       │   ├── status.py           # Status enums
│       │   └── types.py            # Type enums
│       │
│       ├── config/                 # Configuration
│       │   ├── __init__.py
│       │   ├── settings.py         # Settings class
│       │   ├── development.py      # Dev config
│       │   ├── production.py       # Prod config
│       │   └── testing.py          # Test config
│       │
│       ├── messages/               # User-facing strings
│       │   ├── __init__.py
│       │   ├── errors.py           # Error messages
│       │   ├── notifications.py    # Notifications
│       │   ├── ui_text.py          # UI labels/tooltips
│       │   └── translations/       # i18n files
│       │       ├── en_US.json
│       │       └── de_DE.json
│       │
│       ├── models/
│       ├── views/
│       └── controllers/
├── config/                         # External config files
│   ├── app.toml
│   ├── logging.yaml
│   └── database.json
├── .env                            # Environment variables
├── .env.example                    # Template
└── pyproject.toml

Public API Export (constants/init.py)

"""
Constants package public API.

This module exports all constants used throughout the application.
Import from here, not from individual modules.

Example:
    >>> from myapp.constants import MAX_RETRIES, UserStatus
    >>> from myapp.constants import DEFAULT_TIMEOUT
"""

# Application constants
from myapp.constants.app import (
    APP_NAME,
    APP_VERSION,
    APP_AUTHOR,
    MAX_RETRIES,
    DEFAULT_TIMEOUT,
)

# Business logic constants
from myapp.constants.business import (
    BULK_DISCOUNT_THRESHOLD,
    BULK_DISCOUNT_RATE,
    MIN_ORDER_AMOUNT,
    TAX_RATE,
)

# UI constants
from myapp.constants.ui import (
    WINDOW_WIDTH,
    WINDOW_HEIGHT,
    ICON_SIZE,
    ANIMATION_DURATION,
)

# File constants
from myapp.constants.files import (
    DATA_DIR,
    BACKUP_DIR,
    EXPORT_DIR,
    ALLOWED_EXTENSIONS,
)

# Enums
from myapp.enums import (
    UserStatus,
    FileType,
    ProcessingState,
    ConnectionType,
)

__all__ = [
    # App
    'APP_NAME',
    'APP_VERSION',
    'APP_AUTHOR',
    'MAX_RETRIES',
    'DEFAULT_TIMEOUT',
    # Business
    'BULK_DISCOUNT_THRESHOLD',
    'BULK_DISCOUNT_RATE',
    'MIN_ORDER_AMOUNT',
    'TAX_RATE',
    # UI
    'WINDOW_WIDTH',
    'WINDOW_HEIGHT',
    'ICON_SIZE',
    'ANIMATION_DURATION',
    # Files
    'DATA_DIR',
    'BACKUP_DIR',
    'EXPORT_DIR',
    'ALLOWED_EXTENSIONS',
    # Enums
    'UserStatus',
    'FileType',
    'ProcessingState',
    'ConnectionType',
]

Application Constants

constants/app.py

"""
Core application constants.

These are fundamental constants used throughout the application
that rarely change.
"""

from pathlib import Path

# Application metadata
APP_NAME: str = "MyApp"
APP_VERSION: str = "1.0.0"
APP_AUTHOR: str = "Your Name"
APP_ORGANIZATION: str = "Your Organization"

# Network settings
MAX_RETRIES: int = 3
DEFAULT_TIMEOUT: int = 30  # seconds
CONNECT_TIMEOUT: int = 10  # seconds
READ_TIMEOUT: int = 30     # seconds

# Rate limiting
MAX_REQUESTS_PER_MINUTE: int = 60
RATE_LIMIT_WINDOW: int = 60  # seconds

# Pagination
DEFAULT_PAGE_SIZE: int = 50
MAX_PAGE_SIZE: int = 1000

# Validation
MIN_USERNAME_LENGTH: int = 3
MAX_USERNAME_LENGTH: int = 50
MIN_PASSWORD_LENGTH: int = 8
MAX_PASSWORD_LENGTH: int = 128

# Dates and times
DATE_FORMAT: str = "%Y-%m-%d"
TIME_FORMAT: str = "%H:%M:%S"
DATETIME_FORMAT: str = "%Y-%m-%d %H:%M:%S"
ISO_DATETIME_FORMAT: str = "%Y-%m-%dT%H:%M:%SZ"

# Encoding
DEFAULT_ENCODING: str = "utf-8"
FALLBACK_ENCODING: str = "latin-1"

constants/business.py

"""
Business logic constants.

Constants related to business rules and calculations.
"""

# Pricing
UNIT_PRICE: float = 9.99
BULK_DISCOUNT_THRESHOLD: int = 100
BULK_DISCOUNT_RATE: float = 0.10  # 10%
PREMIUM_DISCOUNT_RATE: float = 0.15  # 15%

# Tax rates (by region)
DEFAULT_TAX_RATE: float = 0.19  # 19%
EU_TAX_RATE: float = 0.20       # 20%
US_TAX_RATE: float = 0.08       # 8%

# Order processing
MIN_ORDER_AMOUNT: float = 10.0
MAX_ORDER_AMOUNT: float = 10000.0
FREE_SHIPPING_THRESHOLD: float = 50.0

# Inventory
LOW_STOCK_THRESHOLD: int = 10
REORDER_QUANTITY: int = 50

# Subscriptions
TRIAL_PERIOD_DAYS: int = 14
SUBSCRIPTION_GRACE_PERIOD_DAYS: int = 7

constants/ui.py

"""
UI-related constants.

Constants for window sizes, colors, animations, etc.
"""

# Window dimensions
WINDOW_WIDTH: int = 1024
WINDOW_HEIGHT: int = 768
MIN_WINDOW_WIDTH: int = 800
MIN_WINDOW_HEIGHT: int = 600

# Widget sizes
ICON_SIZE: int = 24
LARGE_ICON_SIZE: int = 48
BUTTON_HEIGHT: int = 32
TOOLBAR_HEIGHT: int = 40

# Spacing
DEFAULT_MARGIN: int = 10
DEFAULT_SPACING: int = 5
SECTION_SPACING: int = 20

# Animation
ANIMATION_DURATION: int = 250  # milliseconds
FADE_DURATION: int = 150
SLIDE_DURATION: int = 300

# Colors (as hex strings)
PRIMARY_COLOR: str = "#2196F3"
SECONDARY_COLOR: str = "#FFC107"
SUCCESS_COLOR: str = "#4CAF50"
WARNING_COLOR: str = "#FF9800"
ERROR_COLOR: str = "#F44336"
INFO_COLOR: str = "#00BCD4"

# Fonts
DEFAULT_FONT_FAMILY: str = "Segoe UI"
MONOSPACE_FONT_FAMILY: str = "Consolas"
DEFAULT_FONT_SIZE: int = 10
HEADER_FONT_SIZE: int = 14
TITLE_FONT_SIZE: int = 16

constants/files.py

"""
File and path-related constants.
"""

from pathlib import Path

# Base directories (relative to project root)
PROJECT_ROOT: Path = Path(__file__).parent.parent.parent
DATA_DIR: Path = PROJECT_ROOT / "data"
PERSISTENT_DATA_DIR: Path = DATA_DIR / "persistent_data"
APP_DATA_DIR: Path = DATA_DIR / ".app_data"

# Subdirectories
BACKUP_DIR: Path = PERSISTENT_DATA_DIR / "backups"
EXPORT_DIR: Path = PERSISTENT_DATA_DIR / "exports"
TEMP_DIR: Path = DATA_DIR / "temp"
LOG_DIR: Path = DATA_DIR / "logs"

# File extensions
PROJECT_FILE_EXTENSION: str = ".myproj"
BACKUP_FILE_EXTENSION: str = ".bak"
TEMP_FILE_EXTENSION: str = ".tmp"

# File name patterns
BACKUP_NAME_PATTERN: str = "backup_{timestamp}.json"
EXPORT_NAME_PATTERN: str = "export_{name}_{timestamp}.csv"
LOG_NAME_PATTERN: str = "{date}.log"

# Allowed file types
ALLOWED_EXTENSIONS: tuple[str, ...] = (
    ".json",
    ".xml",
    ".csv",
    ".txt",
)

ALLOWED_IMAGE_EXTENSIONS: tuple[str, ...] = (
    ".png",
    ".jpg",
    ".jpeg",
    ".gif",
    ".bmp",
)

# File size limits (in bytes)
MAX_FILE_SIZE: int = 10 * 1024 * 1024  # 10 MB
MAX_IMAGE_SIZE: int = 5 * 1024 * 1024   # 5 MB
MAX_LOG_SIZE: int = 50 * 1024 * 1024    # 50 MB

# Backup settings
MAX_BACKUP_COUNT: int = 10
BACKUP_RETENTION_DAYS: int = 30

Enumerations (Enums)

Why Enums Instead of Plain Strings?

# BAD - String constants
USER_STATUS_ACTIVE = "active"
USER_STATUS_INACTIVE = "inactive"
USER_STATUS_SUSPENDED = "suspended"

def check_user(status: str) -> bool:
    if status == "activ":  # Typo! No error at compile time
        return True
    return False

# GOOD - Enum
from enum import Enum

class UserStatus(Enum):
    ACTIVE = "active"
    INACTIVE = "inactive"
    SUSPENDED = "suspended"

def check_user(status: UserStatus) -> bool:
    if status == UserStatus.ACTIV:  # IDE warns immediately!
        return True
    return False

enums/user.py

"""User-related enumerations."""

from enum import Enum, auto


class UserStatus(Enum):
    """User account status."""
    ACTIVE = "active"
    INACTIVE = "inactive"
    SUSPENDED = "suspended"
    DELETED = "deleted"


class UserRole(Enum):
    """User role/permission level."""
    GUEST = "guest"
    USER = "user"
    MODERATOR = "moderator"
    ADMIN = "admin"
    SUPERADMIN = "superadmin"

    @property
    def level(self) -> int:
        """Get numeric permission level."""
        levels = {
            self.GUEST: 0,
            self.USER: 10,
            self.MODERATOR: 50,
            self.ADMIN: 90,
            self.SUPERADMIN: 100,
        }
        return levels[self]

    def can_access(self, required_level: "UserRole") -> bool:
        """Check if this role has sufficient permissions."""
        return self.level >= required_level.level


class SubscriptionTier(Enum):
    """Subscription tier."""
    FREE = "free"
    BASIC = "basic"
    PREMIUM = "premium"
    ENTERPRISE = "enterprise"

    @property
    def max_projects(self) -> int:
        """Get maximum allowed projects for this tier."""
        limits = {
            self.FREE: 3,
            self.BASIC: 10,
            self.PREMIUM: 50,
            self.ENTERPRISE: -1,  # Unlimited
        }
        return limits[self]

enums/status.py

"""Status and state enumerations."""

from enum import Enum, auto


class ProcessingState(Enum):
    """Processing state for async operations."""
    IDLE = auto()
    RUNNING = auto()
    PAUSED = auto()
    COMPLETED = auto()
    FAILED = auto()
    CANCELLED = auto()

    @property
    def is_active(self) -> bool:
        """Check if state represents active processing."""
        return self in (self.RUNNING, self.PAUSED)

    @property
    def is_terminal(self) -> bool:
        """Check if state is terminal (no further transitions)."""
        return self in (self.COMPLETED, self.FAILED, self.CANCELLED)


class FileStatus(Enum):
    """File operation status."""
    PENDING = "pending"
    UPLOADING = "uploading"
    PROCESSING = "processing"
    READY = "ready"
    ERROR = "error"


class ConnectionState(Enum):
    """Network connection state."""
    DISCONNECTED = auto()
    CONNECTING = auto()
    CONNECTED = auto()
    RECONNECTING = auto()
    ERROR = auto()

enums/types.py

"""Type classifications."""

from enum import Enum


class FileType(Enum):
    """File type classification."""
    DOCUMENT = "document"
    IMAGE = "image"
    VIDEO = "video"
    AUDIO = "audio"
    ARCHIVE = "archive"
    CODE = "code"
    DATA = "data"
    OTHER = "other"

    @classmethod
    def from_extension(cls, extension: str) -> "FileType":
        """Determine file type from extension."""
        ext = extension.lower().lstrip('.')

        if ext in ('jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg'):
            return cls.IMAGE
        elif ext in ('mp4', 'avi', 'mov', 'mkv'):
            return cls.VIDEO
        elif ext in ('mp3', 'wav', 'flac', 'ogg'):
            return cls.AUDIO
        elif ext in ('zip', 'rar', '7z', 'tar', 'gz'):
            return cls.ARCHIVE
        elif ext in ('py', 'js', 'java', 'cpp', 'html', 'css'):
            return cls.CODE
        elif ext in ('json', 'xml', 'csv', 'sql'):
            return cls.DATA
        elif ext in ('pdf', 'doc', 'docx', 'txt', 'md'):
            return cls.DOCUMENT
        else:
            return cls.OTHER


class LogLevel(Enum):
    """Logging level."""
    DEBUG = 10
    INFO = 20
    WARNING = 30
    ERROR = 40
    CRITICAL = 50

    def __lt__(self, other: "LogLevel") -> bool:
        """Enable comparison: LogLevel.DEBUG < LogLevel.INFO."""
        return self.value < other.value

Configuration Management

config/settings.py - Main Configuration Class

"""
Application configuration management.

This module provides a centralized configuration system with
environment-specific overrides.
"""

from dataclasses import dataclass, field
from pathlib import Path
from typing import Optional, Dict, Any
import os
import tomli  # pip install tomli


@dataclass
class DatabaseConfig:
    """Database configuration."""
    host: str = "localhost"
    port: int = 5432
    name: str = "myapp"
    user: str = "user"
    password: str = ""
    pool_size: int = 5


@dataclass
class APIConfig:
    """External API configuration."""
    base_url: str = "https://api.example.com"
    api_key: str = ""
    timeout: int = 30
    max_retries: int = 3


@dataclass
class LoggingConfig:
    """Logging configuration."""
    level: str = "INFO"
    file: Optional[Path] = None
    max_size: int = 10 * 1024 * 1024  # 10 MB
    backup_count: int = 5
    format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"


@dataclass
class Settings:
    """
    Application settings.

    Loads configuration from multiple sources in order of precedence:
    1. Environment variables (highest priority)
    2. Config file (TOML)
    3. Defaults (lowest priority)

    Example:
        >>> settings = Settings.load()
        >>> print(settings.app_name)
        'MyApp'
        >>> print(settings.database.host)
        'localhost'
    """

    # Application
    app_name: str = "MyApp"
    app_version: str = "1.0.0"
    environment: str = "development"  # development, staging, production
    debug: bool = False

    # Paths
    data_dir: Path = field(default_factory=lambda: Path("data"))
    log_dir: Path = field(default_factory=lambda: Path("logs"))

    # Sub-configs
    database: DatabaseConfig = field(default_factory=DatabaseConfig)
    api: APIConfig = field(default_factory=APIConfig)
    logging: LoggingConfig = field(default_factory=LoggingConfig)

    # Feature flags
    enable_auto_save: bool = True
    enable_telemetry: bool = False
    enable_experimental_features: bool = False

    @classmethod
    def load(cls, config_file: Optional[Path] = None) -> "Settings":
        """
        Load settings from config file and environment.

        Args:
            config_file: Optional path to TOML config file.
                Defaults to 'config/app.toml'.

        Returns:
            Loaded settings instance.
        """
        if config_file is None:
            config_file = Path("config/app.toml")

        # Load from file
        settings_dict = {}
        if config_file.exists():
            with open(config_file, 'rb') as f:
                settings_dict = tomli.load(f)

        # Override from environment
        settings_dict = cls._apply_env_overrides(settings_dict)

        # Create instance
        return cls(**settings_dict)

    @staticmethod
    def _apply_env_overrides(config: Dict[str, Any]) -> Dict[str, Any]:
        """Apply environment variable overrides."""
        # Example: MYAPP_DEBUG=true → debug = True
        # Example: MYAPP_DATABASE_HOST=prod-db → database.host = "prod-db"

        if debug_env := os.getenv("MYAPP_DEBUG"):
            config['debug'] = debug_env.lower() == "true"

        if db_host := os.getenv("MYAPP_DATABASE_HOST"):
            config.setdefault('database', {})['host'] = db_host

        if api_key := os.getenv("MYAPP_API_KEY"):
            config.setdefault('api', {})['api_key'] = api_key

        return config

    def save(self, config_file: Path) -> None:
        """Save current settings to TOML file."""
        import tomli_w  # pip install tomli-w

        with open(config_file, 'wb') as f:
            tomli_w.dump(self.__dict__, f)


# Global settings instance (singleton pattern)
_settings: Optional[Settings] = None


def get_settings() -> Settings:
    """
    Get global settings instance.

    Returns:
        Settings instance (singleton).

    Example:
        >>> from myapp.config import get_settings
        >>> settings = get_settings()
        >>> print(settings.app_name)
    """
    global _settings
    if _settings is None:
        _settings = Settings.load()
    return _settings


def reload_settings() -> Settings:
    """
    Reload settings from file (useful for testing).

    Returns:
        Reloaded settings instance.
    """
    global _settings
    _settings = Settings.load()
    return _settings

config/app.toml - Configuration File

# Application Configuration

[app]
name = "MyApp"
version = "1.0.0"
environment = "development"
debug = true

[paths]
data_dir = "data"
log_dir = "logs"

[database]
host = "localhost"
port = 5432
name = "myapp_dev"
user = "devuser"
password = ""
pool_size = 5

[api]
base_url = "https://api.example.com"
api_key = ""  # Set via environment variable
timeout = 30
max_retries = 3

[logging]
level = "DEBUG"
file = "logs/app.log"
max_size = 10485760  # 10 MB
backup_count = 5

[features]
enable_auto_save = true
enable_telemetry = false
enable_experimental_features = true

Environment-Specific Configs

# config/development.py
"""Development environment configuration."""

from myapp.config.settings import Settings

def get_dev_settings() -> Settings:
    """Get development settings."""
    settings = Settings()
    settings.environment = "development"
    settings.debug = True
    settings.database.name = "myapp_dev"
    settings.logging.level = "DEBUG"
    settings.enable_telemetry = False
    return settings


# config/production.py
"""Production environment configuration."""

from myapp.config.settings import Settings

def get_prod_settings() -> Settings:
    """Get production settings."""
    settings = Settings()
    settings.environment = "production"
    settings.debug = False
    settings.database.host = "prod-db.example.com"
    settings.logging.level = "WARNING"
    settings.enable_telemetry = True
    return settings

User-Facing Strings (i18n)

messages/errors.py

"""
Error messages.

Centralized error messages for consistent user communication.
"""

# Validation errors
ERROR_EMPTY_FIELD: str = "This field cannot be empty."
ERROR_INVALID_EMAIL: str = "Please enter a valid email address."
ERROR_INVALID_PASSWORD: str = "Password must be at least 8 characters."
ERROR_PASSWORD_MISMATCH: str = "Passwords do not match."
ERROR_USERNAME_TAKEN: str = "This username is already taken."

# File operation errors
ERROR_FILE_NOT_FOUND: str = "The file could not be found."
ERROR_FILE_READ: str = "Failed to read file: {filename}"
ERROR_FILE_WRITE: str = "Failed to write file: {filename}"
ERROR_FILE_PERMISSION: str = "Permission denied: {filename}"
ERROR_FILE_TOO_LARGE: str = "File is too large. Maximum size: {max_size} MB"

# Network errors
ERROR_CONNECTION_FAILED: str = "Failed to connect to server."
ERROR_TIMEOUT: str = "Request timed out. Please try again."
ERROR_NO_INTERNET: str = "No internet connection detected."

# Authentication errors
ERROR_LOGIN_FAILED: str = "Invalid username or password."
ERROR_SESSION_EXPIRED: str = "Your session has expired. Please log in again."
ERROR_UNAUTHORIZED: str = "You don't have permission to perform this action."

# Business logic errors
ERROR_INSUFFICIENT_FUNDS: str = "Insufficient funds for this transaction."
ERROR_INVALID_QUANTITY: str = "Quantity must be greater than zero."
ERROR_ITEM_NOT_AVAILABLE: str = "This item is no longer available."


def format_error(template: str, **kwargs) -> str:
    """
    Format error message with parameters.

    Args:
        template: Error message template with placeholders.
        **kwargs: Values to substitute into template.

    Returns:
        Formatted error message.

    Example:
        >>> format_error(ERROR_FILE_READ, filename="data.json")
        'Failed to read file: data.json'
    """
    return template.format(**kwargs)

messages/notifications.py

"""
Notification messages.

User-facing notification messages.
"""

# Success notifications
SUCCESS_SAVED: str = "Saved successfully."
SUCCESS_DELETED: str = "{item} has been deleted."
SUCCESS_UPLOADED: str = "File uploaded successfully."
SUCCESS_SENT: str = "Message sent."

# Info notifications
INFO_LOADING: str = "Loading..."
INFO_PROCESSING: str = "Processing your request..."
INFO_SYNCING: str = "Synchronizing data..."
INFO_NO_CHANGES: str = "No changes to save."

# Warning notifications
WARNING_UNSAVED_CHANGES: str = "You have unsaved changes."
WARNING_LOW_STORAGE: str = "Storage space is running low."
WARNING_OFFLINE_MODE: str = "You are currently in offline mode."

# Action confirmations
CONFIRM_DELETE: str = "Are you sure you want to delete {item}?"
CONFIRM_DISCARD: str = "Discard unsaved changes?"
CONFIRM_LOGOUT: str = "Are you sure you want to log out?"
CONFIRM_RESET: str = "This will reset all settings. Continue?"

messages/ui_text.py

"""
UI text labels and tooltips.

All user-interface text in one place for easy localization.
"""

# Main menu
MENU_FILE: str = "&File"
MENU_EDIT: str = "&Edit"
MENU_VIEW: str = "&View"
MENU_HELP: str = "&Help"

# File menu items
ACTION_NEW: str = "&New"
ACTION_OPEN: str = "&Open..."
ACTION_SAVE: str = "&Save"
ACTION_SAVE_AS: str = "Save &As..."
ACTION_EXPORT: str = "&Export..."
ACTION_QUIT: str = "&Quit"

# Edit menu items
ACTION_UNDO: str = "&Undo"
ACTION_REDO: str = "&Redo"
ACTION_CUT: str = "Cu&t"
ACTION_COPY: str = "&Copy"
ACTION_PASTE: str = "&Paste"

# Buttons
BUTTON_OK: str = "OK"
BUTTON_CANCEL: str = "Cancel"
BUTTON_APPLY: str = "Apply"
BUTTON_CLOSE: str = "Close"
BUTTON_YES: str = "Yes"
BUTTON_NO: str = "No"
BUTTON_SAVE: str = "Save"
BUTTON_DELETE: str = "Delete"

# Tooltips
TOOLTIP_NEW_PROJECT: str = "Create a new project (Ctrl+N)"
TOOLTIP_OPEN_PROJECT: str = "Open an existing project (Ctrl+O)"
TOOLTIP_SAVE_PROJECT: str = "Save the current project (Ctrl+S)"
TOOLTIP_UNDO: str = "Undo last action (Ctrl+Z)"
TOOLTIP_REDO: str = "Redo last action (Ctrl+Y)"

# Status messages
STATUS_READY: str = "Ready"
STATUS_SAVING: str = "Saving..."
STATUS_LOADING: str = "Loading..."
STATUS_CONNECTED: str = "Connected"
STATUS_DISCONNECTED: str = "Disconnected"

Internationalization (i18n) Setup

# messages/i18n.py
"""
Internationalization support.

Provides translation capabilities for all user-facing strings.
"""

import json
from pathlib import Path
from typing import Dict, Optional

# Current language
_current_language: str = "en_US"
_translations: Dict[str, Dict[str, str]] = {}


def load_translation(language: str) -> None:
    """
    Load translation file for specified language.

    Args:
        language: Language code (e.g., 'de_DE', 'en_US').
    """
    global _current_language, _translations

    translation_file = Path(__file__).parent / "translations" / f"{language}.json"

    if translation_file.exists():
        with open(translation_file, 'r', encoding='utf-8') as f:
            _translations[language] = json.load(f)
        _current_language = language
    else:
        raise FileNotFoundError(f"Translation file not found: {translation_file}")


def t(key: str, **kwargs) -> str:
    """
    Translate a string key.

    Args:
        key: Translation key.
        **kwargs: Format parameters.

    Returns:
        Translated string, or key if translation not found.

    Example:
        >>> t("error.file_not_found")
        'Die Datei wurde nicht gefunden.'
        >>> t("error.file_read", filename="data.json")
        'Fehler beim Lesen der Datei: data.json'
    """
    translation = _translations.get(_current_language, {}).get(key, key)
    return translation.format(**kwargs) if kwargs else translation


def get_current_language() -> str:
    """Get current language code."""
    return _current_language


# Convenience: Load default language
try:
    load_translation("en_US")
except FileNotFoundError:
    pass  # Fallback to keys

translations/de_DE.json:

{
  "error.empty_field": "Dieses Feld darf nicht leer sein.",
  "error.invalid_email": "Bitte geben Sie eine gültige E-Mail-Adresse ein.",
  "error.file_not_found": "Die Datei wurde nicht gefunden.",
  "error.file_read": "Fehler beim Lesen der Datei: {filename}",
  "success.saved": "Erfolgreich gespeichert.",
  "button.ok": "OK",
  "button.cancel": "Abbrechen",
  "menu.file": "&Datei",
  "menu.edit": "&Bearbeiten"
}


Environment-Specific Values

.env - Environment Variables

# .env file (never commit to git!)

# Environment
MYAPP_ENVIRONMENT=production
MYAPP_DEBUG=false

# Database
MYAPP_DATABASE_HOST=prod-db.example.com
MYAPP_DATABASE_PORT=5432
MYAPP_DATABASE_NAME=myapp_prod
MYAPP_DATABASE_USER=prod_user
MYAPP_DATABASE_PASSWORD=super_secret_password

# API Keys (sensitive!)
MYAPP_API_KEY=sk_live_abc123def456
MYAPP_SECRET_KEY=secret_xyz789

# External Services
MYAPP_REDIS_URL=redis://localhost:6379
MYAPP_SMTP_HOST=smtp.gmail.com
MYAPP_SMTP_PORT=587
MYAPP_SMTP_USER=no-reply@example.com
MYAPP_SMTP_PASSWORD=email_password

# Feature Flags
MYAPP_ENABLE_TELEMETRY=true
MYAPP_ENABLE_BETA_FEATURES=false

# Logging
MYAPP_LOG_LEVEL=INFO

.env.example - Template (commit this)

# .env.example - Copy to .env and fill in values

# Environment
MYAPP_ENVIRONMENT=development
MYAPP_DEBUG=true

# Database
MYAPP_DATABASE_HOST=localhost
MYAPP_DATABASE_PORT=5432
MYAPP_DATABASE_NAME=myapp_dev
MYAPP_DATABASE_USER=devuser
MYAPP_DATABASE_PASSWORD=

# API Keys
MYAPP_API_KEY=
MYAPP_SECRET_KEY=

# External Services
MYAPP_REDIS_URL=redis://localhost:6379
MYAPP_SMTP_HOST=
MYAPP_SMTP_PORT=587
MYAPP_SMTP_USER=
MYAPP_SMTP_PASSWORD=

# Feature Flags
MYAPP_ENABLE_TELEMETRY=false
MYAPP_ENABLE_BETA_FEATURES=false

# Logging
MYAPP_LOG_LEVEL=DEBUG

Loading Environment Variables

# utils/env.py
"""
Environment variable utilities.
"""

import os
from pathlib import Path
from typing import Optional, TypeVar, Type
from dotenv import load_dotenv  # pip install python-dotenv

T = TypeVar('T')


def load_env_file(env_file: Path = Path(".env")) -> None:
    """
    Load environment variables from .env file.

    Args:
        env_file: Path to .env file.
    """
    if env_file.exists():
        load_dotenv(env_file)


def get_env(key: str, default: Optional[str] = None) -> Optional[str]:
    """
    Get environment variable.

    Args:
        key: Environment variable name.
        default: Default value if not found.

    Returns:
        Environment variable value or default.
    """
    return os.getenv(key, default)


def get_env_bool(key: str, default: bool = False) -> bool:
    """
    Get boolean environment variable.

    Args:
        key: Environment variable name.
        default: Default value if not found.

    Returns:
        Boolean value.
    """
    value = get_env(key)
    if value is None:
        return default
    return value.lower() in ('true', '1', 'yes', 'on')


def get_env_int(key: str, default: int = 0) -> int:
    """
    Get integer environment variable.

    Args:
        key: Environment variable name.
        default: Default value if not found.

    Returns:
        Integer value.
    """
    value = get_env(key)
    if value is None:
        return default
    try:
        return int(value)
    except ValueError:
        return default


def require_env(key: str) -> str:
    """
    Get required environment variable.

    Args:
        key: Environment variable name.

    Returns:
        Environment variable value.

    Raises:
        ValueError: If environment variable is not set.
    """
    value = get_env(key)
    if value is None:
        raise ValueError(f"Required environment variable not set: {key}")
    return value

PySide6-Specific Patterns

Using Qt Constants

# constants/qt_constants.py
"""
PySide6/Qt-specific constants.
"""

from PySide6.QtCore import Qt, QSize
from PySide6.QtGui import QColor, QFont

# Window flags (for custom dialogs)
DIALOG_FLAGS = (
    Qt.WindowType.Dialog |
    Qt.WindowType.WindowCloseButtonHint |
    Qt.WindowType.WindowTitleHint
)

FRAMELESS_WINDOW_FLAGS = (
    Qt.WindowType.FramelessWindowHint |
    Qt.WindowType.WindowStaysOnTopHint
)

# Alignment
ALIGN_CENTER = Qt.AlignmentFlag.AlignCenter
ALIGN_LEFT = Qt.AlignmentFlag.AlignLeft
ALIGN_RIGHT = Qt.AlignmentFlag.AlignRight
ALIGN_TOP = Qt.AlignmentFlag.AlignTop

# Icon sizes
ICON_SIZE_SMALL = QSize(16, 16)
ICON_SIZE_MEDIUM = QSize(24, 24)
ICON_SIZE_LARGE = QSize(48, 48)

# Colors (QColor objects)
COLOR_PRIMARY = QColor("#2196F3")
COLOR_SUCCESS = QColor("#4CAF50")
COLOR_WARNING = QColor("#FF9800")
COLOR_ERROR = QColor("#F44336")

# Fonts
FONT_DEFAULT = QFont("Segoe UI", 10)
FONT_HEADER = QFont("Segoe UI", 14, QFont.Weight.Bold)
FONT_MONOSPACE = QFont("Consolas", 10)

# Connection types (for explicit signal connections)
from PySide6.QtCore import Qt

CONNECTION_AUTO = Qt.ConnectionType.AutoConnection
CONNECTION_DIRECT = Qt.ConnectionType.DirectConnection
CONNECTION_QUEUED = Qt.ConnectionType.QueuedConnection
CONNECTION_BLOCKING = Qt.ConnectionType.BlockingQueuedConnection

Stylesheets as Constants

# constants/stylesheets.py
"""
Qt stylesheet constants.

Centralized stylesheets for consistent styling.
"""

# Base styles
STYLE_PRIMARY_BUTTON = """
QPushButton {
    background-color: #2196F3;
    color: white;
    border: none;
    border-radius: 4px;
    padding: 8px 16px;
    font-size: 10pt;
}
QPushButton:hover {
    background-color: #1976D2;
}
QPushButton:pressed {
    background-color: #0D47A1;
}
QPushButton:disabled {
    background-color: #BBDEFB;
    color: #90CAF9;
}
"""

STYLE_SECONDARY_BUTTON = """
QPushButton {
    background-color: white;
    color: #2196F3;
    border: 2px solid #2196F3;
    border-radius: 4px;
    padding: 8px 16px;
}
QPushButton:hover {
    background-color: #E3F2FD;
}
"""

STYLE_SUCCESS_LABEL = """
QLabel {
    color: #4CAF50;
    font-weight: bold;
}
"""

STYLE_ERROR_LABEL = """
QLabel {
    color: #F44336;
    font-weight: bold;
}
"""

# Complete widget styles
STYLE_MAIN_WINDOW = """
QMainWindow {
    background-color: #FAFAFA;
}
"""

STYLE_TOOLBAR = """
QToolBar {
    background-color: white;
    border-bottom: 1px solid #E0E0E0;
    spacing: 5px;
}
"""


def get_stylesheet(name: str) -> str:
    """
    Get stylesheet by name.

    Args:
        name: Stylesheet name (without STYLE_ prefix).

    Returns:
        Stylesheet string.

    Example:
        >>> button.setStyleSheet(get_stylesheet("PRIMARY_BUTTON"))
    """
    return globals().get(f"STYLE_{name.upper()}", "")

Usage in Views

# views/main_window.py
from PySide6.QtWidgets import QMainWindow, QPushButton
from myapp.constants.qt_constants import (
    DIALOG_FLAGS,
    ICON_SIZE_MEDIUM,
    COLOR_PRIMARY,
)
from myapp.constants.stylesheets import STYLE_PRIMARY_BUTTON


class MainWindow(QMainWindow):
    """Main application window."""

    def __init__(self):
        super().__init__()
        self._setup_ui()

    def _setup_ui(self):
        """Setup user interface."""
        self.setWindowFlags(DIALOG_FLAGS)

        # Button with constant stylesheet
        self.save_button = QPushButton("Save")
        self.save_button.setStyleSheet(STYLE_PRIMARY_BUTTON)
        self.save_button.setIconSize(ICON_SIZE_MEDIUM)

Best Practices

1. Naming Conventions

# ✅ GOOD - Clear naming
MAX_RETRY_ATTEMPTS = 3          # Constant: UPPERCASE_WITH_UNDERSCORES
DEFAULT_TIMEOUT_SECONDS = 30
ERROR_MESSAGE_TEMPLATE = "Failed to {action}: {reason}"

class UserStatus(Enum):         # Enum class: CapWords
    ACTIVE = "active"           # Enum members: UPPERCASE

# ❌ BAD - Unclear naming
max_retries = 3                 # Looks like a variable
timeout = 30                    # No unit
msg = "Error: {0}"             # Abbreviated, unclear

2. Group by Context

# ✅ GOOD - Grouped by context
# Network timeouts (seconds)
CONNECT_TIMEOUT = 10
READ_TIMEOUT = 30
WRITE_TIMEOUT = 30

# File size limits (bytes)
MAX_FILE_SIZE = 10 * 1024 * 1024
MAX_IMAGE_SIZE = 5 * 1024 * 1024
MAX_VIDEO_SIZE = 100 * 1024 * 1024

# ❌ BAD - Mixed topics
MAX_SIZE = 10000000
TIMEOUT = 30
MAX_IMG = 5000000
CONNECT = 10

3. Document Units

# ✅ GOOD - Units in name or comment
REQUEST_TIMEOUT_SECONDS = 30
FILE_SIZE_LIMIT_MB = 10
CACHE_TTL_MINUTES = 60

# Or with comments
MAX_RETRIES = 3               # Number of retry attempts
DEFAULT_TIMEOUT = 30.0        # Timeout in seconds
BUFFER_SIZE = 8192            # Buffer size in bytes

# ❌ BAD - Ambiguous units
TIMEOUT = 30                  # Seconds? Milliseconds?
MAX_SIZE = 10                 # Bytes? KB? MB?

4. Avoid Duplication

# ✅ GOOD - Calculated from base constants
BYTES_PER_KB = 1024
BYTES_PER_MB = BYTES_PER_KB * 1024
BYTES_PER_GB = BYTES_PER_MB * 1024

MAX_FILE_SIZE_MB = 10
MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * BYTES_PER_MB

# ❌ BAD - Duplicated values
MAX_FILE_SIZE_MB = 10
MAX_FILE_SIZE_BYTES = 10485760  # Magic number! Duplicate!

5. Type Safety with Enums

# ✅ GOOD - Type-safe with Enum
from enum import Enum

class ConnectionType(Enum):
    WIFI = "wifi"
    ETHERNET = "ethernet"
    CELLULAR = "cellular"

def connect(connection_type: ConnectionType) -> bool:
    if connection_type == ConnectionType.WIFI:  # IDE autocomplete!
        return setup_wifi()
    # ...

# ❌ BAD - String constants (typo-prone)
CONN_WIFI = "wifi"
CONN_ETHERNET = "ethernet"

def connect(connection_type: str) -> bool:
    if connection_type == "wiffi":  # Typo! No error!
        return setup_wifi()

6. Default Values in Functions

# ✅ GOOD - Reference constant
from myapp.constants import DEFAULT_TIMEOUT

def fetch_data(url: str, timeout: int = DEFAULT_TIMEOUT) -> bytes:
    """Fetch data with configurable timeout."""
    # If DEFAULT_TIMEOUT changes, all functions update automatically
    pass

# ❌ BAD - Duplicate magic number
def fetch_data(url: str, timeout: int = 30) -> bytes:
    pass

def fetch_json(url: str, timeout: int = 30) -> dict:
    pass
# Now you need to change 30 in multiple places!

7. Configurable vs. Fixed Constants

# constants/app.py - Fixed constants
APP_NAME = "MyApp"                    # Never changes
MIN_PASSWORD_LENGTH = 8               # Business rule

# config/settings.py - Configurable values
@dataclass
class Settings:
    max_retries: int = 3              # User can configure
    timeout: int = 30                 # Environment-specific
    debug: bool = False               # Deployment-specific

Refactoring Strategy

Step 1: Identify

# Script to find magic numbers
import ast
import sys

class MagicNumberFinder(ast.NodeVisitor):
    """Find potential magic numbers in code."""

    def visit_Num(self, node):
        # Ignore obvious constants
        if node.n not in (0, 1, -1, 2, 10, 100, 1000):
            print(f"Line {node.lineno}: {node.n}")
        self.generic_visit(node)

# Usage: python find_magic_numbers.py myfile.py

Step 2: Incremental Refactoring

# BEFORE
def validate_password(password: str) -> bool:
    if len(password) < 8:  # Magic number!
        return False
    return True

def create_account(username: str, password: str) -> bool:
    if len(password) < 8:  # Duplicate magic number!
        raise ValueError("Password too short")
    # ...

# STEP 1: Extract constant
MIN_PASSWORD_LENGTH = 8  # Local constant

def validate_password(password: str) -> bool:
    if len(password) < MIN_PASSWORD_LENGTH:
        return False
    return True

# STEP 2: Move to constants module
from myapp.constants import MIN_PASSWORD_LENGTH

def validate_password(password: str) -> bool:
    if len(password) < MIN_PASSWORD_LENGTH:
        return False
    return True

def create_account(username: str, password: str) -> bool:
    if len(password) < MIN_PASSWORD_LENGTH:
        raise ValueError("Password too short")
    # ...

Step 3: Testing

# tests/test_constants.py
"""Test that constants are used correctly."""

import pytest
from myapp.constants import MIN_PASSWORD_LENGTH

def test_min_password_length_enforced():
    """Verify password length is enforced."""
    from myapp.auth import validate_password

    # Test with exact minimum length
    assert validate_password("a" * MIN_PASSWORD_LENGTH)

    # Test with one less than minimum
    assert not validate_password("a" * (MIN_PASSWORD_LENGTH - 1))

Complete Example: Order Processing

# constants/business.py
"""Business logic constants for order processing."""

# Pricing
BASE_PRICE_PER_UNIT = 9.99
BULK_ORDER_THRESHOLD = 100
BULK_DISCOUNT_RATE = 0.10
PREMIUM_DISCOUNT_RATE = 0.15

# Shipping
FREE_SHIPPING_THRESHOLD = 50.0
STANDARD_SHIPPING_COST = 5.99
EXPRESS_SHIPPING_COST = 12.99

# Limits
MIN_ORDER_QUANTITY = 1
MAX_ORDER_QUANTITY = 1000
MIN_ORDER_AMOUNT = 10.0

# Tax rates by region
TAX_RATE_DEFAULT = 0.19
TAX_RATE_EU = 0.20
TAX_RATE_US = 0.08


# enums/order.py
"""Order-related enumerations."""

from enum import Enum

class OrderStatus(Enum):
    """Order processing status."""
    PENDING = "pending"
    CONFIRMED = "confirmed"
    PROCESSING = "processing"
    SHIPPED = "shipped"
    DELIVERED = "delivered"
    CANCELLED = "cancelled"

class ShippingMethod(Enum):
    """Shipping method."""
    STANDARD = "standard"
    EXPRESS = "express"
    PICKUP = "pickup"

    @property
    def cost(self) -> float:
        """Get shipping cost."""
        from myapp.constants.business import (
            STANDARD_SHIPPING_COST,
            EXPRESS_SHIPPING_COST,
        )

        costs = {
            self.STANDARD: STANDARD_SHIPPING_COST,
            self.EXPRESS: EXPRESS_SHIPPING_COST,
            self.PICKUP: 0.0,
        }
        return costs[self]


# models/order.py
"""Order processing logic."""

from typing import List
from myapp.constants.business import (
    BASE_PRICE_PER_UNIT,
    BULK_ORDER_THRESHOLD,
    BULK_DISCOUNT_RATE,
    PREMIUM_DISCOUNT_RATE,
    FREE_SHIPPING_THRESHOLD,
    MIN_ORDER_QUANTITY,
    MAX_ORDER_QUANTITY,
    TAX_RATE_DEFAULT,
)
from myapp.enums.order import OrderStatus, ShippingMethod


class Order:
    """Order with professional constant usage."""

    def __init__(self, quantity: int, is_premium: bool = False):
        if quantity < MIN_ORDER_QUANTITY:
            raise ValueError(f"Minimum quantity is {MIN_ORDER_QUANTITY}")
        if quantity > MAX_ORDER_QUANTITY:
            raise ValueError(f"Maximum quantity is {MAX_ORDER_QUANTITY}")

        self.quantity = quantity
        self.is_premium = is_premium
        self.status = OrderStatus.PENDING
        self.shipping_method = ShippingMethod.STANDARD

    def calculate_subtotal(self) -> float:
        """Calculate subtotal before discounts."""
        return self.quantity * BASE_PRICE_PER_UNIT

    def calculate_discount(self) -> float:
        """Calculate applicable discount."""
        subtotal = self.calculate_subtotal()

        # Premium discount
        if self.is_premium:
            return subtotal * PREMIUM_DISCOUNT_RATE

        # Bulk discount
        if self.quantity >= BULK_ORDER_THRESHOLD:
            return subtotal * BULK_DISCOUNT_RATE

        return 0.0

    def calculate_shipping(self) -> float:
        """Calculate shipping cost."""
        subtotal = self.calculate_subtotal()

        # Free shipping for large orders
        if subtotal >= FREE_SHIPPING_THRESHOLD:
            return 0.0

        return self.shipping_method.cost

    def calculate_total(self) -> float:
        """Calculate final total with all adjustments."""
        subtotal = self.calculate_subtotal()
        discount = self.calculate_discount()
        shipping = self.calculate_shipping()
        tax = (subtotal - discount) * TAX_RATE_DEFAULT

        return subtotal - discount + shipping + tax

Tool Support

VS Code Extension: Better Comments

# ! Critical constant - do not change without review
MAX_RETRIES = 3

# ? Consider making this configurable
DEFAULT_TIMEOUT = 30

# TODO: Move to config file
API_URL = "https://api.example.com"

# * Important: Used in multiple modules
MIN_PASSWORD_LENGTH = 8

Pre-commit Hook: Check for Magic Numbers

# scripts/check_magic_numbers.py
"""Check for potential magic numbers in staged files."""

import ast
import sys

ALLOWED_NUMBERS = {0, 1, -1, 2, 10, 100, 1000}

def check_file(filepath):
    with open(filepath) as f:
        tree = ast.parse(f.read())

    issues = []
    for node in ast.walk(tree):
        if isinstance(node, ast.Num):
            if node.n not in ALLOWED_NUMBERS:
                issues.append((node.lineno, node.n))

    return issues

if __name__ == "__main__":
    # Check staged Python files
    pass

Summary

Decision Matrix

Scenario Solution
Business rule (discount rate) constants/business.py
Status value (pending, active) enums/status.py with Enum
UI dimensions (window size) constants/ui.py
Environment-specific (API URL) config/settings.py + .env
Secret (API key) .env file ONLY
User message messages/errors.py
File path constants/files.py
Feature flag config/settings.py

Key Takeaways

  1. ✅ Always use named constants instead of magic numbers/strings
  2. ✅ Organize by context (business, ui, files, etc.)
  3. ✅ Use Enums for type safety when values form a set
  4. ✅ Separate configuration from constants
  5. ✅ Never commit secrets - use environment variables
  6. ✅ Document units in names or comments
  7. ✅ Calculate derived values from base constants
  8. ✅ Centralize user-facing strings for i18n
  9. ✅ Test constant usage in critical code
  10. ✅ Refactor gradually - don't do everything at once

Professional code uses NO magic numbers. Every value has a name and a reason.