title: "Session 1: Tools for Scientific Computing" author: Chris Broz date: 01/2026 styles: style: dracula¶
Calibration Slide¶
Window must be this wide ─────────────────────────────────────────────────►
And this tall
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
▼
For use with `lookatme`, a terminal-based presentation tool.
Preparation¶
If you haven't already done so...
- Open
https://github.com/CBroz1/SpyglassWorkshop2026 - Click 'Fork' in the top right, accept defaults
- Copy the new URL
- Open a terminal to a path where you store projects.
- Run the following:
git clone <https://github.com/><YOU>/SpyglassWorkshop2026 cd SpyglassWorkshop conda activate spyglass conda env update -f environment.yml python -m ipykernel install --user --name spyglass
These slides are available at SpyglassWorkshop2026/docs/src/session1_tools.md
Overview¶
This session will cover ...
- ⭕ VS Code: editor tour and settings
- ⭕ Jupyter: cells, kernel, and useful magics
- ⭕ GitHub: repos, branches, forks, pull requests
- ⭕ Code quality: docstrings,
ruff, and refactoring - ⭕ Debugging: breakpoints and
%debug(time permitting)
Overview¶
This session will cover ...
- 👀 VS Code: editor tour and settings
- ⭕ Jupyter: cells, kernel, and useful magics
- ⭕ GitHub: repos, branches, forks, pull requests
- ⭕ Code quality: docstrings,
ruff, and refactoring - ⭕ Debugging: breakpoints and
%debug(time permitting)
VS Code¶
Why a good editor matters¶
Your editor is where you spend most of your time.
Small productivity gains compound across many hours:
- Instant feedback on errors (linting, type hints)
- Format on save — no mental overhead on style
- Jump to definition, rename across files
- Integrated terminal, git, and debugger
VS Code¶
Getting started¶
- Open VS Code, then open the workshop folder:
code /path/to/SpyglassWorkshop2026
-
Accept the prompt to install recommended extensions (from
.vscode/extensions.json) -
Select the conda environment as your Python interpreter:
Ctrl+Shift+P → Python: Select Interpreter
→ spyglass
VS Code¶
Interface tour¶
- Can VSCode do that? Try
Ctrl+Shift+P - Extensions
- File Explorer
VS Code¶
Repository structure¶
A repository is just a directory with a standard layout:
SpyglassWorkshop2026/
├── .vscode/ # Workspace settings and recommended extensions
├── .github/ # issue templates and PR template
├── .gitignore # files Git will never track (secrets, caches)
├── .pre-commit-config.yaml # auto-formatting hooks (run on every commit)
├── README.md # project overview — the front page on GitHub
├── LICENSE # how others may use this code
├── CHANGELOG.md # human-readable history of releases
├── environment.yml # conda environment (reproducible setup)
├── pyproject.toml # package metadata and tool configuration
├── src/spyglass_workshop/ # library source code (importable package)
├── notebooks/ # Jupyter notebooks for demos and exercises
├── tests/ # pytest test suite
├── src/ # source code for this repository
└── docs/ # MkDocs documentation source
Overview¶
This session will cover ...
- ✅ VS Code: editor tour and settings
- 👀 Jupyter: cells, kernel, and useful magics
- ⭕ GitHub: repos, branches, forks, pull requests
- ⭕ Code quality: docstrings,
ruff, and refactoring - ⭕ Debugging: breakpoints and
%debug(time permitting)
Jupyter¶
Why notebooks?¶
Notebooks let you interleave prose, code, and output.
They are well-suited for:
- Exploratory analysis — run one cell at a time, inspect results
- Teaching — explain and demonstrate in the same document
- Reproducible workflows — share as a readable narrative
They are less well-suited for:
- Production code (use
.pymodules instead) - Large collaborations (merge conflicts are painful)
Jupyter¶
Cell types¶
| Type | Purpose |
|---|---|
| Code | Executable Python. Shift+Enter to run. |
| Markdown | Formatted text, equations, images. |
| Raw | Passed through unmodified (e.g., for nbconvert). |
Jupyter¶
The kernel¶
The kernel is the Python process running behind the notebook.
Notebook <-> Kernel (Python)
cell source executes code
cell output <-- returns result
- All cells share the same namespace — order matters.
- If things get confusing:
Kernel → Restart & Run All - The kernel indicator (top-right) shows idle
○vs busy●
In VS Code: use the Variables panel (View → Variables) to inspect all
objects in the current kernel namespace.
Time for a quick tour!
Overview¶
This session will cover ...
- ✅ VS Code: editor tour and settings
- ✅ Jupyter: cells, kernel, and useful magics
- 👀 GitHub: repos, branches, forks, pull requests
- ⭕ Code quality: docstrings,
ruff, and refactoring - ⭕ Debugging: breakpoints and
%debug(time permitting)
GitHub¶
Why version control?¶
Science produces code that:
- Changes frequently as understanding grows
- Must be reproducible months or years later
- Is increasingly shared and reused by others
Version control lets you ...
- Travel back to any previous state
- Work on new ideas without breaking what works
- Propose and review changes safely
- Collaborate without overwriting each other
GitHub¶
Key concepts¶
┌─────────────────────────────────────┐
│ Remote (github.com) │
│ │
│ upstream/main ──── your-fork/main │
│ │ │
└────────────────────────────┼────────┘
│ clone
┌──────────▼──────────┐
│ Local │
│ │
│ main │
│ └── your-branch │
└─────────────────────┘
| Term | Meaning |
|---|---|
| Repository | A project and its full history |
| Commit | A saved snapshot with a message |
| Branch | A parallel line of development |
| Fork | Your personal copy of someone else's repo |
| Pull Request | A proposal to merge one branch into another |
| Issue | A tracked bug, question, or feature request |
| Action | An automated script run by GitHub |
GitHub¶
Branches¶
mainis canonically the stable, shared branch- Create a branch for each feature, fix, or experiment.
Forks and Pull Requests¶
- Fork individual's copy of a repository.
- Clone downloads your fork to your laptop.
- Make changes on a branch.
- Push your branch to your fork.
- Open a Pull Request to propose merging into upstream.
Git Commits¶
Commits happen in 4 phases:
- Edit: Saving changes to a file
- Stage: 'Adding' files to a forthcoming commit
git add <file pattern> - Commit: Saving staged changes as a commit
git commit -m <message> - Pushing: Pushing the commit history to a remote branch
git push origin main
There are plenty of tools to help manage this process, as well as diverging
branches and conflicts, including the Source Control tab in VSCode
(Ctrl+Shift+G).
Jupytext — notebooks in version control¶
.ipynb files store outputs and metadata alongside source, making git diff
noisy. jupytext converts a notebook to a plain Python script — clean diffs, no
JSON, no embedded images.
# Convert all notebooks to lightweight Python scripts
jupytext --to py:light notebooks/*.ipynb
# Move them to a dedicated folder and format
mv notebooks/*.py notebooks/py_scripts/
ruff format notebooks/py_scripts/
The # %% markers in the .py files are understood by VS Code and JupyterLab —
run them interactively or as a plain script.
Overview¶
This session will cover ...
- ✅ VS Code: editor tour and settings
- ✅ Jupyter: cells, kernel, and useful magics
- ✅ GitHub: repos, branches, forks, pull requests
- 👀 Code quality: docstrings,
ruff, and refactoring - ⭕ Debugging: breakpoints and
%debug(time permitting)
Code Quality¶
Why it matters¶
Code is read far more often than it is written.
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." — Martin Fowler
- Consistent style removes cognitive load of formatting preferences
- Docstrings and type hints make intent visible without running code
- Many automatic tools catch common issues and enforce best practices
Code Quality¶
Type hints & docstrings¶
Type hints are not enforced at runtime but document intent so editors and readers don't have to guess:
def get_data_interface(
nwbfile: pynwb.NWBFile,
name: str,
interface_class: type | None = None,
) -> NWBDataInterface | None:
Docstrings power help() and auto-generated docs.
Spyglass uses NumPy style:
"""One-line description.
Parameters
----------
nwbfile : pynwb.NWBFile
The NWB file to search.
name : str
Name of the data interface.
Returns
-------
NWBDataInterface or None
"""
Code Quality¶
ruff¶
ruff is a fast Python linter and formatter — it replaces black flake8, and
more with a single tool.
ruff check my_file.py # report issues
ruff check --fix my_file.py # auto-fix what it can
ruff format my_file.py # format in place
It catches issues like:
F401— imported but unused (import json)E711— comparison toNoneshould useisUP— upgrades to modern Python syntaxI— import ordering (replacesisort)
Try writing a='1' and saving — ruff will change it to a = '1'
automatically.
Code Quality¶
pre-commit¶
pre-commit runs checks automatically before every git commit.
# .pre-commit-config.yaml (already in this repo)
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
hooks:
- id: ruff
- id: ruff-format
pre-commit install # one-time setup (already done)
pre-commit run --all-files # run manually
If a hook fails, the commit is blocked and the file is fixed. Re-stage and try again.
This means bad style never reaches the repository... unless you intentionally
bypass it with git commit --no-verify.
Exercises¶
Try out a few exercises in notebook 1, then stop at 'Readable code'
Code Quality¶
Atomizing¶
Working memory is limited — long functions force you to hold too much in mind at once. Extract pieces into the smallest chunk that deserves a name:
| Level | Mechanism |
|---|---|
| Conceptual group | Blank line (paragraph break) |
| Conditional value | Ternary or early assignment |
| Reusable step | Method on a class |
| Shared within a module | Helper function |
| Shared across a project | Utility module |
A well-named helper turns code you have to read into a word you already know.
Overview¶
This session will cover ...
- ✅ VS Code: editor tour and settings
- ✅ Jupyter: cells, kernel, and useful magics
- ✅ GitHub: repos, branches, forks, pull requests
- ✅ Code quality: docstrings,
ruff, and refactoring - 👀 Debugging: breakpoints and
%debug(time permitting)
Debugging¶
When print statements are not enough¶
Print-based debugging:
- Requires editing and re-running the file
- Only shows what you thought to print
- Gets messy fast
A debugger lets you:
- Pause execution at any line
- Inspect every variable in scope
- Step through code line by line
- Move up and down the call stack
Debugging¶
Manual breakpoints¶
Insert breakpoint() anywhere in your code to pause execution there.
Debugging in IPython¶
If you hit an error either in a notebook or an ipython session, you can run
%debug in a new cell to enter the post-mortem debugger.
%debug
Debugging in VS Code¶
- Either...
- Script: Run and Debug sidebar (
Ctrl+Shift+D) - Notebook: use the dropdown next to the ▶ button → Debug Cell
- Execution pauses at errors and/or breakpoints.
- Use the debug toolbar: Step Over, Step Into, Step Out, Continue.
The Variables panel shows all locals and their current values. The Debug Console lets you evaluate expressions live.
Let's try it out in notebook 1!
Overview¶
This session will cover ...
- ✅ VS Code: editor tour and settings
- ✅ Jupyter: cells, kernel, and useful magics
- ✅ GitHub: repos, branches, forks, pull requests
- ✅ Code quality: docstrings,
ruff, and refactoring - ✅ Debugging: breakpoints and
%debug(time permitting)
Key takeaways:
- VS Code settings live in
.vscode/— they are already configured - Fork → clone → branch → commit → push → PR
- Docstrings and type hints make intent visible without running code
ruffandpre-commitenforce style automatically- Guard clauses and named helpers make code easier to follow
- The debugger is faster than print statements
After the break: Session 2 — Spyglass & DataJoint Infrastructure