Virtual Environments and Dependencies
Create isolated project environments, install and record dependencies deliberately, distinguish applications from libraries, and make setup reproducible.
Before this lesson
Explain environment isolation
Record dependency intent
Design reproducible project setup
The short answer
A virtual environment gives a project its own Python executable and installed packages. Create one per project, activate it for local commands, record direct dependencies and compatible versions, and document the exact test and run commands.
Build the mental model
Installing every package globally makes projects compete over versions and hides undeclared requirements. venv creates an environment directory that should not be committed. The source and dependency declaration belong in version control.
The central idea in this lesson is project environments. Read the rule, predict a concrete outcome, and then run the smallest example that can confirm or reject the prediction. This separates knowledge from familiarity with syntax.
Make the design choice explicit
Applications often pin a resolved environment for repeatable deployment; libraries usually declare compatible ranges because they must coexist with consumer dependencies. Tools such as pip-tools, uv, Poetry, or PDM can manage resolution, but understand the environment model beneath them.
from importlib.metadata import version
print("Python project checklist:")
for item in ["isolated environment", "declared dependencies", "repeatable tests"]:
print(f"- {item}")
print("pip version:", version("pip"))Trace the example before running it. Identify each input, transformation, returned value, and side effect. Then change one boundary value and explain why the new behavior follows from the rule rather than memorizing the output.
Recognize failure modes
Do not commit credentials, .env files containing secrets, or the virtual environment directory. Avoid importing a local file whose name shadows a standard-library or third-party module. Recreate the environment periodically to prove setup instructions work.
Use a professional practice loop
Turn the concept into a repeatable workflow: write down the expected behavior, implement one coherent change, run a representative example, and retain a regression check. If the result surprises you, capture the exact input and error before changing anything.
Review the program for names, boundaries, and hidden side effects. A solution is complete when another developer can understand its contract, reproduce its setup, and verify both the successful path and one meaningful failure path.
Quick knowledge check
Answer before you reveal.
01Why not commit the virtual environment directory?
It is platform-specific generated state; commit dependency declarations and recreate the environment instead.
02What four steps make the practice loop reliable?
Predict the behavior, make one coherent change, run it, and retain a check that detects regression.
Exercise
Practice challenge
Create a fresh sample project environment, record one runtime and one development dependency, and write reproducible install, run, and test commands.
Requirements
- The successful path produces the documented result
- At least one boundary or invalid case is handled deliberately
- Calculation or domain logic is separated from console interaction
Optional extension: Add one automated regression check for the most important rule.
Open in Python compilerLesson checkpoint
One small step locks it in
Mark this lesson complete, then keep the momentum going.
Clear up the details
Frequently asked questions
Is project environments only important in large programs?
No. Small programs reveal the same rules with less noise, and learning the rule early prevents fragile habits from becoming architecture.
Should I memorize every API used here?
No. Memorize the mental model and how to verify behavior. Use documentation for exact names and parameters when needed.
How do I know the exercise is finished?
Meet every success criterion, test at least one boundary or failure case, and explain why the output follows from the code.