Key Takeaways — Chapter 39: Python Best Practices and Collaborative Development

Version Control with Git

Git tracks your code history and enables collaboration. The three-step commit workflow:

git add .                          # Stage changes
git commit -m "Descriptive message"  # Snapshot with context
git push origin main               # Upload to remote

The GitHub branch-and-PR workflow for team development:

git checkout -b feature/your-feature  # Isolated branch
# ... develop ...
git push origin feature/your-feature  # Push branch
# Open Pull Request on GitHub → Code Review → Merge

Always write meaningful commit messages. "Fix gross margin to handle zero-revenue rows" tells a story. "fix" tells nothing.


The .gitignore Contract

Never commit these:

venv/              # Virtual environment
.env               # API keys, passwords
__pycache__/       # Python cache
*.pyc              # Compiled Python
data/raw/          # Real data files (often sensitive)

Always commit these: requirements.txt, README.md, tests/, source code.


Testing with pytest

A test is a function that calls your code and asserts the output is correct:

import pytest
from business_math import calculate_gross_margin

def test_gross_margin_standard():
    result = calculate_gross_margin(100_000, 65_000)
    assert result == pytest.approx(0.35, rel=1e-6)

def test_gross_margin_zero_revenue():
    assert calculate_gross_margin(0, 50_000) == 0.0  # No ZeroDivisionError

Always use pytest.approx for floating-point comparisons. Direct equality (==) fails due to floating-point representation.

Test categories to cover: | Category | Example for gross_margin | |----------|--------------------------| | Happy path | Normal revenue and COGS values | | Edge case | Revenue = 0, COGS = 0, COGS = Revenue | | Invalid input | Negative revenue, empty data | | Regression | Specific bug that occurred in production |


Type Hints

Document what your functions accept and return:

# Python 3.10+ style
def calculate_gross_margin(revenue: float, cogs: float) -> float:
    ...

def calculate_payback_months(
    investment: float,
    monthly_benefit: float,
) -> float | None:  # Can return None
    ...

def summarize_margins(
    revenues: dict[str, float],
) -> dict[str, float]:
    ...

Run mypy to catch type errors without running the code:

mypy your_module.py

Type hints are most valuable in shared modules. They're optional overhead in exploratory scripts.


Code Style and Enforcement

black: Auto-formats your code. No configuration debates.

black .          # Format everything
black --check .  # Preview what would change

flake8: Catches unused imports, undefined names, and other code problems.

flake8 .

Pre-commit hooks run these automatically before every commit:

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/psf/black
    rev: 24.3.0
    hooks:
      - id: black
  - repo: https://github.com/PyCQA/flake8
    rev: 7.0.0
    hooks:
      - id: flake8

Docstrings

The Google style (recommended for business code):

def calculate_gross_margin(revenue: float, cogs: float) -> float:
    """Calculate gross margin as a decimal.

    Args:
        revenue: Total sales revenue. Must be non-negative.
        cogs: Cost of Goods Sold.

    Returns:
        Gross margin as float (0.0 to 1.0). Returns 0.0 if revenue is zero.

    Raises:
        ValueError: If revenue or cogs is negative.

    Example:
        >>> calculate_gross_margin(100_000, 65_000)
        0.35
    """

Write a full docstring for any function you'd have to explain for more than 30 seconds.


Professional Project Structure

project/
├── .gitignore
├── .pre-commit-config.yaml
├── README.md
├── requirements.txt
├── src/
│   ├── business_math.py
│   └── report_builder.py
├── tests/
│   ├── test_business_math.py
│   └── test_report_builder.py
└── data/
    └── sample/      ← commit this

Code Review Culture

Giving feedback: - Be specific ("Extract lines 45–52 into a function" not "this is messy") - Distinguish blocking from non-blocking - Acknowledge what's good

Receiving feedback: - Separate code from identity — it's about the code, not you - Ask for clarification when a comment is unclear - You don't have to accept every non-blocking suggestion


The Complete Professional Workflow

Branch → Develop → Test → Lint → Commit → PR → Review → Merge

Each step catches a specific category of problem. The goal is to surface bugs early — when they're cheap to fix — not late, when they've already corrupted a report or overcharged a client.


Next: Chapter 40 — Building Your Python Business Portfolio.