Applied Software Engineering

Tools and Best Practices for Python Development

Decision-Making and Motion Planning for Automated Driving
KIT - Karlsruhe Institute of Technology

Topics

  1. Git and GitHub
  2. Python and uv
  3. Unit Testing and TDD
  4. Linting and Code Quality
  5. IDE and Debugging

1. Git and GitHub

What is Version Control?

  • Track changes to files over time
  • Collaborate with others without conflicts
  • Revert to previous versions when needed
  • Maintain a complete history of your project
Git = Distributed version control system
GitHub = Web-based hosting for Git repositories

Docs: git-scm.com/doc

Git Basics

# Clone a repository
git clone https://github.com/KIT-MRT/behavior_generation_lecture_python.git

# Check status of your changes
git status

# Stage changes for commit
git add myfile.py

# Commit with a message
git commit -m "Add new feature for path planning"

# Push to remote repository
git push origin main

# Pull latest changes (fetch + merge)
git pull origin main

Resources: GitHub Getting Started, Git reference

Branching and Merging

# Create a new branch
git checkout -b feature/new-controller

# Switch between branches
git checkout main

# Merge a branch
git merge feature/new-controller

# Delete a branch
git branch -d feature/new-controller
main feature/new-controller

Why branches?

  • Isolate development work
  • Work on features independently
  • Review before merging to main

GitHub Workflow

  1. Fork/Clone the repository
  2. Create a branch for your feature
  3. Make changes and commit
  4. Push to your fork/branch
  5. Open a Pull Request (PR)
  6. Code Review by teammates
  7. Merge after approval

2. Python and uv

The Python Environment Problem

  • Different projects need different Python versions
  • Package version conflicts between projects
  • "It works on my machine" syndrome
  • Reproducibility across team members
Solution: Virtual environments + lock files

uv - Modern Python Package Manager

  • Fast (written in Rust, 10-100x faster than pip)
  • Manages Python versions
  • Creates virtual environments automatically
  • Generates lock files for reproducibility

Docs: docs.astral.sh/uv

uv - Common Commands

# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# Create a new project
uv init my-project

# Install dependencies
uv sync

# Add a new package
uv add numpy

# Run a script
uv run python my_script.py

pyproject.toml

Central configuration file for Python projects:

Example (shortened). Full file: pyproject.toml

[project]
name = "behavior_generation_lecture_python"
version = "0.0.2"
requires-python = ">=3.12, <3.13"

dependencies = [
    "numpy>=1.26.0",
    "matplotlib>=2.2.4",
    "scipy>=1.11.0",
    # ...
]

[project.optional-dependencies]
dev = [
    "pytest",
    # ...
]

3. Unit Testing and TDD

Why Testing?

  • Confidence: Know your code works
  • Refactoring: Change code safely
  • Documentation: Tests show how to use code
  • Collaboration: Catch breaking changes early
  • Design: Forces modular, testable code

pytest Basics

# tests/test_a_star.py
import pytest
from behavior_generation_lecture_python.graph_search.a_star import a_star

def test_a_star_finds_path():
    """Test that A* finds a valid path."""
    start = (0, 0)
    goal = (5, 5)
    
    path = a_star(start, goal, grid)
    
    assert path is not None
    assert path[0] == start
    assert path[-1] == goal

def test_a_star_no_path():
    """Test that A* returns None when no path exists."""
    path = a_star(start, goal, blocked_grid)
    
    assert path is None

Docs: docs.pytest.org

Running Tests

# Run all tests
uv run pytest

# Run tests with coverage
uv run pytest --cov=src

# Run specific test file
uv run pytest tests/test_a_star.py

# Run tests matching a pattern
uv run pytest -k "test_a_star"

# Show verbose output
uv run pytest -v

# Stop on first failure
uv run pytest -x

Coverage plugin: pytest-cov

Test-Driven Development (TDD)

The TDD Cycle:

RED Write failing test GREEN Make it pass REFACTOR Improve code

Repeat!

Benefits:

  • Clear requirements before coding
  • Better design decisions
  • High test coverage by default
  • Faster debugging

4. Linting and Code Quality

What is Linting?

  • Static analysis of code for errors and style issues
  • Catches bugs before running the code
  • Enforces consistent code style across team
  • Improves code readability and maintainability
Linter: Finds problems
Formatter: Fixes style automatically

ruff - Fast Python Linter

# Format code (like Black)
uv run ruff format

# Check for linting issues
uv run ruff check

# Auto-fix what can be fixed
uv run ruff check --fix

ruff is 10-100x faster than traditional tools!

Common issues caught:

  • Unused imports and variables
  • Line too long
  • Missing docstrings

Docs: docs.astral.sh/ruff

mypy - Static Type Checking

# Without type hints - mypy cannot help
def calculate_reward(state, action):
    return state * action  # Bug if state is a list!

# With type hints - mypy catches errors
def calculate_reward(state: float, action: float) -> float:
    return state * action  # mypy ensures correct types
# Run type checking
uv run mypy path/to/package_or_module

Type hints = documentation + error prevention

Docs: mypy.readthedocs.io

Continuous Integration (CI)

CI is an automated quality gate that runs on every push / pull request.

  • Fast feedback: catch issues early
  • Reproducible results: same checks for everyone
  • Protects main: merges only after checks pass

Our CI: .github/workflows/ci.yml,

Typical Local Workflow

# Create a branch
git checkout -b feature/my-change

# Install (use the lock file)
uv sync --all-extras

# Run checks (see CI workflow for the exact commands)
uv run ruff format
uv run ruff check
uv run mypy path/to/package_or_module
uv run pytest

5. IDE and Debugging

VS Code / Cursor Setup

VS Code / Cursor Settings

// .vscode/settings.json
{
    "python.defaultInterpreterPath": ".venv/bin/python",
    "[python]": {
        "editor.formatOnSave": true,
        "editor.defaultFormatter": "charliermarsh.ruff"
    }
}

Common Setup Issues (and Fixes)

  • Wrong interpreter: Select .venv/bin/python in the IDE
  • Missing extras: Run uv sync --all-extras (docs, dev tools)
  • Lock file drift: Prefer using the lock file and keep uv.lock committed

Repo files: uv.lock, pyproject.toml

Debugging in VS Code

Key Features:

  • Breakpoints: Click left of line number
  • Step Over (F10): Execute current line
  • Step Into (F11): Enter function
  • Step Out: Exit function
  • Continue (F5): Run to next breakpoint

Debug Views:

  • Variables: See current values
  • Watch: Monitor expressions
  • Call Stack: See function calls
  • Debug Console: Evaluate code

Docs: Python debugging in VS Code

Summary

Topic Key Tools
Version Control git, GitHub, Pull Requests
Environment uv, pyproject.toml, uv.lock
Testing pytest, pytest-cov, TDD
Code Quality ruff, mypy
Development VS Code, Cursor, Python debugger

Getting Started

# Clone the repository
git clone https://github.com/KIT-MRT/behavior_generation_lecture_python.git
cd behavior_generation_lecture_python

# Install dependencies
uv sync --all-extras

# Run the tests
uv run pytest

# Start exploring!
uv run jupyter lab

Documentation