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
- The problem: shared dependencies and conflicts
- What a virtual environment is
- Creating, activating and deactivating an environment with
venv - pip: installing, listing and uninstalling packages
requirements.txt: reproducible environments- Good practices
- 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
pythonandpipcommands 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
piplands 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:
Breaking down the command:
python -m venv— runs thevenvmodule that ships with Python (-mmeans "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 seevenvorenv.
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):
On macOS/Linux:
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 CurrentUseronce 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
.venvand 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, pressCtrl+Shift+P→ "Python: Select Interpreter" and choose the one in.venv.
Deactivating
To go back to the system Python in that terminal:
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
(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:
__________________
| 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:
Seeing what's installed
And for the details of a specific package (version, summary, dependencies):
Freezing versions
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 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:
The > symbol redirects the command's output into the file. The result is a text file at the project root:
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.txtThe -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
.venvtakes 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 installand don't see(.venv)in the prompt, stop and activate the environment. - The environment folder is called
.venvand lives at the project root. It's the convention that tools (VS Code included) detect automatically. requirements.txtis shared;.venvis not. If you use git, add.venv/to the project's.gitignoreso 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 fromrequirements.txt. - Check where you're installing.
pip --versionshows the path of the active pip; if it points inside your project, all is well. - Pin versions in serious projects.
pip freezewith==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 apip 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-ExecutionPolicygiven in the activation section; it's a PowerShell thing, not your installation. - Pushing
.venvto git or emailing it: it's heavy and useless outside your machine.requirements.txtis what's portable. - Renaming or moving the
.venvfolder: environments contain internal absolute paths and stop working. If you need to move one: delete and recreate (withrequirements.txtit's two commands). - Tip: create the environment for your
papyrusfolder 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):
On macOS/Linux:
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:
To view the file's contents: type requirements.txt on Windows or cat requirements.txt on macOS/Linux. It should contain something like:
Solution 3
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 listpip 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
- Introduction to Python
- Setting Up the Development Environment
- Python Syntax and Basic Data Types
- Variables and Constants
- Basic Input and Output
- Virtual Environments and Package Management
Module 2: Control Structures
Module 3: Functions and Modules
- Defining Functions
- Function Arguments
- Lambda Functions
- Modules and Packages
- Standard Library Overview
Module 4: Data Structures
Module 5: Object-Oriented Programming
Module 6: File Handling
Module 7: Error and Exception Handling
- Introduction to Exceptions
- Handling Exceptions
- Raising Exceptions
- Custom Exceptions
- Best Practices and Error Logging
Module 8: Advanced Topics
- Type Hints
- Decorators
- Generators
- Context Managers
- Concurrency: Threads and Processes
- Asyncio for Asynchronous Programming
Module 9: Testing and Debugging
- Introduction to Testing
- Unit Testing with unittest
- Testing with pytest
- Test-Driven Development
- Debugging Techniques
- Using pdb for Debugging
Module 10: Web Development with Python
- Introduction to Web Development
- Flask Framework Fundamentals
- Building REST APIs with Flask
- Introduction to Django
- Building Web Applications with Django
Module 11: Data Science with Python
- Introduction to Data Science
- NumPy for Numerical Computing
- Pandas for Data Manipulation
- Matplotlib for Data Visualization
- Introduction to Machine Learning with scikit-learn
