Virtual Environments: Why One Environment per Project

Before You Start

You should know: - How to navigate the command line (mkdir, cd, pwd). - How to verify that Python is installed and accessible via your terminal (python --version).

You will learn: - The concept of β€œdependency hell” and why global installations are dangerous. - What a virtual environment mechanically achieves. - How to create, activate, and deactivate environments using venv and conda. - Where your environments live on disk and why you should keep them out of Git.

Introduction

You have Python installed. It is tempting to start installing geographic libraries β€” numpy, pandas, geopandas β€” directly into that single Python installation. This is called a global installation, and it is the single biggest source of frustration for early Python programmers.

Eventually, global installations lead to a state called β€œdependency hell” where your projects silently break each other. Understanding why this happens, and how environments prevent it, will save you hours of confusion.

The Problem: Dependency Conflicts

Imagine you start a project in January called Urban Flooding. You install a library called WaterSim version 1.0, which depends on numpy version 1.18. Python installs both.

Six months later you start a new project, Traffic Network. You install RoadNet version 3.0, which requires numpy version 1.25 for a feature that didn’t exist before. Python upgrades numpy to 1.25.

Three months after that, your colleague asks you to re-run the Urban Flooding analysis. You run the script. It crashes immediately with cryptic errors. Why? Because WaterSim 1.0 was never tested against numpy 1.25. The upgrade you made for one project broke the other.

With a global installation, every project competes for the same set of libraries. The latest one to install wins, and everything older breaks quietly.

The Solution: Virtual Environments

A virtual environment is an isolated sandbox. It contains its own copy of Python and its own private library folder. Libraries in one environment have no idea that libraries in another environment exist.

The rule is simple: one environment per project. When you start a new analysis, create a new environment, install only what that project needs, and activate it whenever you work on that project.

This costs you almost nothing β€” environments are cheap to create and fast to rebuild. The protection they give you is enormous.

Creating and Using Environments

The specific commands depend on which installation you chose in the previous chapter.

If you use Standard Python (venv)

First, cd into your project folder.

Create the environment:

python -m venv .venv

(Mac/Linux may need python3 -m venv .venv)

This creates a hidden folder called .venv inside your project directory. The dot prefix makes it hidden by default in file explorers. Run ls -a to see it (the -a flag shows hidden files).

Activate on macOS/Linux:

source .venv/bin/activate

Activate on Windows PowerShell:

.venv\Scripts\Activate.ps1

When activation works, your terminal prompt changes. You will see (.venv) appear at the left:

(.venv) sarah@macbook project %

That prefix is your signal that you are inside the sandbox. Every pip install you run now goes into .venv, not into your global Python.

Deactivate:

deactivate

The (.venv) prefix disappears. You are back in the global environment.

You must activate the environment every time you open a new terminal to work on a project. It does not activate automatically. Forgetting this is the most common reason why import numpy fails even though you definitely installed it.

If you use Miniforge/Conda (conda)

Conda manages environments centrally rather than inside each project folder. All conda environments live in a central directory (usually ~/miniforge3/envs/ on macOS, or C:\Users\you\miniforge3\envs\ on Windows).

Create an environment:

conda create --name geo-flood python=3.11

Name your environments clearly β€” you will accumulate several. geo-flood is better than env1. Include the project name and perhaps the purpose.

Conda will ask you to confirm (y/N). Type y and press Enter. It downloads a fresh Python 3.11 into the new environment.

Activate:

conda activate geo-flood

Your prompt changes to show (geo-flood) on the left.

Deactivate:

conda deactivate

See all your environments:

conda env list

This lists every named environment and where it lives on disk. The asterisk marks the currently active one.

Naming Conventions

Good environment names save confusion:

  • Use the project name: flood-model, traffic-network, census-analysis
  • Add context if needed: flood-model-py311 (if you need to track Python version)
  • Avoid generic names like env, test, or new β€” you will forget what they are for

For venv environments, the folder is almost always named .venv. The project directory name gives you the context.

Keep Environments Out of Git

The .venv folder can contain thousands of files and hundreds of megabytes of compiled libraries. You should never commit this to version control β€” it is machine-specific, regenerable from a requirements file, and will bloat your repository.

Add this to your project’s .gitignore file:

.venv/
__pycache__/
*.pyc

If you use conda, you do not need to gitignore your environment because conda stores it outside your project folder anyway. But you should still add __pycache__/ and *.pyc to your .gitignore.

(We cover Git in a later chapter. For now, just know this rule exists.)

Verify Your Work

  1. Navigate to your coding_projects folder.
  2. Create a subfolder: mkdir flood_analysis && cd flood_analysis
  3. Create and activate a virtual environment using your chosen method.
  4. Confirm the (.venv) or (env-name) prefix appears in your terminal prompt.
  5. Run python --version from inside the active environment.
  6. Deactivate and confirm the prefix disappears.

Next Steps

With a clean, isolated sandbox in place, you are ready to start pulling libraries from the internet into it.