cassionData Analysis

Lesson 1 of 8

Unit · An environment that will still run

A Python you can reinstall without internet

Why the system Python is the wrong place to work, what a virtual environment actually is, and how to carry a working install to a field laptop that has never seen a package index.

Python80 min

The failure this lesson prevents

An analysis runs on your laptop. Three months later the same script is run by someone else, on a different machine, and it either fails to start or — much worse — produces a different number.

That is not usually a bug in the analysis. It is a bug in the environment: a different pandas version whose default changed, a package installed for one project that broke another, a system Python the operating system upgraded underneath you.

This lesson is about making the environment a thing you declare, rather than a thing that accumulates.

Do not work in the system Python

macOS and most Linux distributions ship a Python that the operating system uses for its own tooling. On a shared field laptop, someone has usually installed a second one from a website, and a third arrived with an office suite.

Installing packages into any of them is a bad idea for a specific reason: the operating system depends on the versions it shipped. Upgrading pandas to satisfy your script can break a system utility, and there is nothing to warn you.

Newer Python builds now refuse outright:

error: externally-managed-environment

x This environment is externally managed
+-> To install Python packages system-wide, try apt install
    python3-xyz, where xyz is the package you are trying to
    install.

That error is correct and should not be worked around. There is a flag that overrides it. Using it is how a laptop ends up needing to be reimaged.

What a virtual environment is

A virtual environment is a directory holding its own copy of the interpreter’s package directory. Activating it changes where python and pip look. That is the whole idea.

python3 -m venv .venv
source .venv/bin/activate       # Windows: .venv\Scripts\activate
python -m pip install pandas

Two consequences worth internalising:

  • Per project, not per machine. Two analyses needing different pandas versions coexist without either knowing about the other.
  • Disposable. If an environment gets into a bad state, delete the directory and rebuild it. Nothing of value lives there — which is only true if your dependencies are declared somewhere else.

uv, and why it matters more here than elsewhere

pip resolves and downloads packages one at a time from the network. On a connection that drops, a half-finished install leaves an environment that is neither the old one nor the new one.

uv is a faster resolver that produces a lockfile: an exact list of every package and version, including the ones your packages depend on.

# Install uv itself, once, on a machine that does have internet.
curl -LsSf https://astral.sh/uv/install.sh | sh

uv init muac-analysis
cd muac-analysis
uv add pandas openpyxl
uv run python -c "import pandas; print(pandas.__version__)"

uv add writes two files. pyproject.toml records what you asked for — pandas — and uv.lock records what you got, down to the exact version of every transitive dependency. Commit both. The first is your intent; the second is what makes next quarter’s install identical to this one.

On the field laptop:

uv sync                        # reads uv.lock, installs exactly those versions

conda is the reasonable alternative and is common in this sector, particularly where a geospatial stack is involved — GDAL is far easier to install through conda than through pip. If your organisation already standardises on conda, use conda; the principle is identical and only the commands change.

Installing where there is no internet

This is the part most tutorials skip, and it is the part that matters on a deployment.

Download the packages once, on a connected machine, targeting the platform the field laptop runs:

mkdir wheels
uv pip download pandas openpyxl --dest wheels

Copy the wheels directory onto a USB stick along with your project, then on the offline machine:

uv venv
uv pip install --no-index --find-links wheels pandas openpyxl

--no-index tells the installer not to contact the package index at all, and --find-links points it at the directory instead. The install is then entirely local.

Wheels are platform-specific. A wheel downloaded on macOS will not install on a Windows laptop, and one built for Python 3.12 will not install into 3.11. Download on a machine matching the target, or pass --python-platform and --python-version explicitly.

Pinning the Python version too

The packages are pinned; the interpreter should be as well. A script written against 3.12 and run on 3.9 fails on syntax that did not exist yet.

# pyproject.toml
[project]
name = "muac-analysis"
requires-python = ">=3.11"
dependencies = ["pandas>=2.2", "openpyxl>=3.1"]
uv python install 3.12
uv python pin 3.12

Verifying the environment before trusting it

Before running an analysis on a machine you did not set up, check that you are where you think you are:

import sys
import pandas as pd

print(sys.executable)          # should be inside .venv, not /usr/bin
print(sys.version)
print(pd.__version__)

If sys.executable is /usr/bin/python3, the environment is not activated and you are about to install into the system Python. That single line has saved more laptops than any amount of documentation.

For an analysis whose numbers matter, assert it:

import sys

assert sys.version_info >= (3, 11), f"needs Python 3.11+, running {sys.version}"

What to hand to a colleague

Everything needed to rebuild the environment, and nothing that was built:

Commit Do not commit
pyproject.toml .venv/
uv.lock wheels/
README.md with the two commands __pycache__/

A .gitignore covering the right column is part of the project template in the next lesson.

The README needs two lines, not two pages:

uv sync
uv run python scripts/indicator_table.py --input data/raw/muac.csv

What comes next

The environment is reproducible. The next lesson is about the project around it — where the raw data goes, where outputs go, and why a path written as C:\Users\marie\Desktop\data.csv guarantees the script runs on exactly one machine.

Teach this lesson

The lesson as a slide deck, with the prose kept in the speaker notes rather than on the slide. Generated from this page, so it cannot fall out of step with it.

Start the slideshowRead the slides

The PDF needs no software and projects from any machine. The PowerPoint file is there to be edited — add your organisation's branding, cut a section for a shorter session, or merge two lessons into a workshop.