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.