Python patterns for media tools
A compact lookup for paths, JSON, CLIs, contracts, and tests.
Use this page while working; do not study it as another course. Each pattern is deliberately small, standard-library first, and shaped around media metadata or QC scores.
Paths: compose, inspect, then act
Prefer Path objects to manual separators. Resolve context for diagnosis, check existence, and refuse accidental overwrite.
Runtime: Local Python 3.12 or browser lab · reads path state only · 5 min.
from pathlib import Path
project = Path.cwd()
metadata = project / "fixtures" / "shot_014.json"
print("project:", project.resolve())
print("metadata:", metadata)
print("exists:", metadata.exists())
Lookup: official pathlib documentation. Read the basic path composition and file-method sections only.
Files: make encoding and overwrite policy explicit
Runtime: Local Python 3.12 · creates a new named text artifact only · 5 min.
from pathlib import Path
def write_new_text(path: Path, text: str) -> None:
if path.exists():
raise FileExistsError(f"Refusing to overwrite {path}")
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(text, encoding="utf-8")
JSON: stable fields at tool boundaries
Use JSON for metadata and reports, not raw frame arrays. Sort keys only when stable textual output helps review; consumers should depend on field names, not order.
Runtime: Local Python 3.12 or browser lab · standard library only · 5 min.
import json
report = {"clip": "shot.mov", "worst_score": 0.31, "flagged": True}
encoded = json.dumps(report, indent=2, sort_keys=True)
decoded = json.loads(encoded)
assert decoded == report
Lookup: official json documentation.
CLI arguments: expose every experiment choice
Runtime: Local Python 3.12 · save in a CLI module; --help is read-only · 5 min.
import argparse
from pathlib import Path
parser = argparse.ArgumentParser(description="Inspect media metadata")
parser.add_argument("input", type=Path)
parser.add_argument("--threshold", type=float, default=0.25)
args = parser.parse_args()
Lookup: official argparse documentation.
Functions: validate boundary assumptions
Runtime: Local Python 3.12 or browser lab · standard library only · 5 min.
def worst_score(scores: list[float]) -> float:
if not scores:
raise ValueError("scores must contain at least one measurement")
if any(score < 0 for score in scores):
raise ValueError("scores must be non-negative")
return max(scores)
Tests: protect behaviour, boundary, and failure
Runtime: Local Python 3.12 with pytest · run python -m pytest -q · 10 min.
import pytest
def test_worst_score_selects_the_largest_measurement():
assert worst_score([0.08, 0.31, 0.12]) == 0.31
def test_worst_score_rejects_missing_measurements():
with pytest.raises(ValueError, match="at least one"):
worst_score([])
Lookup: official pytest assertion guide.
Objects: state plus behaviour
Runtime: Local Python 3.12 or browser lab · standard library only · 5 min.
class Threshold:
def __init__(self, value: float):
self.value = value
def classify(self, score: float) -> bool:
return score >= self.value
Ask three questions: what state is stored, what input enters the method, and what output contract leaves? The same trace scales to a PyTorch nn.Module, with additional parameter, tensor-shape, device, and train/eval state.
Debug route
- Capture command, input, runtime, actual output, and traceback/log.
- State expected output and the contract.
- Form one falsifiable hypothesis.
- Reduce the input and instrument only the suspected boundary.
- Write a regression test, see the broken behaviour fail, repair minimally, and run the wider suite.
Stop here. If a pattern is not on this page, consult the linked official reference for that exact question instead of reading it end to end.
Your local study notes mount here when JavaScript is available.
Teaching modes mount here when JavaScript is available. The readable course remains available without them.