One of Python's great strengths is its ecosystem: hundreds of thousands of packages ready to install and use. But installing packages haphazardly into the system Python ends, sooner or later, in version conflicts and broken projects. In this lesson you'll learn the professional solution: virtual environments (venv), which isolate each project's dependencies, and pip, Python's package manager, together with the requirements.txt file that lets you reproduce an environment on any machine. Setting this up now, even though the Papyrus project doesn't need external packages yet, will give you the right habit from day one.

Contents

  1. The problem: shared dependencies and conflicts
  2. What a virtual environment is
  3. Creating, activating and deactivating an environment with venv
  4. pip: installing, listing and uninstalling packages
  5. requirements.txt: reproducible environments
  6. Good practices
  7. Alternatives worth knowing about: conda and poetry

The problem: shared dependencies and conflicts

Imagine this very real scenario:

  • For the Papyrus project you install a reporting package, version 2.0.
  • Months later, for another project, you need the same package but in version 3.0 (with incompatible changes).
  • If both projects share the same Python installation, they can't coexist: upgrading breaks Papyrus; not upgrading blocks the new project.

This is colloquially called dependency hell. And it has a second front: if you install everything into the operating system's Python, you can even interfere with tools of the system itself that depend on it (some Linux distributions outright block it with an externally-managed-environment error).

The solution is conceptually simple: each project gets its own isolated copy of the Python environment, with its own packages and versions.

flowchart TB
    subgraph System
        P["System Python\n(clean, no project packages)"]
    end
    subgraph "Papyrus project"
        V1[".venv\nreporting-package 2.0"]
    end
    subgraph "Another project"
        V2[".venv\nreporting-package 3.0"]
    end
    P -.creates.-> V1
    P -.creates.-> V2

What a virtual environment is

A virtual environment is a folder inside your project that contains:

  • A copy of (or link to) the Python interpreter.
  • Its own folder of installed packages, independent of the system's and of other environments'.
  • Activation scripts that temporarily "redirect" the python and pip commands to that environment.

Key points to understand it well:

  • It's not a virtual machine or anything heavyweight: it's basically a folder with files. Creating one takes seconds.
  • While an environment is activated, everything you install with pip lands inside it, without touching anything else.
  • If an environment gets broken, you delete the folder and create another one. Nothing on the system is affected.

The standard tool for creating them, venv, is included with Python 3: there's nothing to install.

Creating, activating and deactivating an environment with venv

Creating

Move into your project folder (the papyrus folder you created in lesson 01-02) and run:

cd papyrus
python -m venv .venv

Breaking down the command:

  • python -m venv — runs the venv module that ships with Python (-m means "run this module"; you'll understand modules better in module 3 of the course).
  • .venv — the name of the folder where the environment will be created. It's the most widespread conventional name (the leading dot marks it as an "internal working" folder); you'll also see venv or env.

After a few seconds you'll have a .venv folder inside the project. Don't edit anything inside it: it's tool territory.

Activating

Activating the environment means that, in that terminal, python and pip become the environment's own. The command depends on the system:

System and shell Activation command
Windows — PowerShell .venv\Scripts\Activate.ps1
Windows — CMD (Command Prompt) .venv\Scripts\activate.bat
macOS / Linux — bash or zsh source .venv/bin/activate

On Windows (PowerShell):

PS C:\projects\papyrus> .venv\Scripts\Activate.ps1
(.venv) PS C:\projects\papyrus>

On macOS/Linux:

$ source .venv/bin/activate
(.venv) $

The unmistakable sign that it's active is the (.venv) prefix in the terminal prompt. From that moment on:

(.venv) $ python --version   # the environment's Python
(.venv) $ pip --version      # the environment's pip (installs INSIDE .venv)

Note for Windows/PowerShell: if an error about "running scripts is disabled" appears when activating, run Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser once and try again. It's a PowerShell protection, not a Python failure.

Note for VS Code: when you open the project folder, VS Code usually detects .venv and asks whether you want to use it as the interpreter. Say yes: that way the editor and its integrated terminal will use the environment automatically. If it doesn't ask, press Ctrl+Shift+P → "Python: Select Interpreter" and choose the one in .venv.

Deactivating

To go back to the system Python in that terminal:

(.venv) $ deactivate
$

The prefix disappears. The environment is not deleted: it just stops being active. The next time you work on the project, you activate it again. And if some day you want to truly remove it, just delete the .venv folder.

The daily work cycle, summarized:

flowchart LR
    A["cd papyrus"] --> B["Activate .venv"]
    B --> C["Work:\npython, pip..."]
    C --> D["deactivate\n(or close the terminal)"]
    D -.the next day.-> A

pip: installing, listing and uninstalling packages

pip is Python's package manager: it downloads packages from the official PyPI repository (Python Package Index, https://pypi.org, with hundreds of thousands of published packages) and installs them into the active environment.

With the .venv environment activated, the essential commands:

Installing a package

pip install cowsay

(cowsay is a joke package, perfect for practicing risk-free: it makes a text-art cow "say" things.) pip downloads the package and its dependencies and installs them into .venv. Let's try it:

>>> import cowsay
>>> cowsay.cow("Welcome to Papyrus")
  __________________
| Welcome to Papyrus |
  ==================
                  \
                   \
                     ^__^
                     (oo)\_______
                     (__)\       )\/\
                         ||----w |
                         ||     ||

The import statement (which you'll study in depth in module 3) is how you use an installed package from your code.

You can also install a specific version, something key for reproducibility:

pip install cowsay==6.1        # exactly 6.1
pip install "cowsay>=6.0"      # 6.0 or later

Seeing what's installed

pip list
Package Version
------- -------
cowsay  6.1
pip     24.0

And for the details of a specific package (version, summary, dependencies):

pip show cowsay

Freezing versions

pip freeze
cowsay==6.1

pip freeze is like pip list, but in "reinstallable" format (package==version). It's the basis for the requirements.txt coming up next.

Uninstalling

pip uninstall cowsay

pip will ask for confirmation (y) and remove the package from the environment.

Command What it's for
pip install <package> Install the latest version
pip install <package>==X.Y Install an exact version
pip list List what's installed, in table format
pip show <package> Details of an installed package
pip freeze List what's installed in package==version format
pip uninstall <package> Uninstall

requirements.txt: reproducible environments

Imagine you share the Papyrus project with someone else (or with your own computer a year from now). The .venv folder is not shared (it's heavy and machine-specific); what you share is the dependency list: the requirements.txt file.

Generating it

With the environment activated and the packages you use installed:

pip freeze > requirements.txt

The > symbol redirects the command's output into the file. The result is a text file at the project root:

cowsay==6.1

Each line is a package with its exact ("frozen") version: the guarantee that another environment will install exactly the same thing.

Using it to recreate the environment

Whoever receives the project (or you yourself on another machine) only needs:

cd papyrus
python -m venv .venv
# ...activate the environment for their system...
pip install -r requirements.txt

The -r option means "install everything this file lists". In three commands, an environment identical to the original.

The project's complete flow

flowchart LR
    A["pip install package"] --> B["pip freeze > requirements.txt"]
    B --> C["Share the project\n(without the .venv folder)"]
    C --> D["python -m venv .venv\n+ activate"]
    D --> E["pip install -r requirements.txt"]

Keep requirements.txt up to date: every time you install or uninstall a package relevant to the project, run pip freeze > requirements.txt again.

Good practices

  • One virtual environment per project, always. Even if the project is small. Creating a .venv takes 10 seconds; untangling a version mess takes entire afternoons.
  • Don't install packages into the system Python. The "global" Python should stay clean, used only for creating environments. If you ever run pip install and don't see (.venv) in the prompt, stop and activate the environment.
  • The environment folder is called .venv and lives at the project root. It's the convention that tools (VS Code included) detect automatically.
  • requirements.txt is shared; .venv is not. If you use git, add .venv/ to the project's .gitignore so it doesn't get pushed to the repository.
  • Don't edit anything inside .venv. It's regenerated, not repaired: whenever anything strange happens, delete the folder and recreate it from requirements.txt.
  • Check where you're installing. pip --version shows the path of the active pip; if it points inside your project, all is well.
  • Pin versions in serious projects. pip freeze with == guarantees the project will work the same six months from now, even if the packages have published new versions.

Alternatives worth knowing about: conda and poetry

venv + pip is the standard kit and it's all you need in this course. But in the real world you'll hear about other tools, and it's worth having heard of them:

Tool What it brings Where you'll see it
venv + pip The standard included with Python. Simple and universal. This course and most projects
conda Environment and package manager geared towards data science; it also installs non-Python dependencies (compiled numerical libraries). Scientific and data analysis environments
poetry Modern dependency management with pyproject.toml files, advanced version resolution and project packaging. Professional projects and published libraries

We won't study them in this course: everything we do works with venv and pip. If a team or tutorial later uses conda or poetry, the concepts you've just learned (isolated environment, dependency list, pinned versions) are exactly the same; only the commands change.

Common Mistakes and Tips

  • Installing without activating the environment: the most frequent mistake. The package ends up in the system Python and your project "mysteriously" can't find it (or the other way round). Always look for the (.venv) prefix before a pip install.
  • Opening a new terminal and forgetting to reactivate: activation is per terminal and per session. New (or restarted) terminal = activate again.
  • ModuleNotFoundError: No module named '...' when running your script: it almost always means the package is installed in another environment (or in none), or that VS Code is using an interpreter other than your .venv's. Check "Python: Select Interpreter".
  • A "running scripts is disabled" error in PowerShell: apply the Set-ExecutionPolicy given in the activation section; it's a PowerShell thing, not your installation.
  • Pushing .venv to git or emailing it: it's heavy and useless outside your machine. requirements.txt is what's portable.
  • Renaming or moving the .venv folder: environments contain internal absolute paths and stop working. If you need to move one: delete and recreate (with requirements.txt it's two commands).
  • Tip: create the environment for your papyrus folder now and activate it every time you work on the course, even if you barely install anything for the moment. When we install Flask, pandas and friends in modules 10 and 11, the habit will already be in place.

Exercises

Exercise 1

In your project's papyrus folder: create a virtual environment called .venv, activate it, check with pip list that it's (almost) empty and deactivate it. Note down the exact commands you used on your operating system.

Exercise 2

With the Papyrus environment activated: install the cowsay package, check with pip show cowsay which version you have, generate the project's requirements.txt and display its contents in the terminal.

Exercise 3

Simulate "handing over" the project: deactivate and delete the entire .venv folder (relax: that's what the exercise is for), and rebuild the environment from scratch using only requirements.txt. Finish by checking with pip list that cowsay got installed again.

Solutions

Solution 1

On Windows (PowerShell):

cd papyrus
python -m venv .venv
.venv\Scripts\Activate.ps1
pip list
deactivate

On macOS/Linux:

cd papyrus
python3 -m venv .venv
source .venv/bin/activate
pip list
deactivate

pip list in a freshly created environment shows only pip (and in some versions, setuptools): that's the proof that the environment is clean and isolated.

Solution 2

With (.venv) visible in the prompt:

pip install cowsay
pip show cowsay
pip freeze > requirements.txt

To view the file's contents: type requirements.txt on Windows or cat requirements.txt on macOS/Linux. It should contain something like:

cowsay==6.1

Solution 3

deactivate

Deleting the folder: Remove-Item -Recurse -Force .venv in PowerShell (or delete it from the file explorer), rm -rf .venv on macOS/Linux. Then, the rebuild:

python -m venv .venv
# activate for your system (see solution 1)
pip install -r requirements.txt
pip list

pip list shows cowsay again, in the exact version recorded in requirements.txt. You've just demonstrated the lesson's central idea: the environment is disposable; the dependency list is what's valuable.

Conclusion

With this lesson you close the introductory module equipped like a professional: you know why dependencies are isolated, you create and manage environments with venv (create, activate per system, deactivate), you handle pip (install, list, show, freeze, uninstall) and you make your projects reproducible with requirements.txt, following the good practices of one environment per project and an always-clean system Python. You've also heard of conda and poetry, the alternatives you'll come across out there.

The Papyrus project now has everything it needs: a complete development environment, its first scripts (welcome, catalog, interactive book card) and a virtual environment ready to grow. In the next module, Control Structures, your programs will start making decisions and repeating tasks: conditionals to know whether something is in stock, loops to walk through the entire catalog, and much more. That's where programming starts to feel like a superpower.

Python Programming Course

Module 1: Introduction to Python

Module 2: Control Structures

Module 3: Functions and Modules

Module 4: Data Structures

Module 5: Object-Oriented Programming

Module 6: File Handling

Module 7: Error and Exception Handling

Module 8: Advanced Topics

Module 9: Testing and Debugging

Module 10: Web Development with Python

Module 11: Data Science with Python

Module 12: Final Project

© Copyright 2026. All rights reserved