Courseiva

Python Institute Certified Professional in Python Programming 1 (PCPP1, PCPP-32-101) (PCPP1) (PCPP1) — Questions 76–150

290 questions total · 4 pages · All types, answers revealed

Page 1

Page 2 of 4

Page 3
76
MCQhard

A developer is writing a Python function that accepts a mutable default argument, such as `def add_item(item, items=[])`. A code reviewer flags this as a potential bug. Which statement best explains the issue and the recommended fix according to best practices?

A.The default list is copied for each call, so the only issue is performance; use a tuple for efficiency.
B.The default list is shared across all calls, so use `None` as the default and create a new list inside the function.
C.The default list is immutable, so it cannot be modified; use a tuple instead.
D.The default argument is re-evaluated on each call, so the code is safe; no change is needed.
AnswerB

In Python, default arguments are evaluated only once at function definition time. Using a mutable default like `[]` means the same list object is reused across all calls, leading to unintended persistence of data. The recommended fix is to use `None` as the default and then check `if items is None: items = []` inside the function. This ensures a fresh list is created for each call, avoiding shared state bugs.

Why this answer

Mutable default arguments are evaluated once at definition time, causing shared state across calls. The correct practice is to use `None` as a default and create a new mutable object inside the function. This avoids bugs where data unexpectedly persists.

Other options either misdiagnose the problem or propose ineffective solutions.

Exam trap

The trap here is thinking that default arguments are re-evaluated on each call, when they are actually evaluated once at function definition.

77
MCQmedium

You are building a Tkinter application with a Button widget that should run a long-running calculation when clicked, but the GUI freezes until the calculation finishes. Which approach best keeps the interface responsive while performing the calculation?

A.Run the calculation in a separate thread and update the GUI using a thread-safe mechanism such as a queue polled by after().
B.Call update_idletasks() inside the calculation loop to refresh the window.
C.Call the calculation function directly inside the button's command callback.
D.Use the after() method with a delay of zero to schedule the calculation repeatedly.
AnswerA

Tkinter is not thread-safe, so GUI updates must happen on the main thread. Running the heavy calculation in a worker thread keeps the event loop free to redraw and respond to input. The worker communicates results through a queue, and the main thread polls that queue using after(), performing widget updates safely on the main thread. This combination preserves responsiveness without violating Tkinter's threading constraints.

Why this answer

Tkinter widgets must be manipulated from the thread that created the Tk instance, which is normally the main thread running mainloop(). Performing a long computation in a button callback monopolizes that thread, freezing the interface. The reliable pattern is to execute the computation in a worker thread and pass results back through a thread-safe queue that the main thread inspects with after().

This keeps the event loop cycling and the GUI responsive.

Exam trap

The trap here is assuming that calling update_idletasks() or after() with a zero delay makes long-running work non-blocking, when in fact both still execute on the main event loop thread.

78
MCQeasy

You need to add a label that displays static text in your GUI. Which widget is most appropriate for this purpose?

A.tk.Message()
B.tk.Entry()
C.tk.Display()
D.tk.Label()
E.tk.Text()
AnswerD

tk.Label() renders static, non-editable text and accepts no user input, matching the requirement for a display-only label. Unlike Entry or Text, it exposes no editing or selection behaviour, so it is the minimal widget satisfying the static-text constraint.

Why this answer

tk.Label() is the canonical Tkinter widget for displaying static, non-editable text (or images) in a GUI. It supports options like text, font, fg, bg, and anchor, and is designed specifically for read-only display. For multi-line static text, tk.Message() is a variant, but tk.Label() is the general-purpose choice.

Exam trap

PCPP1 often tests the distinction between Label (static display) and Entry/Text (editable input) — candidates may confuse Message with Label or pick a fabricated widget like Display.

How to eliminate wrong answers

Option A is wrong because tk.Message() is a specialized widget for multi-line text that wraps automatically — it is less flexible than Label and not the general-purpose choice for static text. Option B is wrong because tk.Entry() is a single-line editable input field, not a display widget. Option C is wrong because tk.Display() does not exist in Tkinter — it is a fabricated widget name.

Option E is wrong because tk.Text() is a multi-line editable text area, not a static label.

79
MCQmedium

When using the __call__ method to implement a decorator, what does the decorator receive as an argument?

A.The arguments to the function.
B.The instance of the class.
C.The class object.
D.The function to be decorated.
AnswerD

A class defining `__call__` receives the function being decorated as its initialiser argument, storing it for later invocation. This satisfies the stem's requirement: the decorator object wraps the target function, then `__call__` intercepts subsequent calls, forwarding arguments and returning the wrapped result.

Why this answer

The decorator receives the function object that is being decorated as the argument to the constructor (if the decorator is a class instance) or directly if it is a function.

80
MCQmedium

You need to perform a HEAD request to check if a file exists on a server without downloading the body. How is this done with 'requests'?

A.requests.head(url)
B.requests.post(url, data={'type': 'head'})
C.requests.options(url)
D.requests.get(url, headers={'Method': 'HEAD'})
AnswerA

requests.head() issues an HTTP HEAD request, so the server returns only headers with no message body, satisfying the requirement to check file existence without downloading content. It mirrors requests.get() but uses the HEAD verb, which is the correct method for metadata-only checks.

Why this answer

The requests.head() method sends a HEAD request, which only retrieves headers.

81
MCQhard

You are working with a large XML file and need to extract specific elements efficiently without loading the entire document into memory. You decide to use the xml.etree.ElementTree module. Which of the following methods should you use to iterate over all 'book' elements in the document?

A.Use the findall() method on the root element to retrieve all 'book' elements at once.
B.Use the XMLPullParser to pull events and process 'book' elements as they are encountered.
C.Use the iterparse() function to process the XML incrementally and handle 'end' events for 'book' tags.
D.Use the parse() function and then iterate over the tree using a for loop.
AnswerC

iterparse() is designed for incremental parsing of large XML files. It generates events (start, end, start-ns, end-ns) and allows you to process elements as they are parsed. By listening for 'end' events and checking if the tag is 'book', you can extract each book element and then clear it to free memory. This is the most memory-efficient way to handle large files.

Why this answer

For memory-efficient parsing of large XML files, iterparse() is the recommended function. It allows incremental processing by generating events as elements are parsed. By handling 'end' events for 'book' tags and clearing elements, you can extract data without loading the entire document.

The other methods load the full document into memory, which is inefficient for large files.

Exam trap

The trap here is assuming that findall() or parse() are memory-efficient because they are commonly used, but they load the entire XML tree into memory.

82
MCQhard

Why does the __init__ method not return anything?

A.Because it is designed to initialize an existing instance.
B.Because of internal Python constraints.
C.To allow for multiple initialization.
D.Because it's a generator.
AnswerA

__init__ initialises an already-created instance in place, so it must return None; returning any other value raises TypeError. Object construction itself is handled by __new__, which allocates and returns the instance, so __init__ has nothing meaningful to return.

Why this answer

The __init__ method is for initialization only; the object creation is handled by __new__.

83
MCQeasy

What is the primary difference between the 'socket.AF_INET' and 'socket.AF_INET6' address families?

A.AF_INET6 supports UDP only
B.AF_INET requires a password
C.AF_INET is faster than AF_INET6
D.AF_INET is for IPv4; AF_INET6 is for IPv6
AnswerD

AF_INET selects the IPv4 protocol stack, expecting addresses as (host, port) tuples with 32-bit hosts; AF_INET6 selects IPv6, using 128-bit addresses and four-element tuples. The stem asks for the primary difference, which is precisely the IP version each family binds sockets to.

Why this answer

AF_INET is for IPv4, while AF_INET6 is for IPv6 addressing.

84
MCQhard

A developer implements a class `Vector` with `__add__` returning a new `Vector`, and also defines `__iadd__` that mutates `self` in place and returns `self`. A colleague writes `a = Vector(1,2); b = Vector(3,4); c = a; a += b`. What is the state of `c`?

A.`c` raises an AttributeError on access because `__iadd__` invalidates all prior references to the mutated object.
B.`c` now reflects the updated values because `__iadd__` mutated the shared object that `c` also references.
C.`c` is unchanged because `+=` always creates a new object, leaving the original binding intact.
D.`c` is unchanged because the augmented assignment rebinds `a` to a new object produced by `__add__`, ignoring `__iadd__`.
AnswerB

`a += b` invokes `Vector.__iadd__`, which mutates `self` and returns it. Because `c = a` binds `c` to the same object, the in-place mutation is visible through `c`. This aliasing effect is the defining behavior of in-place operators and can surprise developers who expect `+=` to rebind a new object.

Why this answer

Augmented assignment prefers the in-place method `__iadd__` over `__add__`. When `__iadd__` mutates the object and returns it, any other references to that same object see the updated state. This aliasing behavior is a common source of subtle bugs when mutable objects are shared between variables.

Exam trap

The trap here is believing that `+=` always produces a new object, when in fact `__iadd__` can mutate the existing instance in place.

85
MCQhard

In a multithreaded network application, you observe 'ConnectionResetError'. What is the most likely cause when using Python sockets?

A.The port is already in use by another process
B.The socket was never bound
C.The remote server closed the connection abruptly
D.The local thread pool is exhausted
AnswerC

ConnectionResetError is raised when the peer sends a TCP RST rather than a graceful FIN, which happens when the remote process terminates or drops the socket abruptly. This matches the stem's multithreaded socket scenario, where the server side closed without completing the normal shutdown handshake.

Why this answer

This occurs when the remote host closes the connection while the local end is still trying to send or receive data.

86
MCQhard

What is the purpose of the 'weakref' module in relation to the Observer pattern?

A.To allow private access to observers.
B.To ensure thread safety.
C.To prevent memory leaks.
D.To serialize observers.
AnswerC

Observers registered with a subject via strong references keep each other alive, so unregistered observers are never collected. weakref holds observers without incrementing their reference count, letting garbage collection reclaim them and preventing the memory leaks that accumulate over long-lived subjects.

Why this answer

It allows the subject to maintain references to observers without preventing their collection by the garbage collector.

87
MCQmedium

When using configparser, what happens if you attempt to read a configuration file that does not exist using the read() method?

A.It raises a FileNotFoundError.
B.It raises a configparser.Error.
C.It creates an empty configuration object.
D.It returns an empty list.
AnswerD

`read()` returns a list of filenames successfully parsed, so a missing file simply yields an empty list rather than raising an exception. This satisfies the stem's scenario because `configparser` deliberately treats absent files as non-fatal, letting callers supply defaults or fallback paths without wrapping the call in error handling.

Why this answer

The read() method returns an empty list and does not raise an exception.

88
MCQmedium

You are using the socket module to create a TCP client. After creating the socket object, which method call is required to establish a connection to a remote server listening on 192.168.1.50 at port 8080?

A.sock.bind(('192.168.1.50', 8080))
B.sock.accept()
C.sock.connect(('192.168.1.50', 8080))
D.sock.listen(1)
AnswerC

connect() takes a single tuple of (host, port) and performs the TCP three-way handshake, binding the client socket to the remote endpoint at 192.168.1.50:8080. Alternatives such as bind() or accept() serve server-side roles, so connect() is the only call that establishes the outbound connection required here.

Why this answer

For a TCP client socket, after creating the socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM), the connect() method is what initiates the TCP three-way handshake with the remote server. Passing a tuple of (host, port) — here ('192.168.1.50', 8080) — tells the OS to open a connection to that endpoint. This is the client-side counterpart to the server's bind/listen/accept sequence.

Exam trap

PCPP1 often tests confusion between client-side and server-side socket methods — candidates must remember that connect() is for clients and bind()/listen()/accept() are for servers, and that bind() does not establish a connection.

How to eliminate wrong answers

Option A is wrong because bind() is used on the server side (or to bind a client to a specific local address) to associate the socket with a local address and port; calling bind() with a remote IP does not establish a connection. Option B is wrong because accept() is a server-side call that blocks waiting for an incoming connection and returns a new socket plus the client address — it is meaningless on a client socket. Option D is wrong because listen() is also server-side; it puts a bound socket into a listening state so it can accept incoming connections, and it does nothing for an outbound client connection.

89
MCQmedium

You are writing a Python tool that must connect to a REST API over HTTPS. The API's server certificate is signed by an internal corporate CA whose root certificate is stored in a file named corp-ca.pem. You use the requests library and need the connection to be verified against that specific CA while still performing normal hostname checking. Which call accomplishes this?

A.requests.get(url, verify=False)
B.requests.get(url, proxies={'https': 'corp-ca.pem'})
C.requests.get(url, cert='corp-ca.pem')
D.requests.get(url, verify='corp-ca.pem')
AnswerD

Passing the path of a CA bundle to verify makes requests use exactly that file as the trust store, so the internal root is trusted while standard certificate and hostname validation still run. It is the documented way to point the library at a private CA without disabling security.

Why this answer

The verify parameter accepts either a boolean or a path to a CA bundle. Supplying the path to the corporate root certificate causes requests to trust that CA in addition to performing the usual certificate chain and hostname validation. Disabling verification, configuring a client certificate, or setting a proxy does not achieve trusted validation against a private CA.

Exam trap

The trap here is assuming that pointing cert or proxies at a CA file changes which certificate authority is trusted, when only verify accepts a CA bundle path.

90
MCQeasy

You are prototyping a Tkinter application and want a single-line input field where users can type a search term. The field should also show a placeholder-like behavior by pre-filling the text 'Search...' when the window opens. Which widget and option combination achieves this most directly?

A.An Entry widget with a StringVar whose initial value is 'Search...' and passed via the `textvariable` option.
B.A Text widget with `height=1` and the initial string passed as the first positional argument.
C.A Spinbox widget with `values=('Search...',)` and `state='readonly'` so the placeholder cannot be modified.
D.A Label widget with `textvariable` bound to a StringVar set to 'Search...' and made editable via `state=tk.NORMAL`.
AnswerA

Entry is the standard single-line input widget. Binding a StringVar initialized to 'Search...' through `textvariable` pre-fills the field and keeps the value synchronized for later reading. This is the most direct way to seed initial text while retaining two-way data binding, and it matches the single-line search field requirement exactly.

Why this answer

An Entry widget is the canonical single-line text input in Tkinter. Pairing it with a StringVar initialized to the placeholder text and connected via `textvariable` gives both an initial visible value and a live binding that the application can read or update. This directly satisfies the requirement of a pre-filled, editable search field without extra workarounds.

Exam trap

The trap here is reaching for Text or Label when the requirement is a single-line editable field with initial content, which is exactly Entry's role.

91
MCQeasy

A developer is writing a Python script and wants to ensure that lines do not exceed the recommended maximum length according to PEP 8. What is the maximum line length that PEP 8 recommends for code?

A.100 characters
B.80 characters
C.79 characters
D.120 characters
AnswerC

PEP 8 recommends limiting all lines to a maximum of 79 characters. This limit is intended to improve readability, especially when viewing code side-by-side or on smaller displays. It also allows for multiple files to be open simultaneously. While many modern projects relax this to 99 or 119 characters, the official PEP 8 guideline remains 79 for code and 72 for docstrings and comments.

Why this answer

PEP 8 recommends a maximum line length of 79 characters for code. This limit is intended to improve readability and allow for side-by-side viewing. It also accommodates smaller screens and terminals.

While some projects adopt longer limits like 99 or 119 characters, the official PEP 8 guideline is 79. Following this convention helps maintain consistency across Python codebases.

Exam trap

The trap here is rounding up to 80 characters, which is a common misconception but not what PEP 8 specifies.

92
MCQmedium

You are writing a Python script that must process a large text file line by line. The file is UTF-8 encoded, but some lines contain characters that are not representable in the default system encoding. You want to ensure that the script reads the file correctly on any platform. Which code correctly opens the file?

A.open('data.txt', 'r')
B.open('data.txt', 'r', errors='ignore')
C.open('data.txt', 'rb')
D.open('data.txt', 'r', encoding='utf-8')
AnswerD

Explicitly specifying `encoding='utf-8'` ensures that the file is decoded using UTF-8 regardless of the platform's default encoding. This is the recommended practice for text files to avoid `UnicodeDecodeError` on systems where the default encoding is not UTF-8, such as Windows with cp1252.

Why this answer

Specifying `encoding='utf-8'` when opening a text file ensures consistent decoding across platforms. Relying on the default encoding can cause errors on systems where the default is not UTF-8. The `errors` parameter should not be used to mask decoding issues when the goal is correct reading.

Exam trap

The trap here is assuming that the default encoding is always UTF-8, or that using `errors='ignore'` is a safe way to handle encoding issues, when in fact it can hide data corruption.

93
Multi-Selectmedium

Which TWO of the following are valid ways to define a configuration option in configparser?

Select 2 answers
A.parser['section']['option'] = 'value'
B.parser.add_option('section', 'option', 'value')
C.parser.write('section', 'option', 'value')
D.parser.set('section', 'option', 'value')
E.parser.insert('section', 'option', 'value')
AnswersA, D

Assigning through `parser['section']['option'] = 'value'` works because `ConfigParser` implements the mapping protocol: `__getitem__` returns a `SectionProxy` that supports `__setitem__`, writing straight into the section. This satisfies the stem's requirement for a valid definition method, unlike `set()` or `add_option()`, which do not exist on the parser.

Why this answer

Option A is correct because configparser supports the mapping-style interface, so assigning parser['section']['option'] = 'value' creates or updates the option 'option' in 'section' with the string 'value'. Option D is correct because the ConfigParser.set(section, option, value) method is the explicit API for setting an option's value within a section, and it requires the section to already exist. Options B, C, and E are not valid configparser methods: add_option, write, and insert do not exist with those signatures — write() actually writes the configuration to a file-like object, and there is no add_option or insert method for defining options.

94
MCQhard

How do you define a property in a class to make it read-only?

A.Use the 'readonly' decorator.
B.Use the 'final' modifier.
C.Set the attribute to private.
D.Define a property with only @property, no @setter.
AnswerD

Using only the `@property` decorator creates a read-only attribute: the getter runs on access, but any assignment raises `AttributeError` because no setter exists. This directly satisfies the stem's read-only constraint, unlike a plain attribute, which remains freely writable.

Why this answer

By defining the property with only a getter (using @property) and omitting the setter method.

95
MCQeasy

A developer is writing a Python script and wants to ensure that the code adheres to PEP 8's recommendations for blank lines. According to PEP 8, how many blank lines should surround a top-level function definition?

A.Two blank lines before and after the function definition.
B.No blank lines are required; the function can be adjacent to other code.
C.One blank line before and after the function definition.
D.Three blank lines before and after the function definition.
AnswerA

PEP 8 specifies that top-level function and class definitions should be surrounded by two blank lines. This convention improves readability by clearly separating distinct sections of code. It helps developers quickly identify where one function ends and another begins, especially in larger modules. Adhering to this rule is a common practice in well-formatted Python codebases.

Why this answer

PEP 8 recommends two blank lines before and after top-level function and class definitions. This provides clear visual separation and improves readability. One blank line is used for methods inside classes, and no blank lines would make the code cramped.

Three blank lines are excessive. The correct choice is two blank lines.

Exam trap

The trap here is confusing the rule for top-level functions with the rule for methods, which require only one blank line.

96
Multi-Selecthard

Which TWO of the following are true regarding the HTTP 'User-Agent' header?

Select 2 answers
A.It is used to encrypt the payload
B.It can be spoofed to mimic browsers
C.It identifies the client application to the server
D.It is automatically set by the socket module
E.It is mandatory for all HTTP requests
AnswersB, C

The User-Agent header is client-supplied text, so any value can be sent regardless of the actual software. Tools and scripts routinely set it to a browser string, satisfying the requirement that it can be spoofed to mimic browsers.

Why this answer

Option B is correct because the User-Agent header is a plaintext, client-supplied string with no cryptographic protection or server-side verification, so tools like curl, browsers, or scripts can freely set it to any value (e.g., 'Mozilla/5.0') to impersonate another client. Option C is correct because the User-Agent header's defined purpose in HTTP is to identify the requesting user agent — the client application, its version, and often the OS — to the server, which may use it for content negotiation, analytics, or bot detection. Option A is wrong because encryption is provided by TLS/HTTPS, not by any HTTP header; User-Agent carries no cryptographic function.

Option D is wrong because the socket module operates at the transport layer and has no knowledge of HTTP semantics; libraries like requests or http.client set User-Agent, not raw sockets. Option E is wrong because HTTP/1.1 only mandates the Host header for requests, and User-Agent is optional — many clients omit it or send an empty value.

97
Multi-Selectmedium

Which THREE of the following are correct regarding socket buffer sizes?

Select 3 answers
A.Buffer sizes are limited by the operating system
B.SO_RCVBUF sets the receiving buffer size
C.The buffer size has no effect on throughput
D.Setting a massive buffer always improves speed
E.Buffer size can be configured using setsockopt
AnswersA, B, E

Socket buffer sizes are bounded by kernel-level limits such as SO_RCVBUF and SO_SNDBUF maxima, so the operating system constrains how large buffers can be set. This is the actual constraint governing socket buffer configuration, not the Python socket module itself.

Why this answer

Option A is correct because socket buffer sizes are bounded by OS-level limits such as net.core.rmem_max and net.core.wmem_max on Linux, so an application cannot arbitrarily set them beyond what the kernel permits. Option B is correct because the SO_RCVBUF socket option specifically controls the size of the receive buffer used to hold incoming data before the application reads it. Option E is correct because setsockopt() is the standard API call used to configure socket options like SO_RCVBUF and SO_SNDBUF on a socket.

Option C is wrong because buffer size directly influences throughput, especially on high-bandwidth or high-latency links where too small a buffer limits the window. Option D is wrong because excessively large buffers can waste memory, increase latency, and do not guarantee faster transfer since throughput is also constrained by bandwidth, RTT, and application processing.

98
Multi-Selectmedium

Which TWO practices ensure secure handling of sensitive environment configurations?

Select 2 answers
A.Commit .env files to the code repository.
B.Store secrets in code comments.
C.Share the '.env' file via email.
D.Add '.env' to your '.gitignore' file.
E.Use a library like 'python-dotenv' to load configuration.
AnswersD, E

Adding `.env` to `.gitignore` prevents credentials and API keys from being committed to version control, satisfying the constraint that secrets must never enter the repository history. Since Git tracks content permanently, excluding the file at source stops accidental exposure through pushed commits, forks or public mirrors.

Why this answer

Option D is correct because adding '.env' to '.gitignore' prevents the file containing sensitive configuration values from being tracked and pushed to the Git repository, keeping secrets out of version control history. Option E is correct because using a library like 'python-dotenv' loads configuration from a local '.env' file into environment variables at runtime, so secrets stay out of source code and can be managed per-environment. Options A and C are insecure because committing '.env' files to the repository or emailing them exposes secrets to unintended parties and version history.

Option B is also wrong since storing secrets in code comments still embeds them in source code that may be shared or committed.

99
MCQmedium

You are building a Python script that consumes a REST API which returns paginated JSON responses. The API includes a 'next' link in the response body for the next page. You need to follow these links until all pages are retrieved. Which approach is most appropriate using the requests library?

A.Set the 'stream' parameter to True in the GET request to retrieve all pages in a single streaming response.
B.Use the requests.get() method with the 'params' argument to specify a page number, incrementing it until an empty response is received.
C.Use a while loop that sends a GET request to the current URL, parses the JSON, extracts the 'next' link, and updates the URL until 'next' is null.
D.Use the requests.Session object and call session.get() with the initial URL, relying on the session to automatically follow the 'next' links in the JSON body.
AnswerC

This approach correctly handles pagination by iteratively requesting each page, extracting the next link from the JSON response, and continuing until there are no more pages. It uses the requests library to send GET requests and parse JSON, which is straightforward and effective for APIs that provide next links in the body.

Why this answer

When an API returns a 'next' link in the JSON body, the correct way to paginate is to iteratively follow that link. This requires parsing the JSON, extracting the URL, and making subsequent requests until the link is absent or null. The requests library facilitates this with its get() method and .json() parsing.

Other options either misunderstand the features or assume a different pagination style.

Exam trap

The trap here is assuming that requests.Session automatically follows pagination links in the response body, or that streaming can combine pages, when in fact pagination logic must be implemented manually.

100
MCQhard

A script processes data from untrusted sources. Which technique best mitigates 'pickle' deserialization vulnerabilities?

A.Only unpickle from files with a specific extension.
B.Use an alternative format like JSON or XML for serialization.
C.Wrap the unpickling in a try-except block.
D.Use 'pickle.load()' with a restricted whitelist of modules.
AnswerB

JSON and XML parsers construct only primitive data types, so they cannot execute arbitrary code during deserialisation. This directly satisfies the untrusted-source constraint, where pickle's `__reduce__` method allows attackers to run commands. Switching format removes the code-execution vector entirely rather than merely restricting which classes may load.

Why this answer

The pickle module is inherently unsafe for untrusted data because unpickling executes arbitrary code via the __reduce__ method during object reconstruction. The only reliable mitigation is to avoid pickle entirely for untrusted input and use a data-only format like JSON or XML, which cannot execute code during parsing. JSON/XML parsers only construct primitive data types (dicts, lists, strings, numbers), eliminating the remote code execution vector.

Exam trap

PCPP1 often tests the misconception that defensive coding patterns like try-except or file validation can secure pickle, when the only real fix is to not use pickle on untrusted data at all.

How to eliminate wrong answers

Option A is wrong because file extensions are trivially spoofed and provide zero protection — a malicious pickle can be named anything. Option C is wrong because try-except only catches exceptions after the malicious __reduce__ payload has already executed; the damage is done before any exception is raised. Option D is wrong because pickle.load() has no built-in whitelist mechanism — there is no restricted unpickler in the standard library, and third-party solutions like restricted unpicklers are fragile and easily bypassed.

101
MCQeasy

When naming a constant in Python, which convention does PEP 8 recommend?

A.UPPER_CASE_WITH_UNDERSCORES.
B.PascalCase.
C.snake_case.
D.CamelCase.
AnswerA

PEP 8 specifies that constants be written in all-uppercase letters with words separated by underscores, satisfying the stem's request for the recommended naming convention. This distinct style visually flags module-level values that should not change, separating them from lowercase variables and functions.

Why this answer

Constants should be named using all capital letters with underscores to separate words.

102
Multi-Selecteasy

Which THREE of the following are recommended in PEP 8 for class definitions?

Select 3 answers
A.Put two blank lines between top-level classes.
B.Place imports inside the class definition.
C.Omit docstrings for private classes.
D.Use CamelCase for class names.
E.Include a docstring for the class.
AnswersA, D, E

PEP 8 mandates two blank lines before and after every top-level class definition, visually separating it from surrounding module-level code. This satisfies the stem's request for recommended class-definition formatting, distinguishing top-level classes from nested ones and methods, which use a single blank line.

Why this answer

Option A is correct because PEP 8's blank-lines rule requires two blank lines around top-level function and class definitions, so separating top-level classes with two blank lines is the recommended style. Option D is correct because PEP 8 prescribes the CapWords (CamelCase) convention for class names, e.g., class MyClass. Option E is correct because PEP 8 states that docstrings should be written for all public modules, functions, classes, and methods, so a class should include a docstring.

Option B is not recommended: imports must be placed at the top of the file, after module docstrings and before module-level code, never inside a class body. Option C is not recommended: PEP 8 calls for docstrings on all public classes, and omitting them for private classes is not a PEP 8 rule.

103
MCQmedium

You wish to group several widgets together within a frame. Which widget acts as a container for this purpose?

A.tk.Group()
B.tk.Box()
C.tk.Container()
D.tk.Frame()
AnswerD

'tk.Frame()' creates a rectangular container widget that groups and positions child widgets, and can itself be placed inside a window or another frame. This directly satisfies the stem's requirement for a widget acting as a container.

Why this answer

The Frame widget is specifically designed as a container to group other widgets.

104
MCQeasy

Which magic method is used to control how an instance is displayed when using the print() function?

A.__str__
B.__display__
C.__repr__
D.__print__
AnswerA

`__str__` supplies the informal, human-readable string that `print()` calls when converting an instance to text. Python's `print()` invokes `str()` on its arguments, which delegates to `__str__`; `__repr__` only serves as a fallback when `__str__` is undefined. This directly satisfies the stem's requirement for controlling printed output.

Why this answer

print() implicitly calls str(obj), which in turn calls __str__.

105
MCQeasy

You are developing a Python application that needs to retrieve data from a public REST API. The API returns JSON data and requires you to send a GET request with a custom User-Agent header. Which of the following code snippets correctly sends the request using the requests library?

A.requests.get(url, user_agent='MyApp/1.0')
B.requests.get(url, headers=('User-Agent', 'MyApp/1.0'))
C.requests.get(url, custom_headers={'User-Agent': 'MyApp/1.0'})
D.requests.get(url, headers={'User-Agent': 'MyApp/1.0'})
AnswerD

This snippet correctly uses the headers parameter, which accepts a dictionary of HTTP headers to send with the request. The User-Agent header is set to 'MyApp/1.0', fulfilling the requirement. This is the standard and recommended way to add custom headers in requests.

Why this answer

The requests library provides the headers parameter to specify custom HTTP headers. It accepts a dictionary where keys are header names and values are header values. This is the standard way to set a User-Agent or any other header.

The other options use non-existent parameters or incorrect data types, which would cause errors.

Exam trap

The trap here is confusing the parameter name or format, such as using user_agent instead of headers, or providing a tuple instead of a dictionary.

106
MCQmedium

A developer is implementing the Observer pattern and wants to store a list of observers without preventing them from being garbage collected when no other references exist. They decide to use `weakref.WeakSet` to hold the observers. Which statement accurately describes the behavior they should expect?

A.Observers continue to receive notifications until the `WeakSet` itself is garbage collected.
B.Observers are automatically removed from the set when their last strong reference is gone.
C.Calling `len()` on a `WeakSet` raises `ReferenceError` once any member is collected.
D.Observers must be hashable and are kept alive by the `WeakSet` until explicitly removed.
AnswerB

`WeakSet` stores weak references, so when an observer object has no other strong references, it is collected and the set entry disappears silently. This is precisely the behavior wanted for the Observer pattern to avoid keeping observers alive indefinitely. No manual unregistration is required for objects that go out of scope.

Why this answer

A `WeakSet` holds weak references and drops entries when the referenced objects are garbage collected. That makes it ideal for observer registries where you do not want the subject to keep observers alive. The other statements misstate weak reference semantics or confuse `WeakSet` behavior with `weakref.ref` dereferencing errors.

Exam trap

The trap here is conflating `weakref.ref` dereference errors with `WeakSet` behavior, or assuming the set keeps members alive.

107
MCQeasy

You are creating a Tkinter application with a Canvas widget. You draw a circle using create_oval and assign it the tag 'ball'. Later, you want to move the circle 10 pixels to the right and 5 pixels down. Which Canvas method should you use?

A.canvas.coords('ball', 10, 5)
B.canvas.translate('ball', 10, 5)
C.canvas.move('ball', 10, 5)
D.canvas.moveto('ball', 10, 5)
AnswerC

The move method takes a tag or item ID and delta x and delta y values, and moves the item(s) by that amount. Using the tag 'ball' moves all items with that tag, which in this case is the circle, by 10 pixels right and 5 pixels down, exactly as required.

Why this answer

The Canvas.move method is designed to shift items by a relative offset. It accepts a tag or item ID and delta x and delta y values. The other methods either set absolute coordinates, do not exist, or are from different libraries.

Thus, move is the correct choice for moving the circle by (10,5).

Exam trap

The trap here is confusing move with coords, or assuming a moveto method exists similar to other GUI frameworks.

108
MCQhard

A developer is writing a Python script that processes sensitive data. They want to ensure that any errors are logged without exposing the sensitive data itself. Which logging practice should they follow to avoid leaking sensitive information in logs?

A.Log only the exception type and not the message or traceback.
B.Use a custom logging filter to redact sensitive fields before logging.
C.Disable logging entirely for the module that processes sensitive data.
D.Log the full exception traceback including the exception message.
AnswerB

A custom logging filter can inspect log records and redact or remove sensitive information before they are emitted. This allows developers to log useful debugging information while ensuring that sensitive data such as passwords, tokens, or personal identifiers are not written to logs, maintaining security and compliance.

Why this answer

Using a custom logging filter to redact sensitive fields is a balanced approach. It allows logging of useful information while preventing sensitive data from being written. This practice is recommended for applications handling sensitive data, as it maintains security without sacrificing debuggability.

Exam trap

The trap here is thinking that logging the full traceback is always safe; in reality, exception messages can contain sensitive data that would be exposed in logs.

109
Multi-Selectmedium

You are designing a Tkinter application that uses a ttk.Treeview to display a table of records. You need to configure the widget so that users can select multiple non-contiguous rows and so that the first column shows a tree-style expander control. Which two actions must you perform? (Choose two.)

Select 2 answers
A.Call tree.heading('#0', text='Name') to set the label of the tree column.
B.Set the show option to 'tree headings' or include 'tree' in the show tuple.
C.Set the height option to a value greater than the number of rows.
D.Call tree.column('#0', stretch=True) to make the tree column resize with the widget.
E.Set the selectmode option to 'extended' when creating the Treeview.
AnswersB, E

The show option determines which parts of the Treeview are displayed. Including 'tree' displays the tree column with expander controls, while 'headings' shows the column headers. Using 'tree headings' displays both, so the first column can act as an expandable tree node, matching the requirement.

Why this answer

Multi-selection in a Treeview is governed by selectmode, which must be 'extended' to allow non-contiguous picks. The tree-style expander in the first column is controlled by the show option: including 'tree' (for example, 'tree headings') displays the tree column with expander controls. Heading text, height, and stretch are unrelated to these two requirements.

Exam trap

The trap here is thinking that setting a heading or column option enables the tree expander, when only the show option controls whether the tree column is rendered.

110
MCQeasy

You are creating a simple Tkinter application and notice that your window does not appear on the screen after calling the Tk() constructor. Which method must be called to start the event loop?

A.root.show()
B.root.render()
C.root.mainloop()
D.root.run()
AnswerC

Tk() only constructs the root window; nothing is drawn or processed until the event loop runs. Calling root.mainloop() hands control to Tk's event dispatcher, satisfying the stem's requirement to start the event loop so the window appears and responds.

Why this answer

The mainloop() method is required to start the Tkinter event loop, which listens for events and updates the display.

111
MCQmedium

You have a Checkbutton and you need to track its state. What is the recommended way to associate a variable with the Checkbutton?

A.Use the 'onvalue' parameter.
B.Pass a BooleanVar object to the 'variable' parameter.
C.Use the state attribute directly.
D.Use the 'command' parameter to set a global flag.
AnswerB

Tkinter's Checkbutton writes its on/off state into a shared control variable, so passing a BooleanVar to the 'variable' parameter lets you read or set the tick state directly through that object rather than polling widget internals.

Why this answer

A BooleanVar or IntVar should be passed to the 'variable' parameter of the Checkbutton.

112
MCQhard

A colleague built a Tkinter form where every Entry widget uses `pack()` in the same frame. They now need the labels to sit in a single column with the entries aligned in the next column and the whole form centered. They ask you to recommend the smallest structural change that makes this alignment reliable. What should you suggest?

A.Replace `pack()` with `grid()` inside a dedicated Frame, assigning labels and entries to the same row with different column indexes, then pack that Frame into the parent.
B.Keep `pack()` but add `side=tk.LEFT` to every label and `side=tk.RIGHT` to every entry so they form two implicit columns.
C.Use `pack()` for the labels and `grid()` for the entries in the same container, relying on Tkinter to merge both managers automatically.
D.Switch each Entry to `place()` and hard-code its x and y coordinates based on the current window size.
AnswerA

The grid geometry manager is designed for row-and-column alignment. Placing the labels in column 0 and entries in column 1 of the same row guarantees vertical alignment regardless of text length or font. Wrapping that grid inside its own Frame and packing the Frame lets you center the whole form in the parent, which is the minimal, idiomatic change for this requirement.

Why this answer

Grid is the correct tool for two-column alignment because it assigns widgets to explicit row and column cells, keeping labels and entries aligned regardless of content width. Wrapping the grid in its own Frame and packing that Frame into the parent is the smallest structural change that both aligns the fields and centers the form, without rewriting the entire window layout.

Exam trap

The trap here is thinking pack() can emulate columns through side options, when only grid() provides true row-and-column cell alignment.

113
MCQmedium

In the context of the Observer pattern, what is the benefit of an event-driven system over a direct-method-call approach?

A.Reduced memory usage.
B.Increased performance.
C.Decoupling between the subject and observers.
D.Automatic thread synchronization.
AnswerC

Observers register callbacks with the subject rather than being invoked by name, so the subject holds no compile-time reference to concrete observer classes. This satisfies the stem's decoupling constraint, letting observers be added or removed at runtime.

Why this answer

Decoupling is the primary benefit; the subject does not need to know the implementation details of the observers.

114
MCQmedium

You are writing to a CSV file. If your data contains the delimiter character itself (e.g., a comma in a text field), what does the csv module do by default?

A.It raises a csv.Error.
B.It quotes the field.
C.It ignores the delimiter.
D.It escapes the character with a backslash.
AnswerB

The csv writer applies QUOTE_MINIMAL by default, wrapping any field containing the delimiter, quotechar or newline in double quotes and escaping embedded quotes by doubling them. This preserves the comma inside the text field so the reader parses it as one value rather than splitting it.

Why this answer

The csv module automatically wraps such fields in quotes.

115
MCQhard

You are implementing a Python client that communicates with a REST API over HTTPS. The API uses a self-signed certificate. You need to verify the server's certificate against a custom CA bundle while also ensuring that the hostname is verified. Which approach correctly configures the 'requests' library?

A.Set the 'verify' parameter to False and manually check the certificate fingerprint.
B.Set the 'verify' parameter to the path of the custom CA bundle; hostname verification is automatically enabled.
C.Set the 'cert' parameter to the path of the custom CA bundle and set 'verify' to True.
D.Pass the path to the custom CA bundle to the 'verify' parameter and set 'verify_hostname' to True.
AnswerB

When you pass a path to a CA bundle to the 'verify' parameter, requests uses that bundle to verify the server's certificate. Hostname verification is performed by default as part of the SSL verification process. There is no need for an additional parameter. This approach correctly configures requests to use the custom CA and ensures hostname verification is active, meeting the scenario's requirements.

Why this answer

To use a custom CA bundle with requests, you pass the path to the bundle to the 'verify' parameter. This enables certificate verification against that bundle, and hostname verification is performed automatically as part of the SSL handshake. No additional parameter is needed for hostname verification, and disabling verification is insecure.

Exam trap

The trap here is thinking that there is a separate parameter for hostname verification, or confusing the 'cert' parameter (for client certificates) with the 'verify' parameter (for CA bundles).

116
MCQhard

When using the grid layout manager, which option allows a column to grow when the window is resized?

A.root.grid_grow(column=0, weight=1)
B.root.columnconfigure(0, weight=1)
C.root.grid_column(0, resizable=True)
D.root.set_grid(0, expand=True)
AnswerB

Assigning a non-zero weight to column 0 via columnconfigure makes Tkinter distribute any surplus width to that column when the window grows, satisfying the resize constraint. Weight defaults to 0, so columns stay fixed without it; weight=1 grants the column proportional claim on extra space.

Why this answer

The columnconfigure() method is used to set the weight of a column, allowing it to expand.

117
Multi-Selecteasy

Which THREE of the following are valid HTTP request methods commonly used in RESTful API design?

Select 3 answers
A.SEND
B.DELETE
C.GET
D.POST
E.FETCH
AnswersB, C, D

DELETE is a standard HTTP request method used in RESTful design to remove the resource identified by the request URI. It satisfies the stem by being one of the valid methods commonly applied to REST endpoints.

Why this answer

GET (C), POST (D), and DELETE (B) are all standard HTTP request methods defined in RFC 7231 and are core to RESTful API design: GET retrieves a representation of a resource, POST creates a new resource or submits data to be processed, and DELETE removes the specified resource. These methods map directly to REST's CRUD semantics (Read, Create, Delete) and are idempotent or non-idempotent as appropriate (GET and DELETE are idempotent, POST is not). SEND (A) and FETCH (E) are not valid HTTP request methods; FETCH is a JavaScript browser API for making network requests, and SEND is not part of the HTTP method registry, so neither belongs in a RESTful API design discussion.

118
MCQhard

What is the purpose of the __set_name__ method in descriptors?

A.To set the name of the class.
B.To delete the attribute.
C.To rename the attribute.
D.To allow the descriptor to know its name in the owner class.
AnswerD

__set_name__ is called automatically at class creation with the owner class and the attribute name, letting the descriptor capture its own identifier. This removes the need to pass the name manually, enabling descriptors to store or validate per-attribute data.

Why this answer

__set_name__ is called at class creation time to inform the descriptor of its name in the owner class, allowing it to store values in a private attribute without needing to know the name beforehand.

119
MCQmedium

Why should you use super() instead of calling the parent class method directly by name?

A.It is required for private methods.
B.It correctly resolves the next method in the MRO.
C.It is faster.
D.It makes the code more verbose.
AnswerB

super() delegates to the next class in the method resolution order rather than a hard-coded parent, so cooperative multiple inheritance chains correctly. This satisfies the stem's requirement by avoiding the brittle, MRO-breaking direct parent call.

Why this answer

super() is preferred over calling the parent class method directly because it correctly resolves the next method in the Method Resolution Order (MRO). This ensures that in multiple inheritance scenarios, all appropriate parent classes are called in the correct order, avoiding duplication or skipping.

Exam trap

PCPP1 often tests the misconception that super() is just a shortcut for calling the parent class; candidates may not realize it follows the MRO, which is essential for multiple inheritance.

How to eliminate wrong answers

Option A is wrong because super() is not required for private methods; private methods (name-mangled) are not inherited in the same way and super() does not affect them. Option C is wrong because super() is not primarily about speed; it may be slightly slower due to MRO lookup, but the main benefit is correctness. Option D is wrong because super() typically makes code less verbose and more maintainable, not more verbose.

120
Multi-Selectmedium

You are using the csv module to read a file that contains fields with embedded newlines and commas. Which TWO of the following statements about the csv.reader are correct? (Choose two.)

Select 2 answers
A.The csv.reader requires the file to be opened with newline='' to correctly handle embedded newlines.
B.The csv.reader can only read files encoded in UTF-8.
C.The csv.reader returns each row as a list of strings, regardless of the original data types.
D.The csv.reader automatically converts numeric fields to int or float.
E.The csv.reader automatically detects and uses the correct delimiter based on the file content.
AnswersA, C

When reading CSV files with embedded newlines, you must open the file with newline='' to prevent universal newline translation from interfering. The csv module expects the file to be opened with newline='' so it can correctly interpret line breaks within quoted fields. This is a documented requirement for both reading and writing.

Why this answer

The csv.reader requires newline='' when opening the file to handle embedded newlines correctly, and it always returns rows as lists of strings. It does not auto-detect delimiters or convert types, and it supports any encoding. These behaviors are essential for correct CSV parsing.

Exam trap

The trap here is assuming csv.reader performs smart parsing like delimiter detection or type conversion, when it is deliberately simple.

121
Multi-Selecteasy

Which TWO of the following are commonly used for debugging REST API integrations?

Select 2 answers
A.Hardcoding all credentials
B.Deleting the socket library
C.Increasing the CPU clock speed
D.Using a proxy tool to inspect traffic
E.Logging the request and response headers
AnswersD, E

A proxy tool intercepts HTTP traffic between client and server, exposing the actual request URLs, methods, payloads and status codes. This directly satisfies the need to debug REST API integrations, since it reveals what is genuinely transmitted rather than what the code intends to send.

Why this answer

Option D is correct because a proxy tool (e.g., Charles Proxy, Fiddler, or mitmproxy) acts as an intercepting man-in-the-middle that captures and displays the actual HTTP/HTTPS requests and responses, letting you inspect methods, URLs, status codes, and payloads for REST debugging. Option E is correct because logging request and response headers (e.g., Content-Type, Authorization, Accept, and custom headers) reveals exactly what the client sent and what the server returned, which is essential for diagnosing issues like missing auth tokens, wrong content negotiation, or unexpected status codes. The remaining options do not belong: hardcoding all credentials (A) is a security anti-pattern that exposes secrets and does nothing to aid debugging, deleting the socket library (B) would break networking entirely, and increasing the CPU clock speed (C) is a hardware performance tweak unrelated to inspecting or troubleshooting API traffic.

122
Multi-Selectmedium

Which THREE practices are recommended when handling external libraries?

Select 3 answers
A.Install libraries globally.
B.Import all libraries at the very end of the file.
C.Use a virtual environment for every project.
D.Document dependencies in a manifest file.
E.Pin your dependencies in a requirements.txt file.
AnswersC, D, E

A virtual environment isolates each project's installed packages from the system interpreter and from other projects, preventing version conflicts between libraries that demand incompatible dependencies. Creating one per project is the recommended baseline for reproducible, dependency-safe development.

Why this answer

Option C is correct because creating a virtual environment (e.g., python -m venv .venv) for every project isolates its third-party packages from the system Python and other projects, preventing version conflicts and keeping the global interpreter clean. Option D is correct because documenting dependencies in a manifest file (such as requirements.txt, pyproject.toml, or package.json) records exactly which external libraries the project needs, enabling reproducible installs and easier auditing. Option E is correct because pinning dependencies in requirements.txt (e.g., requests==2.31.0) locks exact versions so builds are deterministic and a later upstream release cannot silently break the application.

Option A is wrong because installing libraries globally pollutes the system interpreter, risks version clashes between projects, and often requires elevated privileges. Option B is wrong because imports should be grouped at the top of the file per PEP 8, and deferring them to the end harms readability and can cause NameError at runtime.

Exam trap

The trap is treating 'install globally' or 'import at the end' as harmless style choices — the exam expects you to recognize that global installs and misplaced imports violate both PEP 8 and reproducibility principles.

123
Multi-Selecthard

You are reviewing a Tkinter application that uses ttk widgets and a Canvas to draw a seating chart. The chart must redraw when the window is resized, and a toolbar above it must stay a fixed height. Which two techniques correctly contribute to a layout where the Canvas expands and the toolbar does not? (Choose two.)

Select 2 answers
A.Set canvas.configure(width=800, height=600) and bind the toplevel's <Configure> event to call canvas.configure with the new toplevel size.
B.Call canvas.pack(expand=True, fill='both') and toolbar.pack(side='top') in the same parent, relying on pack to keep the toolbar fixed.
C.Set the toolbar's grid row weight to 1 and the Canvas row weight to 0, then call canvas.update_idletasks() after each resize.
D.Place the toolbar and Canvas in the same container with grid(), give the toolbar row weight=0 and the Canvas row weight=1, and set sticky='nsew' on the Canvas so it adheres to all cell edges.
E.Bind the Canvas <Configure> event to a handler that reads event.width and event.height and redraws the chart using those dimensions.
AnswersD, E

Row weights control how surplus vertical space is distributed by grid(). A weight of zero keeps the toolbar row at its natural height, while a weight of one lets the Canvas row absorb all extra space. The sticky='nsew' option makes the Canvas fill the entire cell rather than centering at its requested size, which is required for the chart to use the available area.

Why this answer

A responsive chart needs both correct space allocation and a redraw trigger. Weighted grid rows with sticky='nsew' ensure the Canvas receives the surplus area while the toolbar keeps its natural height, and a <Configure> binding on the Canvas supplies the new dimensions for redrawing. The other options either mix incompatible geometry managers, hard-code sizes, or invert the weights.

Exam trap

The trap here is focusing only on making the Canvas expand while forgetting that the drawing itself must be regenerated from the Canvas's own <Configure> event to follow the new size.

124
MCQeasy

When parsing XML with ElementTree, how do you retrieve the text content of an element?

A.element.content
B.element.value
C.element.get_text()
D.element.text
AnswerD

ElementTree stores an element's direct text in its .text attribute, which returns the string between the opening and closing tags (or None if empty). This is the standard accessor for retrieving character data from a parsed element, satisfying the requirement to obtain text content.

Why this answer

The .text attribute of the Element object holds the text content.

125
Multi-Selectmedium

You are building a Python application that uses the shelve module to store persistent data. You want to ensure that the database file is updated correctly and that you can access keys as attributes. Which TWO of the following statements about the shelve module are true? (Choose two.)

Select 2 answers
A.By default, shelve uses the pickle module to serialize values.
B.The shelve module provides a dictionary-like interface for persistent storage.
C.shelve automatically synchronizes changes to disk after every assignment.
D.You can access shelf keys as attributes using dot notation.
E.The shelve module is thread-safe by default.
AnswersA, B

shelve uses pickle by default to serialize values before storing them in the underlying dbm database. This allows storage of arbitrary Python objects, as long as they are picklable. The keys are also pickled. This is a fundamental aspect of how shelve works. The statement is true and important to understand for correct usage, especially regarding object compatibility across Python versions.

Why this answer

The shelve module provides a persistent, dictionary-like object. It uses pickle to serialize values by default, allowing storage of complex Python objects. However, it does not automatically sync after each assignment; you must call sync() or close the shelf.

Keys are accessed via subscription, not attributes, and it is not thread-safe. Therefore, the true statements are about the dictionary-like interface and pickle serialization.

Exam trap

The trap here is assuming that shelve automatically saves changes immediately or that it supports attribute access, which it does not.

126
MCQeasy

When is it acceptable to ignore PEP 8 guidelines?

A.Only when you disagree with the stylistic choice.
B.Never.
C.When you are writing a script that will only be used once.
D.When necessary to maintain consistency with existing code or for legacy reasons.
AnswerD

PEP 8 explicitly permits local consistency to override its rules when working within an existing codebase, so matching surrounding legacy conventions takes precedence over strict compliance. This satisfies the stem's constraint by acknowledging that readability and uniformity within a project outweigh blanket adherence to the style guide.

Why this answer

PEP 8 itself states that project consistency and backward compatibility may warrant exceptions to the rules.

127
MCQmedium

When designing a public API, how should you signal that a method is for internal use only?

A.By prepending a single underscore.
B.By raising a warning if called externally.
C.By adding a comment like '# INTERNAL'.
D.By using all caps.
E.By suffixing with an underscore.
AnswerA

A single leading underscore marks the method as non-public by convention, satisfying the need to signal internal-only use without enforcing access control. Python's documentation treats such names as internal, and `from module import *` excludes them, so external callers receive a clear warning while the API remains unbroken.

Why this answer

Prefixing a name with a single underscore is the conventional way to indicate internal use.

128
Multi-Selecthard

You are developing a Python application that uses the `requests` library to consume a REST API. You need to implement a retry mechanism for transient HTTP errors (e.g., 500, 502, 503, 504) and connection timeouts. Which TWO of the following approaches are valid and recommended for achieving this with `requests`? (Choose two.)

Select 2 answers
A.Set the `max_retries` parameter directly in the `requests.get()` call, e.g., `requests.get(url, max_retries=3)`.
B.Pass a `retry` parameter to `requests.get()` with a dictionary of retry settings, e.g., `requests.get(url, retry={'total': 3})`.
C.Use the `requests.Session` object and set `session.retries = 3`.
D.Use the `Retry` class from `urllib3.util.retry` and mount it to an `HTTPAdapter` on a `requests.Session` object.
E.Wrap the request in a `try/except` block and manually loop with a counter, catching `requests.exceptions.ConnectionError` and checking `response.status_code` for server errors.
AnswersD, E

The `requests` library uses `urllib3` under the hood, and `urllib3.util.retry.Retry` allows fine-grained control over retries, including which status codes to retry on, backoff factors, and total retries. By creating an `HTTPAdapter` with a `Retry` instance and mounting it to a `Session`, you can automatically retry failed requests. This is the recommended, robust way to implement retries.

Why this answer

The recommended way to add retries in `requests` is by using `urllib3`'s `Retry` class with an `HTTPAdapter` mounted on a `Session`. Alternatively, you can manually implement retry logic with loops and exception handling. The other options reference non-existent parameters or attributes.

Both correct approaches provide control over transient errors and timeouts.

Exam trap

The trap here is assuming that `requests` has built-in retry parameters like `max_retries` or `retry` in its top-level API, when retries must be configured via adapters or manual loops.

129
MCQmedium

What is the purpose of the 'type' function when called with three arguments?

A.To register a class.
B.To create a new class dynamically.
C.To inherit from multiple classes.
D.To check object type.
AnswerB

Calling `type(name, bases, dict)` invokes the three-argument metaclass constructor, which builds a fresh class object at runtime from the supplied name string, base-class tuple and namespace dictionary. This satisfies the stem's requirement precisely: the three-argument form exists to create classes dynamically, unlike the single-argument form that merely returns an object's type.

Why this answer

It is used for dynamic class creation: type(name, bases, dict).

130
MCQmedium

When writing a library, what is the best practice for documenting the usage of a function?

A.Include the documentation as comments above the function definition.
B.Use docstrings to provide a clear summary and usage details.
C.Provide usage examples in the 'README.md' file only.
D.Wait for users to ask for documentation.
AnswerB

Docstrings are the conventional, introspectable place for usage documentation in Python. Because they attach to the function object itself, tools like help() and IDEs surface the summary and usage details directly, satisfying the library's need for discoverable, self-contained documentation.

Why this answer

Docstrings provide the most standard and accessible form of documentation that can be integrated with tools like Sphinx.

131
MCQhard

You are building a client for a REST API that requires an OAuth 2.0 bearer token. The token is long-lived and stored in an environment variable. You want every request in a session to carry the Authorization header without repeating the header setup at each call site. Which approach is correct and idiomatic with the requests library?

A.Create a requests.Session, set session.headers.update({'Authorization': f'Bearer {token}'}), and issue calls through that session.
B.Pass auth=('Bearer', token) to each request so the library builds the header.
C.Set os.environ['HTTP_AUTHORIZATION'] = f'Bearer {token}' before each call.
D.Subclass requests.Session and override send to inject the header after the request is prepared.
AnswerA

A Session object holds default headers that are merged into every request made through it, so updating session.headers once applies the bearer token to all calls. This is idiomatic, avoids repetition, and also reuses the underlying TCP connection for better performance.

Why this answer

A Session stores default headers that are merged into each prepared request, so updating session.headers with the Authorization bearer value applies authentication everywhere the session is used. Environment variables are not consulted by requests for outgoing headers, tuple-based auth produces Basic credentials, and overriding send is needlessly complex compared with the supported header mechanism.

Exam trap

The trap here is believing the auth tuple can express any scheme, when in fact it only produces HTTP Basic credentials from a username and password.

132
MCQhard

A developer is writing a Python function that accepts a callback. They want to ensure the function's docstring follows PEP 257 conventions for multi-line docstrings. Which of the following is the correct format for a multi-line docstring?

A.The summary line is indented, followed by a blank line, then the detailed description, and the closing quotes are indented to match the summary line's indentation.
B.The opening triple quotes are followed by a blank line, then the summary line, then the detailed description, with closing quotes on the same line as the last sentence.
C.The entire docstring is on a single line, regardless of length, to avoid multi-line formatting issues.
D.The summary line starts on the same line as the opening triple quotes, followed by a blank line, then a more detailed description, and the closing triple quotes are on a line by themselves.
AnswerD

PEP 257 specifies that multi-line docstrings should begin with a summary line on the same line as the opening quotes, followed by a blank line, then a more detailed description. The closing quotes should be on a separate line. This structure allows tools like help() to display the summary first and ensures consistent formatting across the codebase.

Why this answer

PEP 257 defines the canonical format for multi-line docstrings: a summary line on the same line as the opening triple quotes, a blank line, a detailed description, and closing quotes on their own line. This structure is widely supported by documentation generators and helps maintain consistency. The summary line should be a concise one-line description, while the body provides additional details.

Exam trap

The trap here is misplacing the summary line or the closing quotes, which can break automated docstring parsers.

133
MCQhard

You are designing a Tkinter application with a Listbox widget that displays multiple items. You want to allow the user to select multiple non-contiguous items (e.g., by holding Ctrl and clicking). Which configuration option of the Listbox should you set, and to what value?

A.selectmode='multiple'
B.selectmode='browse'
C.selectmode='single'
D.selectmode='extended'
AnswerD

Setting selectmode to 'extended' enables the standard multi-selection behavior where users can select multiple items using Ctrl+click for non-contiguous items or Shift+click for ranges. This is the default mode for Listbox and matches typical desktop application behavior. It provides the most intuitive user experience for multiple selections.

Why this answer

The Listbox widget's selectmode option controls how many items can be selected and how. The 'extended' mode allows multiple selections using Ctrl+click for non-contiguous items and Shift+click for ranges, which is the standard behavior. The 'multiple' mode allows multiple selections but with a toggle mechanism, not requiring Ctrl. 'single' and 'browse' restrict to one selection.

Exam trap

The trap here is confusing 'multiple' and 'extended' select modes, as both allow multiple selections but with different interaction models.

134
MCQhard

You are writing a Tkinter dialog that must react to a user pressing the Escape key at any time, even when focus is inside an Entry widget. You have a function named on_cancel. Which binding correctly achieves this?

A.root.bind_class('Entry', '<Escape>', on_cancel)
B.root.bind_all('<Escape>', on_cancel)
C.entry.bind('<Escape>', on_cancel)
D.root.bind('<Escape>', on_cancel, add='+')
AnswerB

bind_all registers the handler at the application level, so the binding fires regardless of which widget currently has focus. This is the correct way to implement a global keyboard shortcut such as Escape to cancel a dialog, because it applies to every widget in the application without needing to bind each one individually.

Why this answer

A global cancel shortcut must be registered at the application level. bind_all places the handler in the application-wide binding table so it triggers no matter which widget has focus. Widget-level and class-level bindings are scoped to specific widgets or widget classes and therefore miss events when focus is elsewhere, which is why they cannot satisfy the scenario.

Exam trap

The trap here is confusing bind_class with bind_all: bind_class targets a widget class, while bind_all applies to the entire application regardless of focus.

135
MCQmedium

A colleague's script parses a CSV export that uses a semicolon as the field separator and contains quoted text fields with embedded semicolons. They call csv.reader(f) without arguments and complain that rows are split incorrectly into too many fields. What is the correct fix?

A.Pre-process each line with str.split(';') before feeding the rows to csv.reader().
B.Open the file with newline='' and pass delimiter=';' to csv.reader().
C.Pass dialect='excel-tab' to csv.reader() to switch to tab-separated parsing.
D.Pass quoting=csv.QUOTE_NONE to csv.reader() so embedded semicolons are ignored.
AnswerB

csv.reader() defaults to a comma delimiter, so semicolon-separated data splits at every semicolon, including those inside quoted fields once quoting rules do not match. Supplying delimiter=';' makes the parser treat semicolons as separators and honour the default quotechar so embedded semicolons inside quotes stay within one field. Opening with newline='' is also required so the csv module controls line splitting.

Why this answer

The csv module defaults to a comma delimiter, so a semicolon-separated file must be parsed with delimiter=';'. Because quoted fields may contain the delimiter, that quoting behaviour must be preserved, which is the default when quotechar is left unchanged. The file should also be opened with newline='' so that embedded line breaks inside quoted fields are handled by the csv parser rather than by universal newline translation.

Exam trap

The trap here is assuming csv.reader() auto-detects delimiters, when it always defaults to a comma unless told otherwise.

136
MCQhard

In the context of writing robust error handling, what is the 'EAFP' principle?

A.Ensure All Functions Pass.
B.Exit All Files Properly.
C.Easier to Ask for Forgiveness than Permission.
D.Evaluate All Faults Promptly.
AnswerC

EAFP means attempting the operation and catching exceptions rather than pre-checking conditions. Python's try/except embodies this, avoiding race conditions between a check and the action, and suiting duck-typed code where pre-validation is unreliable or verbose.

Why this answer

EAFP stands for 'Easier to Ask for Forgiveness than Permission,' a Python coding philosophy that encourages attempting an operation and catching exceptions if it fails, rather than checking preconditions beforehand. In practice, this means using try/except blocks around code that might raise errors (e.g., accessing a dictionary key or opening a file) instead of using if statements to verify conditions first. This approach aligns with Python's dynamic nature and often results in cleaner, faster code because it avoids redundant checks and race conditions.

Exam trap

PCPP1 often tests... the confusion between EAFP and LBYL, where candidates might pick a distractor that sounds like a proactive error-checking strategy (like Option D) instead of recognizing the specific Python idiom of using try/except over if-checks.

How to eliminate wrong answers

Option A is wrong because 'Ensure All Functions Pass' is a meaningless phrase that does not correspond to any known programming principle; it confuses the acronym with a generic quality goal. Option B is wrong because 'Exit All Files Properly' describes a resource management practice (like using context managers), not the EAFP principle, and misinterprets the acronym. Option D is wrong because 'Evaluate All Faults Promptly' suggests a proactive error-checking strategy, which is closer to the opposite philosophy (LBYL – Look Before You Leap) and does not match the EAFP acronym or its meaning.

137
MCQmedium

You are creating a Tkinter application with a menu bar. You want to add a keyboard shortcut (accelerator) to a menu item so that pressing Ctrl+S triggers the save action. Which option of the add_command method should you use to display the shortcut text, and what additional step is required to make the shortcut functional?

A.Use the accelerator option to display 'Ctrl+S', and the shortcut will automatically be functional without additional code.
B.Use the accelerator option to display 'Ctrl+S', and bind the keystroke to the save function using the bind method on the root window.
C.Use the command option to specify both the function and the shortcut, e.g., command=(save, 'Ctrl+S').
D.Use the underline option to set the shortcut key, and bind it using the bind method.
AnswerB

The accelerator option only displays the shortcut text next to the menu item; it does not create the binding. To make the shortcut work, you must explicitly bind the key sequence (e.g., '<Control-s>') to the save function using bind on a widget, typically the root window. This two-step process is necessary because Tkinter does not automatically associate the accelerator text with the binding.

Why this answer

In Tkinter, the accelerator option of a menu item only displays the shortcut text; it does not create a key binding. To make the shortcut functional, you must explicitly bind the key sequence to the desired function using the bind method, typically on the root window. The underline option is for mnemonics, and the command option only sets the callback for menu selection.

Exam trap

The trap here is assuming that setting the accelerator option automatically enables the keyboard shortcut.

138
Multi-Selectmedium

Which THREE of the following are valid parameters for the csv.writer constructor?

Select 3 answers
A.lineterminator
B.encoding
C.buffer_size
D.quotechar
E.delimiter
AnswersA, D, E

`lineterminator` is a valid `csv.writer` constructor parameter, letting you override the default `'\r\n'` row separator when writing files. This satisfies the stem's requirement for genuine constructor arguments, unlike dialect-only or reader-specific settings. It directly controls the character sequence terminating each written row.

Why this answer

The csv.writer constructor accepts a dialect and formatting parameters, and lineterminator (A) is a valid parameter that sets the string used to terminate lines written by the writer, defaulting to '\r\n'. quotechar (D) is also valid and specifies the single character used to quote fields containing special characters such as the delimiter or quotechar itself. delimiter (E) is valid as well, defining the one-character string used to separate fields, defaulting to a comma. The encoding (B) option is not a csv.writer parameter; encoding is handled by the underlying file object passed to the writer, typically via open(). The buffer_size (C) option is likewise not a csv.writer parameter; buffering is controlled by the file object's buffering argument in open(), not by the CSV writer.

139
MCQeasy

A developer is adding a new public function `calculate_discount` to an existing Python module. The module currently uses four spaces per indentation level, and the function spans several nested `if` blocks. Which PEP 8 indentation practice should the developer follow?

A.Use one tab per indentation level because tabs render consistently in every IDE.
B.Use four spaces per indentation level throughout the function and avoid mixing tabs with spaces.
C.Use two spaces per indentation level to keep deeply nested blocks from drifting too far right.
D.Use a mix of tabs for the outer blocks and spaces for the inner blocks to visually separate nesting levels.
AnswerB

PEP 8 explicitly recommends four spaces per indentation level and states that spaces are the preferred indentation method. Using four spaces consistently in the new function keeps the module uniform and avoids the ambiguity that arises when tabs and spaces are mixed, which can cause `TabError` or silent misalignment across different editors.

Why this answer

PEP 8 recommends four spaces per indentation level and spaces over tabs. Because the existing module already uses four spaces, the new function should match that convention to keep the file internally consistent and avoid tab/space mixing, which Python 3 can reject with `TabError`. Consistency within a module matters more than personal preference.

Exam trap

The trap here is assuming that tab indentation is acceptable simply because it renders consistently in a particular editor.

140
MCQmedium

What does the @abstractmethod decorator do when applied to a method inside an ABC?

A.It requires the subclass to implement the method.
B.It prevents the method from being called.
C.It automatically generates a default implementation.
D.It makes the method faster.
AnswerA

The @abstractmethod decorator marks a method as abstract within an ABC, so any concrete subclass that does not override it cannot be instantiated; Python raises TypeError at instantiation. This enforces the subclass implementation the question describes.

Why this answer

It marks the method as requiring an override in any non-abstract concrete subclass.

141
MCQeasy

You are writing a Python script that must read a configuration file in TOML format. Which module from the Python Standard Library should you use?

A.yaml
B.configparser
C.tomllib
D.json
AnswerC

tomllib is the standard library module introduced in Python 3.11 for parsing TOML files. It provides load() and loads() functions to read TOML data into Python dictionaries. For older Python versions, you would need a third-party library, but for current Python, tomllib is the correct standard module.

Why this answer

tomllib is the Standard Library module for reading TOML files, added in Python 3.11. It correctly parses TOML syntax and returns native Python types. Other modules like configparser, json, or yaml are either for different formats or not in the standard library.

Exam trap

The trap here is assuming configparser can handle any configuration format, including TOML.

142
MCQmedium

You wrote a small REST client that calls `requests.get('https://api.example.com/v1/items', timeout=5)`. Under normal network load the call succeeds, but the server occasionally takes longer than 5 seconds to start sending the response body while the TCP connection is already established. You want to allow up to 5 seconds for the connection to be established and up to 30 seconds for the server to send data after the connection is made. Which call achieves this?

A.requests.get('https://api.example.com/v1/items', timeout=30)
B.requests.get('https://api.example.com/v1/items', timeout=(30, 5))
C.requests.get('https://api.example.com/v1/items', timeout=(5, 30))
D.requests.get('https://api.example.com/v1/items', timeout=5, read_timeout=30)
AnswerC

The timeout parameter accepts a tuple where the first value is the connect timeout (maximum time to establish the TCP connection) and the second is the read timeout (maximum time to wait for a chunk of data after the connection is established). Passing (5, 30) exactly matches the requirement: 5 seconds to connect, 30 seconds to receive data.

Why this answer

The requests library accepts a timeout tuple of (connect_timeout, read_timeout). Only the tuple form allows different limits for establishing the connection and for waiting on data. The scenario explicitly asks for 5 seconds to connect and 30 seconds to read, so the correct call uses (5, 30).

Any single value or reversed tuple misconfigures one of the two phases.

Exam trap

The trap here is assuming a single timeout value or a named keyword controls both connect and read phases independently.

143
MCQmedium

When using abstract base classes (ABCs) from the abc module, what happens if a class inherits from an ABC but fails to implement one of the abstract methods?

A.The class will be created, but calling the missing method will raise an AttributeError.
B.The class will be marked as abstract and will raise a TypeError upon instantiation.
C.The missing method will default to a 'pass' statement.
D.The parent ABC will automatically provide a NotImplementedError.
AnswerB

Inheriting an ABC without overriding every abstract method leaves the subclass abstract, so Python refuses instantiation and raises TypeError. This satisfies the stem's constraint: the missing implementation is detected at instantiation time, not at class definition, because ABCMeta records remaining abstract methods in `__abstractmethods__`.

Why this answer

Python will raise a TypeError when you attempt to instantiate the class, preventing the creation of an incomplete object.

144
MCQhard

You are refactoring code that performs sensitive operations. Which of the following is the most secure practice for handling secret keys?

A.Use environment variables to store sensitive configuration.
B.Encrypt the secrets and store them as constants in a module.
C.Store secrets in a private class attribute.
D.Hardcode them as strings inside a 'config.py' file and ignore it in Git.
AnswerA

Environment variables keep secrets out of source code and version control, so credentials are injected at runtime rather than committed. This satisfies the constraint of handling sensitive keys without embedding them in files that could be leaked.

Why this answer

Hardcoding secrets is a major security vulnerability; using environment variables is the industry standard.

145
MCQhard

You are implementing a Python client that uses the `socket` module to communicate with a server. The server sends data in chunks, and you need to ensure you receive all data until the connection is closed by the server. Which approach correctly reads all data from the socket?

A.data = b''; while True: chunk = sock.recv(4096); if not chunk: break; data += chunk
B.data = sock.recv_all()
C.data = sock.recv(1024)
D.data = sock.recv(0)
AnswerA

This loop repeatedly calls `recv(4096)` and appends chunks to a bytes object until `recv` returns an empty bytes object (`b''`), which signals that the server has closed the connection. This is the correct pattern to read all data from a TCP socket until EOF. It handles arbitrary data sizes and ensures no data is missed.

Why this answer

To read all data from a TCP socket until the server closes the connection, you must call `recv()` in a loop, accumulating chunks until `recv()` returns an empty bytes object. A single `recv()` call may not return all data. The `socket` module does not provide a `recv_all()` method, and `recv(0)` reads nothing.

Thus, the loop approach is correct.

Exam trap

The trap here is assuming a single `recv()` call retrieves all data, or that a convenience method like `recv_all()` exists.

146
Multi-Selectmedium

You are writing a REST client that must handle HTTP error responses robustly. For each response, you want to detect server errors and extract the error message returned in a JSON body. Which TWO of the following approaches are correct and safe? (Choose two.)

Select 2 answers
A.Call response.json() unconditionally on every response without checking the Content-Type header.
B.Use response.status_code >= 400 to decide whether to parse the error body, then call response.json() to extract the error message.
C.Assume any response with status_code 200 contains valid data and skip further validation.
D.Call response.raise_for_status() inside a try block and catch requests.exceptions.HTTPError to handle 4xx and 5xx responses.
E.Ignore the status code and rely solely on the presence of an 'error' key in the JSON body.
AnswersB, D

Checking status_code directly is explicit and avoids relying on exceptions. Calling response.json() on an error response is valid when the API documents JSON error bodies. This approach gives full control over parsing and is safe as long as the body is known to be JSON.

Why this answer

Both raise_for_status() with HTTPError handling and explicit status_code checks are valid, safe patterns for detecting HTTP errors. The first centralizes error handling via exceptions, while the second gives explicit control and is useful when the API returns structured JSON error bodies. The other options either skip essential validation or assume JSON without verifying it.

Exam trap

The trap here is assuming a 200 status guarantees a valid payload or that every response body can be parsed as JSON.

147
MCQmedium

What is the consequence of not calling super().__init__() in a class with multiple inheritance?

A.The class will not be created.
B.All attributes will be lost.
C.The initialization chain for parent classes is interrupted.
D.Python will raise a RuntimeError.
AnswerC

Skipping super().__init__() breaks Python's cooperative multiple-inheritance chain: the MRO traversal halts at that class, so subsequent parent initialisers never execute. This satisfies the stem's constraint that later classes in the MRO remain uninitialised, leaving their instance attributes unset.

Why this answer

The MRO chain will break, and sibling classes may not be initialized properly, potentially causing missing attributes or logic errors.

148
Multi-Selectmedium

You are working with the sqlite3 module to build a small inventory application. You need to execute a parameterized INSERT statement and then retrieve the auto-generated primary key for the newly inserted row. Which two approaches are valid and safe? (Choose two.)

Select 2 answers
A.Execute the INSERT with placeholders, then query the sqlite_sequence table for the maximum value.
B.Execute the INSERT with placeholders, then call cursor.lastrowid.
C.Execute the INSERT with string formatting, then call connection.insert_id().
D.Execute the INSERT with placeholders, then execute SELECT last_insert_rowid().
E.Execute the INSERT with placeholders, then call cursor.fetchone() to get the new primary key.
AnswersB, D

cursor.lastrowid returns the rowid of the most recent successful INSERT on that cursor. For a table with an INTEGER PRIMARY KEY, this is the auto-generated key. Using placeholders for parameters prevents SQL injection. This is a standard, safe method to obtain the new key immediately after insertion.

Why this answer

The two safe and valid ways to retrieve the auto-generated primary key after an INSERT are cursor.lastrowid and the SQL function last_insert_rowid(). Both operate on the same connection and return the rowid of the most recent successful INSERT. The other options either use non-existent APIs, insecure string formatting, or attempt to read a result set that an INSERT does not produce.

Exam trap

The trap here is assuming that fetchone() can return the new key after an INSERT, or that connection.insert_id() exists, when in fact INSERT statements yield no result set and that method is not part of the sqlite3 API.

149
MCQmedium

You have a list of options and want the user to select one using a dropdown menu. Which widget should you use?

A.tk.ComboBox()
B.tk.Select()
C.tk.Dropdown()
D.tk.OptionMenu()
AnswerD

tk.OptionMenu() binds a Tk variable to a menubutton displaying the current selection, letting the user pick exactly one value from a fixed list. This directly satisfies the stem's single-selection dropdown constraint, unlike Checkbutton or Listbox, which permit multiple selections or expose no collapsed menu.

Why this answer

tk.OptionMenu() is the correct widget because it is specifically designed to present a fixed set of options as a dropdown menu in Tkinter. It is a subclass of Menubutton that displays the currently selected option and, when clicked, reveals a menu of choices. The user can select exactly one option, and the widget automatically updates the displayed text to reflect the selection.

Exam trap

PCPP1 often tests the difference between classic Tkinter widgets and themed ttk widgets, and candidates may mistakenly choose ttk.Combobox or assume a widget named Dropdown exists.

How to eliminate wrong answers

Option A is wrong because tk.ComboBox() does not exist in standard Tkinter; the closest widget is ttk.Combobox, which is part of the themed ttk module and not a direct tk method. Option B is wrong because tk.Select() is not a Tkinter widget at all; there is no such class for creating dropdowns. Option C is wrong because tk.Dropdown() is not a Tkinter widget; dropdown functionality is provided by OptionMenu or ttk.Combobox, not a class named Dropdown.

150
MCQhard

When implementing secure coding practices in a web-facing Python application, how should you handle raw user input to prevent command injection?

A.Pass the entire input string to os.system().
B.Concatenate the input string into a shell command for execution.
C.Pass input arguments as a list to subprocess.run(args, shell=False).
D.Sanitize input using a custom regex to remove special characters.
AnswerC

Passing arguments as a list with shell=False bypasses the shell entirely, so metacharacters like `;`, `|` and `&&` are treated as literal argument data rather than shell syntax. This satisfies the stem's command injection constraint by removing shell interpretation, the mechanism through which injected commands would otherwise execute.

Why this answer

Using the 'subprocess' module with 'shell=False' (the default) prevents the shell from interpreting user-provided strings as commands.

Page 1

Page 2 of 4

Page 3

All pages