Article 8: Documentation Best Practices

Introduction

Documentation is often treated as an afterthought, but it's a critical part of professional software development. Through maintaining projects over years, I've learned that good documentation is what makes the difference between a usable project and an abandoned one.

This article covers documentation best practices, from inline docstrings to comprehensive README files and API documentation.

Why Documentation Matters

spinner

Good documentation:

  • Reduces onboarding time - New team members get up to speed faster

  • Enables self-service - Users answer their own questions

  • Preserves knowledge - Capture decisions and context

  • Improves code quality - Writing docs forces clearer thinking

Docstrings

PEP 257 Standards

def calculate_discount(price: Decimal, discount_rate: float) -> Decimal:
    """
    Calculate the discounted price.

    Applies a percentage discount to the original price and returns
    the final amount after discount.

    Args:
        price: The original price before discount.
        discount_rate: The discount as a decimal (e.g., 0.10 for 10%).

    Returns:
        The price after applying the discount.

    Raises:
        ValueError: If discount_rate is negative or greater than 1.

    Examples:
        >>> calculate_discount(Decimal("100.00"), 0.10)
        Decimal('90.00')
        >>> calculate_discount(Decimal("50.00"), 0.25)
        Decimal('37.50')
    """
    if not 0 <= discount_rate <= 1:
        raise ValueError(f"discount_rate must be between 0 and 1, got {discount_rate}")
    
    discount = price * Decimal(str(discount_rate))
    return price - discount

Google Style Docstrings

Class Docstrings

Module Docstrings

README Files

README Structure

Installation

Detailed installation instructions including prerequisites.

Usage

More comprehensive usage examples and common scenarios.

Configuration

Available configuration options and how to set them.

API Reference

Link to full API documentation or key endpoints.

Contributing

How to contribute to the project.

License

License information.

Installation

Requirements

  • Python 3.11 or higher

  • pip or pipx

Install via pip

Install from source

Usage

Creating Tasks

Listing Tasks

Managing Tasks

Configuration

Task Manager CLI uses a configuration file at ~/.config/task-manager/config.toml.

Environment Variables

Variable
Description
Default

TASK_MANAGER_DB

Database path

~/.local/share/task-manager/tasks.db

TASK_MANAGER_CONFIG

Config file path

~/.config/task-manager/config.toml

NO_COLOR

Disable colors

Not set

Development

Setup

Running Tests

Code Quality

Contributing

Contributions are welcome! Please see CONTRIBUTING.mdarrow-up-right for guidelines.

  1. Fork the repository

  2. Create a feature branch (git checkout -b feature/amazing-feature)

  3. Commit your changes (git commit -m 'Add amazing feature')

  4. Push to the branch (git push origin feature/amazing-feature)

  5. Open a Pull Request

License

This project is licensed under the MIT License - see LICENSEarrow-up-right for details.

Acknowledgments

MkDocs with mkdocstrings

Inline API Documentation

Keeping Documentation Updated

Documentation as Code

Doctest for Verified Examples

Pre-commit Documentation Checks

Documentation Patterns

Architecture Decision Records (ADRs)

Changelog

Contributing Guide

Code Style

  • Follow PEP 8

  • Use type hints

  • Write docstrings for public functions

  • Keep functions small and focused

Testing

  • Write tests for all new features

  • Maintain test coverage above 80%

  • Run pytest before submitting PR

Documentation

  • Update docstrings for API changes

  • Update README for user-facing changes

  • Add entries to CHANGELOG.md

Exercise 2: Create a README

Create a README for a hypothetical URL shortener project:

  • Name: ShortLink

  • Features: Shorten URLs, custom aliases, click tracking

  • Tech: Python, FastAPI, Redis

  • Installation, usage, configuration sections

Documentation Checklist

Use this checklist for projects:

Key Takeaways

  1. Write docstrings first - They help clarify your design

  2. README is your landing page - Make it welcoming and clear

  3. Keep docs with code - Documentation as code stays updated

  4. Automate verification - Use doctests and CI checks

  5. Document decisions - ADRs preserve context for future

What's Next?

With well-documented code, let's focus on handling the unexpected. In Article 9: Error Handling and Logging, we'll cover exception handling, structured logging, and debugging strategies.


This article is part of the Software Engineering 101 series.

Last updated