Python Environments & Conda

Why ecologists who never thought they'd touch a package manager need one anyway, and how to set it up so you don't fight your laptop for the rest of the course.

1. The problem environments solve

Here is a real situation you will hit in this course (and in every Python project for the rest of your career):

If you pip install all of these into one Python, sooner or later one will overwrite a shared dependency at a version that breaks another. You'll get a four-line cryptic error, lose two hours debugging, and learn the wrong lesson ("Python is bad"). The right lesson is: each project gets its own isolated Python — an "environment" — and they don't share packages.

An environment is just a folder containing its own Python interpreter and its own copy of every package it needs. When you activate the environment, typing python or pip in your shell uses that folder's Python instead of the system one.

2. The cast of characters

NameWhat it isWhen to reach for it
venv Built into Python. Creates a lightweight environment that uses your existing Python and installs packages with pip. Quick projects where you already have the right Python version and only need pure-Python packages. Used by the instructor for the answer-key venv (.venv/ in the course folder).
conda Heavier. Installs an entire Python interpreter and packages, including non-Python tools like sox, ffmpeg, gdal. Anything ML-flavoured (TensorFlow, PyTorch with CUDA), anything that needs a specific Python version, anything that depends on a binary tool. This is the default in this course.
Miniforge A small conda installer that defaults to the open conda-forge package channel (free of Anaconda's commercial licensing concerns). What we recommend installing. It gives you conda and mamba.
mamba A drop-in replacement for the slow parts of conda (especially dependency solving). Same commands, ~10x faster. Once you have conda working, you may want to substitute mamba for conda in commands like create and install. Ships with Miniforge.
pip The Python-only package installer. Available in any conda or venv env. Inside a conda env, use it for packages that aren't on conda-forge (most ML packages by the time you read this).

3. Install Miniforge (one time per laptop)

macOS

# Recommended: via Homebrew
brew install --cask miniforge

# Initialize your shell (zsh is default on modern macOS)
conda init zsh

# Close and reopen your terminal so the changes take effect.
# Verify:
conda --version
mamba --version

Windows

Two equally fine options:

# Option A: WinGet
winget install CondaForge.Miniforge3

# Option B: Download from https://github.com/conda-forge/miniforge and run the .exe
# Accept all defaults.

# Verify in a NEW PowerShell:
conda --version
mamba --version

Windows users: search the Start menu for "Miniforge Prompt" the first time. It's a pre-configured terminal where conda already works. After conda init powershell, regular PowerShell will work too.

Linux / WSL

curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh"
bash Miniforge3-*.sh -b -p ~/miniforge3
~/miniforge3/bin/conda init bash      # or zsh, fish, etc.
# Restart shell, verify:
conda --version

4. Your first environment (do this once now)

Let's make the course environment you'll use for all the Python labs:

# Create a fresh env called "aiecol" with Python 3.11 (the sweet spot — works with
# pycnet-audio AND PyTorch AND birdnet at the same time).
mamba create -n aiecol -c conda-forge python=3.11 sox ffmpeg -y

# Switch into it
conda activate aiecol
# Your prompt now shows (aiecol).

# Install the Python packages. We use pip here because most ML packages publish to
# PyPI faster than to conda-forge. This is a totally normal and supported pattern
# inside a conda env.
pip install numpy pandas matplotlib scikit-learn pillow requests exifread \
            soundfile librosa pyyaml tqdm \
            torch torchvision \
            ultralytics birdnet

# Sanity check
python -c "import torch, ultralytics, librosa, birdnet; print('all good')"

That's it. You now have one isolated environment with everything Lab 2–7 needs. Whenever you start a new terminal session and want to work on the course, run:

conda activate aiecol

and your prompt will say (aiecol) instead of (base). To leave it (and return to the base/system Python):

conda deactivate
What's (base)? Every Miniforge install ships with a "base" environment that is auto-activated when you open a terminal. Never install project packages into base. Always create a named env per project. The base env is for conda itself.

5. The second environment — an example of why this matters

For Lab 7 we use PNW-Cnet via pycnet-audio, which is fussier — it requires Python 3.8–3.11 and a specific TensorFlow version that fights with birdnet's newer TensorFlow. Easiest fix: a separate environment for that one tool.

mamba create -n pycnet -c conda-forge sox python=3.11 -y
conda activate pycnet
pip install pycnet-audio

# Use it
pycnet process /path/to/audio -c v5 -a

# When done, go back to your main course env
conda deactivate
conda activate aiecol

You now have two envs: aiecol (everything else) and pycnet (just PNW-Cnet). Switching between them is free.

6. environment.yml — saving and sharing an env

When your project gets serious (a manuscript, a thesis, your final project for this course), write down exactly what's in your env so you and your collaborators can recreate it later. The standard way is an environment.yml file:

# Dump the current env to a portable file
conda env export --from-history > environment.yml

# Or, more commonly, write it by hand to be deliberate:
cat > environment.yml <<'EOF'
name: my_project
channels:
  - conda-forge
dependencies:
  - python=3.11
  - sox
  - ffmpeg
  - pip
  - pip:
      - numpy
      - pandas
      - librosa
      - birdnet
EOF

# Recreate it later (yours or a colleague's machine)
mamba env create -f environment.yml
conda activate my_project
Why --from-history? A raw conda env export lists every transitive dependency at exact versions, which often doesn't reproduce cross-platform (a macOS export won't install on Linux because some packages have different platform-specific builds). --from-history exports only the packages you explicitly asked for — much more portable.

Commit environment.yml to git. Don't commit the env folder itself; add .conda/ and envs/ to your .gitignore.

7. pip vs conda — when to use which

Inside a conda env, both pip install X and conda install X work. Which should you pick?

8. Activating envs in different tools

RStudio terminal pane

RStudio's Terminal tab opens a normal shell. Just type conda activate aiecol and you're in. You may need to first conda init zsh (macOS) or conda init bash (Linux) once for that shell to know about conda.

Claude Code

Same trick — Claude Code runs commands in a normal shell. Before starting Claude, activate your env in that terminal. Or, to make it automatic per project, add to your project's CLAUDE.md:

# in CLAUDE.md
Always run Python via the `aiecol` conda env. Never `pip install` into base.
If a command needs the env, prefix with `conda run -n aiecol`.

You can also use conda run -n aiecol python ... for one-off commands without changing the active env.

VS Code

Cmd/Ctrl-Shift-P → "Python: Select Interpreter" → pick the one whose path ends in envs/aiecol/bin/python. After that, VS Code's "Run Python File" button and the integrated terminal automatically use that env.

Jupyter

conda activate aiecol
pip install jupyterlab
python -m ipykernel install --user --name aiecol --display-name "Python (aiecol)"

# Then in JupyterLab, pick the "Python (aiecol)" kernel.

9. When you don't need an environment

Be honest with yourself; not every script needs a fresh env. If you're:

just use the base env or system Python. Spinning up a fresh env for every trivial task gets in the way of fast iteration.

But: the moment you pip install anything for a one-liner script, it has become a project. Make it an env.

10. When to use one env per project vs one big env

Two reasonable workflows:

The right default for a research project is one env per repo, with the environment.yml living in the repo root next to README.md.

11. Pitfalls and rescue commands

SymptomCauseFix
conda activate aiecol → "command not found: conda" You skipped conda init, or the shell hasn't been restarted. Run conda init zsh (or your shell), close the terminal, open a new one.
conda solver hangs for many minutes Real conda solver is slow. Many old StackOverflow answers say so. Use mamba instead: mamba install .... Ships with Miniforge.
ModuleNotFoundError: No module named 'X' after installing You're not in the env you think you are. Check the env name in your prompt; which python should point at the env's bin folder. Run conda activate <env>.
Two envs got mixed up; one is acting weird You pip-installed into base, or pip-overwrote a conda-installed package. Delete and recreate: conda env remove -n broken, then create from your environment.yml.
Disk fills up with env folders Each env is ~1–5 GB, mostly PyTorch wheels. conda clean --all reclaims a few GB; conda env list shows what's around; remove old ones with conda env remove -n old_env.
"InvalidVersionSpec" or "ResolvePackageNotFound" Two packages require incompatible versions. Pin Python (python=3.11) and the major conflicting package explicitly; try installing one at a time to see which causes the conflict.
Apple Silicon: "wheel not available for platform" Some packages don't have arm64 wheels yet. Try conda-forge (broader arm64 coverage); or, as a last resort, set CONDA_SUBDIR=osx-64 to install x86_64 versions that run under Rosetta.

12. Cheat sheet

# list all envs
conda env list

# create new env from scratch
mamba create -n NAME -c conda-forge python=3.11 PACKAGE1 PACKAGE2 -y

# create from a yml file
mamba env create -f environment.yml

# activate / deactivate
conda activate NAME
conda deactivate

# install / uninstall
mamba install -c conda-forge PACKAGE          # preferred
pip install PACKAGE                            # for ML / PyPI-only packages

# save / share
conda env export --from-history > environment.yml
git add environment.yml && git commit -m "freeze env"

# remove
conda env remove -n NAME

# what version of X is installed?
conda list PACKAGE
pip   show  PACKAGE

One last sanity rule: if you can't remember whether you're in the right env, run which python (Unix) or where python (Windows). The path tells you exactly which Python you're about to use. Trust the path, not your memory.

→ Continue to Claude Code setup