Key Points

Writing Effective Functions


  • Extract a function when you find yourself repeating logic, not just to look tidy
  • Prefer returning values over printing them, so functions can be composed
  • Type hints document expected input/output types for editors and readers
  • A docstring documents purpose, parameters, and return value. Its often best to write it as part of writing the function, not as an afterthought

Organizing Functions into Modules


  • A module is a single .py file; a package is a directory of modules with an __init__.py
  • %load_ext autoreload + %autoreload 2 lets a notebook pick up edits to your own modules without a kernel restart
  • Python checks your notebook’s own directory before the standard library, such that a module named random.py or csv.py can silently break unrelated imports elsewhere in your code
  • Not everything needs a module. Modularize logic that’s substantial or repeated

Building a Repository and Managing Environments


  • Separate the installable package (src/mooring_tools/) from notebooks and data
  • A src/ layout turns “the package isn’t actually installed” from a silent bug into a raised error
  • uv init --lib creates the project skeleton; uv add installs a dependency and records it in pyproject.toml and uv.lock
  • uv run runs a command in the project’s environment with nothing to activate; the .venv folder is disposable and never committed
  • pyproject.toml declares what your code needs (minimum versions); uv.lock records exactly what’s installed: commit both, and reproduction is git clone plus uv sync

Documentation and Reuse


  • A README’s job is to let someone else install and run the project without asking you
  • Docstring consistency matters more as a project grows past one file
  • A well-documented function’s docstring tells the reader what’s safe to extend, not just what the function currently does
  • Reusing a repo well means extending generic functions with new data/config, not copy-pasting or editing working code
  • Bumping a version number and tagging the commit is enough to keep “what did I run this with” answerable later