Try 10 focused PCAP-31-03 questions on Section 1: Modules and Packages, with explanations, then continue with IT Mastery.
Open the matching IT Mastery practice page for timed mocks, topic drills, progress tracking, explanations, and full practice.
| Field | Detail |
|---|---|
| Exam route | PCAP-31-03 |
| Topic area | Section 1: Modules and Packages |
| Blueprint weight | 12% |
| Page purpose | Focused sample questions before returning to mixed practice |
Use this page to isolate Section 1: Modules and Packages for PCAP-31-03. Work through the 10 questions first, then review the explanations and return to mixed practice in IT Mastery.
| Pass | What to do | What to record |
|---|---|---|
| First attempt | Answer without checking the explanation first. | The fact, rule, calculation, or judgment point that controlled your answer. |
| Review | Read the explanation even when you were correct. | Why the best answer is stronger than the closest distractor. |
| Repair | Repeat only missed or uncertain items after a short break. | The pattern behind misses, not the answer letter. |
| Transfer | Return to mixed practice once the topic feels stable. | Whether the same skill holds up when the topic is no longer obvious. |
Blueprint context: 12% of the practice outline. A focused topic score can overstate readiness if you recognize the pattern too quickly, so use it as repair work before timed mixed sets.
These questions are original IT Mastery practice items aligned to this topic area. They are designed for self-assessment and are not official exam questions.
Topic: Section 1: Modules and Packages
A developer organizes a small package like this:
# geometry/circle.py
class Circle:
def __str__(self):
return "circle"
# geometry/__init__.py
from .circle import Circle
# main.py
from geometry import Circle
print(Circle.__module__)
What is the role of geometry/__init__.py in this example?
Options:
A. It changes Circle.__module__ to geometry.
B. It holds shared class variables for every package class.
C. It exposes Circle in the package namespace during import.
D. It calls Circle() automatically when geometry is imported.
Best answer: C
Explanation: When a package is imported, Python executes its __init__.py file. In this example, that file imports Circle from the submodule into the package namespace, so from geometry import Circle works directly.
__init__.py is package-level initialization code. When Python imports geometry, it executes geometry/__init__.py, and any names imported or assigned there become available as attributes of the package. Here, from .circle import Circle makes Circle accessible as geometry.Circle, which is why from geometry import Circle succeeds.
This file does not instantiate the class, manage class variables, or rewrite introspection metadata. The class was defined in geometry.circle, so Circle.__module__ still reflects that defining module. Methods such as __str__() belong to the class definition itself and are unrelated to the role of __init__.py.
The key idea is that __init__.py can initialize a package and control what the package exposes.
__init__.py is a package module, not a special container for class attributes.Topic: Section 1: Modules and Packages
A developer imports a simple user-defined module named toolbox and checks it in the REPL:
import toolbox
print(dir(toolbox))
['__doc__', '__file__', '__name__', 'build', 'version']
Which TWO statements are justified by this result?
Options:
A. build must be a zero-argument function.
B. version must be a string constant.
C. toolbox.build is a currently available module attribute.
D. The list is complete documentation of toolbox behavior.
E. The output does not show how build should be called.
F. The list shows which sys.path entry supplied toolbox.
Correct answers: C and E
Explanation: From this result, you can safely infer namespace information: build and version are names exposed by toolbox right now. You cannot infer parameter lists, object types, return values, or which sys.path location supplied the module from dir() alone.
dir() is mainly a namespace inspection tool. For a normal module, it shows the names currently available on that module object, so seeing build means the module exposes an attribute with that name. But the list does not describe semantics: it does not tell you whether build is a function, class, or other object, and it does not reveal parameters, return values, side effects, or possible exceptions.
It also does not show how Python found the module during import. Information about import search locations belongs to sys.path, and the actual loaded file path would require checking something like toolbox.__file__, not just reading the name list from dir().
Treat dir() as a discovery aid for names, not as complete API or behavior documentation.
build is a zero-argument function fails because dir() does not show callable signatures.version must be a string fails because the list shows only names, not object types.sys.path entry fails because dir() does not report where the module was found.Topic: Section 1: Modules and Packages
A developer imports a user-defined module for the first time:
import tools
After the import, the project directory looks like this:
project/
tools.py
__pycache__/
tools.cpython-311.pyc
What is the purpose of the __pycache__ directory?
Options:
A. It records the directories Python searched in sys.path.
B. It saves the names returned by calling dir() on the module.
C. It stores compiled bytecode files for faster future imports.
D. It keeps backup copies of the original module source files.
Best answer: C
Explanation: The __pycache__ directory is used to store cached bytecode files such as .pyc files created when a module is imported. Python can reuse that bytecode later, which can speed up subsequent imports when the source has not changed.
When Python imports a module, it may compile the module’s source code into bytecode and save that bytecode in a .pyc file inside __pycache__. The cache file name often includes information about the Python implementation or version, such as tools.cpython-311.pyc.
This directory is not for source backups, search-path tracking, or namespace inspection results. Its job is simply to cache compiled module bytecode so Python can avoid recompiling unchanged source on later imports. The closest distractor is the idea of a backup copy, but __pycache__ is about execution efficiency, not source preservation.
__pycache__ stores compiled bytecode, not copies of tools.py.sys.path record is wrong because Python’s module search path is maintained separately and not written there.dir() results is wrong because dir() inspects names at runtime and does not create cached listings in __pycache__.Topic: Section 1: Modules and Packages
A developer runs this standalone script and gets NameError: name 'random' is not defined.
import random as rnd
nums = [rnd.randint(1, 3) for _ in range(4)]
print(random.choice(nums))
Which change correctly fixes the error while keeping the same behavior?
Options:
A. Replace import random as rnd with from random import choice.
B. Replace random.choice(nums) with rnd.choice(nums).
C. Replace rnd.randint(1, 3) with random.randint(1, 3).
D. Replace print(random.choice(nums)) with print(choice(nums)).
Best answer: B
Explanation: import random as rnd creates the local name rnd, not random. Since the script later uses random.choice(nums), it refers to a name that was never imported, so the call must use the alias.
The key concept is namespace binding with import ... as .... In a standalone script, import random as rnd adds only rnd to the current namespace and binds it to the random module. It does not also create a second local name called random.
That is why rnd.randint(...) works but random.choice(...) raises NameError. The correct fix is to use the same alias consistently:
import random as rnd
nums = [rnd.randint(1, 3) for _ in range(4)]
print(rnd.choice(nums))
A common mistake is assuming the original module name remains available automatically after aliasing, but it does not.
from random import choice removes the alias rnd, so rnd.randint(...) would fail.choice(nums) directly would still fail because choice was not imported into the local namespace.rnd.randint(...) to random.randint(...) repeats the same mistake by using an undefined local name.Topic: Section 1: Modules and Packages
A developer keeps the existing error handling but needs this function to return the smallest integer greater than or equal to delta for any numeric input, using only the already imported math module.
import math
def normalize(delta):
try:
return ???
except ValueError as err:
print(err)
return None
finally:
print("checked")
Which expression should replace ????
Options:
A. math.ceil(delta)
B. math.floor(delta)
C. math.trunc(delta)
D. math.fabs(delta)
Best answer: A
Explanation: The required operation is the mathematical ceiling: the least integer that is not smaller than the input. With only import math available, math.ceil(delta) is the correct choice and fits the existing try/except/finally structure unchanged.
The core concept is matching the wording of the calculation to the correct math function. math.ceil(x) returns the smallest integer greater than or equal to x, so it is the proper choice whenever the requirement says to round a value up.
math.floor(x) does the opposite by returning the greatest integer less than or equal to x. math.trunc(x) removes the fractional part toward zero, which is different from a ceiling for many negative numbers. math.fabs(x) returns the absolute value as a float, not an integer rounded upward.
The try/except/finally block is just surrounding context here; it does not change which math function performs the requested calculation.
math.floor() rounds down, not up.math.trunc() drops the fractional part toward zero, so it is not a true ceiling.math.fabs() returns absolute value and does not perform integer rounding.Topic: Section 1: Modules and Packages
A developer runs /project/app/main.py directly. The file /project/shared/tools.py exists, and neither /project nor /project/shared is already on sys.path. This code fails with ModuleNotFoundError:
import sys
import tools
print(tools.NAME)
Which change is the best fix?
Options:
A. Insert sys.append("/project/shared") before import tools.
B. Replace import tools with from sys import tools.
C. Replace import tools with from shared import tools.
D. Insert sys.path.append("/project/shared") before import tools.
Best answer: D
Explanation: Python searches for modules in the directories listed in sys.path. Because tools.py is stored in /project/shared, that directory must be added to sys.path before import tools runs. sys.path is a list, so append() is the appropriate operation.
sys.path is the module search path: a list of directory strings that Python checks when it executes an import. In this scenario, tools.py is in /project/shared, but that directory is not one of the places Python is currently searching, so import tools raises ModuleNotFoundError.
path attribute of the sys module.append() to add /project/shared.import tools.After that, Python can search /project/shared and load tools.py as the module tools. Import statements use module names, not file paths, and append() belongs to sys.path, not to the sys module.
tools from sys fails because tools is not a name defined in the sys module.append() on sys fails because the searchable list is sys.path, not sys itself.from shared import tools would require /project to be on sys.path, which the stem says is not true.Topic: Section 1: Modules and Packages
A developer needs to choose 3 different backup servers from a list, with no repeats. The current code is broken:
import random
servers = ["s1", "s2", "s3", "s4", "s5"]
picked = random.choice(servers, 3)
print(picked)
Which replacement for the picked = ... line is the best fix?
Options:
A. picked = sample(servers, 3)
B. picked = random.choice(servers)
C. picked = random.choices(servers, k=3)
D. picked = random.sample(servers, 3)
Best answer: D
Explanation: random.sample(population, k) is the correct API when you need k unique elements chosen without replacement. Because the code uses import random, the function must be called as random.sample(...).
The core concept is choosing unique items without replacement from the random module. random.choice() returns a single element, so it cannot directly produce three distinct servers. In this case, the correct fix is to replace the broken call with random.sample(servers, 3), which returns a list of three different elements from the given population.
import random means you access functions with the module prefix, such as random.sample(...).sample(population, k) selects k unique items.The closest distractor is the call to random.choices(...), but that function samples with replacement, so duplicates can appear.
random.choices mismatch can return the same server more than once, so it does not guarantee unique results.sample(...) is not defined in the local namespace after only import random.Topic: Section 1: Modules and Packages
A developer has this project layout:
project/
main.py
bakery/
prices.py # TAX = 0.23
main.py contains:
from bakery import TAX
print(TAX)
Running main.py raises an import error. Many existing modules already use from bakery import TAX, so the team wants a package-level fix without changing those imports. What is the best correction?
Options:
A. Add bakery/__init__.py with from .prices import TAX
B. Change main.py to import bakery.prices as TAX
C. Change main.py to from prices import TAX
D. Add bakery/__init__.py with import prices
Best answer: A
Explanation: from bakery import TAX expects TAX to be available in the bakery package namespace. Adding bakery/__init__.py and importing TAX there exposes the name at package level and preserves all existing imports.
__init__.py is the package initialization file. In this scenario, Python imports the bakery package first, then looks for TAX inside that package namespace because the code uses from bakery import TAX. Adding bakery/__init__.py with from .prices import TAX makes the constant available directly from the package.
from .prices import TAX is a relative import from a module inside the same package.Changing the caller to import prices.py directly would bypass the package-level design the stem asks you to preserve.
from prices import TAX treats prices as a top-level module instead of a module inside bakery.import bakery.prices as TAX binds TAX to the module object, not to the constant value.import prices inside __init__.py is the wrong import target for a sibling module in this package layout.TAX from __init__.py preserves from bakery import TAX across existing files.Topic: Section 1: Modules and Packages
During a deterministic test run, tests/test_picker.py imports picker and calls sample_ids() twice. The team wants every fresh program start to produce the same two lists, but the second call in the same run must continue the pseudo-random sequence rather than restart it.
# picker.py
import random
def sample_ids():
return [random.randint(100, 999) for _ in range(3)]
Which change best meets this requirement?
Options:
A. Add random.seed(7) as the first line inside sample_ids().
B. Add random.seed() once after import random.
C. Add random.seed(7) once after import random.
D. Add seed(7) once after import random.
Best answer: C
Explanation: random uses a pseudo-random generator whose output depends on its seed. Calling random.seed(7) once before generating values gives the same starting state on each fresh run, while later calls in that run continue from the current state.
The core concept is that Python’s random module is deterministic after you set a fixed seed. A seed initializes the generator’s internal state, so using the same seed at the start of each fresh program run produces the same sequence of values every time.
Because the module was imported with import random, the function must be called with its qualified name: random.seed(...).
7 for reproducible tests.The closest trap is reseeding inside sample_ids(), which repeats the beginning of the sequence on every call instead of continuing it.
seed(7) fails because only the module name was imported, so seed is not available directly.sample_ids() restarts the generator for each call, so the sequence does not continue within one run.random.seed() without an argument does not create a fixed, repeatable test sequence across fresh runs.Topic: Section 1: Modules and Packages
Two files are in the same directory. What is printed when main.py is run?
# tools.py
label = "PCAP"
def show():
return label.lower()
# main.py
import tools
from tools import label
print(label)
print(tools.label)
try:
print(show())
except NameError:
print("no-show")
print(tools.show())
Options:
A. The program prints: PCAP, PCAP, pcap, pcap.
B. The program prints three lines, then raises AttributeError at tools.show().
C. The program prints: PCAP, PCAP, no-show, pcap.
D. The program raises NameError before printing anything.
Best answer: C
Explanation: import tools makes only the module name tools available in main.py. from tools import label adds label directly to the current namespace, but it does not add show, so show() fails while tools.show() succeeds.
The key idea is that the two import forms create different names in the importing module.
import tools binds one local name: tools. To reach objects from that module, you use qualified names like tools.label and tools.show().
from tools import label binds a second local name: label. That is why print(label) works directly. But show was never imported into main.py as a standalone name, so show() raises NameError. The except NameError block catches that and prints no-show. Execution then continues, and tools.show() returns the lowercase form of "PCAP", which is pcap.
So the output is two PCAP lines, then no-show, then pcap.
import tools does not make show a standalone local name.label is incorrect because from tools import label places label directly in main.py.show is defined inside tools, so tools.show() is valid.Use the PCAP-31-03 Practice Test page for the full IT Mastery route, mixed-topic practice, timed mock exams, explanations, and web/mobile app access.
Try PCAP-31-03 on Web View PCAP-31-03 Practice Test
Read the PCAP-31-03 Cheat Sheet on Tech Exam Lexicon, then return to IT Mastery for timed practice.