pip & Package Installation - Python

  1. Which command correctly tells pip to install the requirements listed inside the file?
    Answer: python -m pip install -r requirements.txt When working with pip, it's important to distinguish between installing a package by name and installing from a requirements file. These are two different operations that require different syntax. The key flag here is -r, which stands for "requirements." When you run python -m pip install -r requirements.txt, you're explicitly telling pip to read the file and install each package listed inside it. This is the correct and standard workflow for Python projects — answer A is right. The original command in the passage, python -m pip install requirements.txt, fails because pip interprets requirements.txt as a package name to look up on PyPI, not a file to open. That's the exact trap the question is testing. B is wrong because pip import is not a valid pip subcommand at all — you can't "import" packages via pip. C uses --package, which doesn't exist as a pip flag; there's no such option in pip's interface. D scrambles the entire command structure — python -m requirements.txt would try to run requirements.txt as a Python module, and install -r at the end is syntactically meaningless. A useful memory trick: think of -r as "read this file." Whenever you see a requirements.txt in a project, the command to install from it is always pip install -r requirements.txt. This pattern appears constantly in real-world Python development, so it's worth memorizing cold — on exams and in practice, it's one of the most common pip operations you'll encounter.
  2. Which action most directly addresses the cause of the failed import?
    Answer: Rename the local requests.py file, clear its stale cache if necessary, and run the application again. When you see an import error like this, think about Python's module search order. Python resolves imports by scanning locations in a specific sequence: the current directory (or the script's directory) first, then any paths in PYTHONPATH, and finally site-packages where third-party packages live. This means a local file can silently "shadow" an installed package if they share the same name. That's exactly what's happening here. The project's requests.py is found before the installed requests package, so Python imports the wrong file. Answer A directly fixes the root cause: renaming the local file eliminates the naming conflict, and clearing any stale .pyc cache files in __pycache__ ensures Python doesn't continue using a cached version of the old name. Once the conflict is gone, the next import resolves correctly to site-packages. Answer B is a trap — reinstalling or upgrading the package doesn't change the search order. site-packages is still checked after the local directory, so the shadowing problem persists regardless of which version is installed. Answer C would actually make things worse, or at best create a messy workaround. Moving the package into the project directory doesn't resolve the naming conflict and breaks the package's intended installation structure. Answer D describes syntax that simply doesn't exist in Python. You cannot use import site-packages.requests — Python interprets the hyphen as subtraction, and this would raise a SyntaxError. As a study tip: whenever you encounter unexpected import behavior, immediately ask yourself "is there a local file or directory with the same name as the package I'm importing?" That naming conflict is one of the most common silent bugs in Python projects.
  3. Which command both expresses the required version constraint and avoids the shell misinterpreting it?
    Answer: python -m pip install "urllib3<2" When installing packages with pip, version specifiers like <, >, ==, and >= tell pip which versions are acceptable. The tricky part is that some of these characters have special meaning to the shell — specifically, < and > are used for input/output redirection. This question tests whether you understand both pip's version constraint syntax and shell quoting rules. The correct answer is D: python -m pip install "urllib3<2". Wrapping the entire package specifier in double quotes tells the shell to treat the < as a literal character rather than a redirection operator. Pip then receives urllib3<2 as its argument and correctly interprets it as "install any version of urllib3 that is strictly less than 2," which satisfies the compatibility requirement described. A is wrong because ==2 means exactly version 2, not below version 2. This would install a version that the application is explicitly incompatible with. B is wrong despite having the correct version logic (<2). Without quotes, the shell intercepts the < and tries to use 2 as an input file for the command, causing an error before pip even runs. Never pass unquoted < or > in a shell command. C is wrong on two counts: >2 specifies versions above 2, which is the opposite of what's needed, and while > in quotes would at least be parsed correctly by pip, the constraint itself is backwards. A good rule of thumb: whenever a pip version specifier contains < or >, always wrap it in quotes to prevent shell misinterpretation.
  4. Which command most directly installs requests for the interpreter that runs the application?
    Answer: /opt/project/.venv/bin/python -m pip install requests When working with Python virtual environments, the critical concept is that each environment has its own isolated interpreter and package directory. The command used to run a script determines which interpreter executes it — and that interpreter only sees packages installed in its associated environment. Here, the application runs with /opt/project/.venv/bin/python, meaning the virtual environment's interpreter is active. The error occurs because requests lives in /usr/local/lib/python3.x/site-packages — the system Python's package directory — not inside .venv. The fix is to install requests specifically for the .venv interpreter, which is exactly what B does. Running /opt/project/.venv/bin/python -m pip install requests invokes that environment's own pip module, guaranteeing the package lands in .venv/lib/.../site-packages where that interpreter can find it. A is wrong because running pip install requests from app.py's directory changes nothing — pip's behavior is determined by which Python environment it belongs to, not your working directory. This likely calls the system pip again. C is nonsensical syntax. Arguments after a script name are passed to the script itself, not to Python — so -m pip install requests would be received by app.py as command-line arguments, not executed by the interpreter. D invents a flag that doesn't exist. pip show has no --location option that redirects installation; pip show only displays information about already-installed packages. A useful rule of thumb: always pair your interpreter with its own pip using python -m pip. This guarantees you're installing to exactly the environment that will run your code.
  5. Which correction best uses the package's declared dependency information?
    Answer: Run python -m pip install analyst without --no-deps so pip can process the declared dependency. When working with pip and package dependencies, it's essential to understand what "declared dependencies" actually are and how pip normally handles them. Package authors list dependencies (like helperlib>=3) in their package metadata so that pip can automatically fetch everything needed — that's the whole point of the dependency system. The --no-deps flag tells pip to deliberately skip this automatic resolution and install only the named package. It's a power-user option for edge cases, not a default workflow. When you use it, you're essentially telling pip: "I'll handle the dependencies myself." If you haven't done that, imports will fail exactly as described in the passage. The fix, then, is simply to reinstall without that flag — run pip install analyst normally, letting pip read the package's declared metadata and pull in helperlib>=3 automatically. That's why C is correct: it removes the artificial restriction and lets pip do its job. A is wrong because Python's import statement has no syntax for version constraints like >=3 — that's pip's job, not Python's, and imports don't trigger downloads at all. B is a trap: repeating the same command with --no-deps again will produce the same result, since the flag still suppresses dependency resolution on every run. D misunderstands what dependencies are — helperlib is a separate package that analyst relies on internally; renaming your import doesn't install anything or resolve that relationship. As a strategy tip: whenever you see --no-deps in a scenario where something is "missing," that flag is almost always the culprit — it's the one pip option that deliberately bypasses the dependency mechanism.
  6. What is the best explanation and correction?
    Answer: Virtual-environment activation is per shell; activate .venv in terminal B or invoke its Python directly. When working with Python virtual environments, the key concept to understand is scope of activation. A virtual environment is not a global system state — it's a shell-level configuration that modifies environment variables like PATH and PYTHONPATH for a single terminal session. This is exactly what's being tested here. When you activate .venv in terminal A and install httpx, that package lives inside .venv/lib/. Terminal A's shell knows to use .venv's Python interpreter because activation prepended .venv/bin/ to its PATH. Terminal B is a completely separate shell process with its own environment — it never ran activate, so its PATH still points to the system Python, which has no knowledge of httpx. The fix is simple: either run source .venv/bin/activate in terminal B, or invoke .venv/bin/python app.py directly. This makes A correct. B is wrong because package availability is tied to which interpreter you use, not which directory your script lives in. Moving app.py into .venv changes nothing about which Python runs it. C contains a partial truth — reinstalling httpx via terminal B's pip would technically work — but it's not the best explanation or correction. It treats the symptom (missing package) rather than addressing the root cause (wrong interpreter/environment). Running pip again wastes time and misses the real lesson. D is nonsense; import .venv is not valid Python syntax, and virtual environments don't self-activate on import. As a study tip, remember: activation is per shell, not per project. Any time you open a new terminal, assume the virtual environment is inactive until you explicitly activate it.
  7. Which workflow best resolves the problem while keeping the project's packages isolated?
    Answer: Create a virtual environment, use its Python to install dataviz, and run the project with that environment. When you see a question about package installation failures on shared systems, think about Python's virtual environment tool — its entire purpose is to create an isolated, user-owned Python installation that doesn't require system-level permissions. A virtual environment (python -m venv myenv) creates a self-contained directory with its own Python interpreter and pip. Because you own that directory, you can install packages freely without touching system paths or affecting other users. Running myenv/bin/pip install dataviz installs everything inside that folder, keeping the project perfectly isolated. This makes D the correct workflow — it solves the permission problem, satisfies the isolation requirement, and follows standard Python best practice. A is tempting but dangerously incomplete. Dropping a single source file next to your scripts ignores dataviz's declared dependencies, meaning the package almost certainly won't work. Manually omitting dependencies isn't a "fix" — it just trades one problem for several silent failures. B resolves the permission issue by brute force, but it violates the core requirement: isolation. Installing globally means every project on the machine shares that version of dataviz, creating potential conflicts and affecting other users — exactly the scenario you were asked to avoid. C shows a misunderstanding of how pip works. Moving the pip executable changes nothing about the installation target. Pip installs packages based on which Python interpreter it's associated with, not where the executable file lives. The system interpreter remains the target, so permission errors persist. As a study tip: whenever a Python question mentions "permissions," "shared systems," or "project isolation," virtual environments are almost always the answer. Know how to create one, activate it, and install packages inside it.
  8. Assuming the upgrade targeted the notebook's environment, what should the user do next?
    Answer: Restart the notebook kernel and import examplepkg again. When working with Python in a notebook environment, it's important to understand how the module import system interacts with package installation. Python loads a module into memory the first time it's imported, and that loaded version persists for the entire session — even if the underlying package files change on disk afterward. This is exactly what's happening in the passage. The upgrade succeeded at the file system level, but the notebook's kernel is still running the original imported module from memory. The fix is straightforward: restart the kernel, which clears all loaded modules from memory, then import examplepkg again. Python will now find and load version 2.0 from disk. This makes B the correct answer. A is wrong because importlib.install() doesn't exist — this is a made-up function designed to sound plausible. The real importlib module does have importlib.reload(), which can reload a module, but even that is not listed here. Watch out for distractors that invent realistic-sounding function names. C is wrong because the notebook's filename has absolutely no relationship to which version of a package Python imports. Package resolution depends on the environment's sys.path, not the notebook name. D is wrong because %pip show only displays metadata about an installed package — it does not trigger any module reloading or affect what's currently in memory. Displaying information about a package is entirely separate from the runtime import system. As a study tip, remember this pattern: installation changes disk, restart changes memory. Any time a question involves a package update not being reflected in a running session, the kernel restart is almost always the answer.
  9. Which command should the developer run from the project root?
    Answer: python -m pip install -e . When working with local Python packages during active development, the key concept is editable installs — a mode where pip links your source directory into the environment rather than copying files, so changes to your code are immediately reflected without reinstalling. The -e flag (short for --editable) is what enables this behavior. Running python -m pip install -e . tells pip to install the package found in the current directory (.) in editable mode, reading the project metadata from pyproject.toml automatically. After this single command, any script in the same virtual environment can import your package, and every source edit is instantly visible. That makes C the correct answer. Looking at the distractors: A (pip install pyproject.toml) passes the filename as if it were a package name or requirements file — pip doesn't accept a pyproject.toml file as a direct argument like this, so it would simply fail or attempt to find a package literally named "pyproject.toml" on PyPI. B (pip install --upgrade pip) upgrades pip itself, which has nothing to do with installing your local project — it's a maintenance command, not a project-installation command. D (python -m pyproject.toml install .) is syntactically nonsensical; pyproject.toml is a configuration file, not a Python module you can invoke with -m. A good memory anchor: the -e flag means "editable," and you always pair it with a path (usually . for the current directory). Whenever a question mentions ongoing edits staying visible without reinstalling, that's your signal to reach for pip install -e ..
  10. Which sequence correctly follows the installation and import workflow?
    Answer: Run python -m pip install beautifulsoup4, then import from bs4. When working with Python packages, you need to understand a crucial distinction: the distribution name (what you install via pip) and the import name (what you use in your code) are often different. This question tests whether you recognize that these two names don't have to match. BeautifulSoup is a classic example of this mismatch. The PyPI distribution is named beautifulsoup4 — this is the name the Python Package Index uses to catalog it, and the name pip needs to locate and download it. However, the package's author chose bs4 as the importable module name inside your Python environment. So the correct workflow is exactly what option A describes: install with python -m pip install beautifulsoup4, then import using from bs4 import BeautifulSoup. These are two separate namespaces that simply don't mirror each other. Option B gets it backwards — pip install bs4 won't find the correct package under that distribution name on PyPI, and beautifulsoup4 is not a valid import name. Option C is a near-miss trap: it uses the correct install command but then tries to import from beautifulsoup4, which doesn't exist as an importable module — you'd get a ModuleNotFoundError. Option D uses the outdated BeautifulSoup distribution name (an older, separate package) rather than the current beautifulsoup4, making the installation itself incorrect. As a study strategy, always check both the install name (from the project's setup or PyPI page) and the import name (from the project's usage examples or docs) — never assume they match. BeautifulSoup is the most famous example of this pattern, but it appears with many other libraries too.

Start this quiz