Python Institute · Free Practice Questions · Last reviewed May 2026
30 real exam-style questions organised by domain, each with the correct answer highlighted and a plain-English explanation of why it's right — and why the others are wrong.
How do you correctly call a method from a sibling class in a diamond inheritance structure using super()?
Call the grandparent class directly.
Use super() in each class to delegate to the next class in the MRO.
Using `super()` in each class delegates along Python's C3 linearisation, so every sibling in the diamond is invoked exactly once in method resolution order. This satisfies the stem's requirement to reach a sibling class without duplicating the shared base, which direct base-class calls would trigger.
Use the __bases__ attribute to iterate through parents.
Explicitly call the sibling class method by name.
Which magic method is responsible for providing the informal string representation of an object, typically used for user-facing output?
__str__
`__str__` returns the informal, human-readable string representation, which `print()` and `str()` invoke for user-facing output. The alternative `__repr__` targets developers and aims for an unambiguous, ideally evaluable representation. The stem's constraint — informal, user-facing display — maps directly onto `__str__`, making it the responsible magic method.
__format__
__unicode__
__repr__
What is the result of applying the @staticmethod decorator to a method inside a class that also defines a metaclass?
The metaclass must manually convert it back to a static method.
It raises a TypeError at class definition time.
The method is correctly bound as a static function regardless of the metaclass.
The `@staticmethod` decorator wraps the function in a descriptor that returns the plain function without binding `self` or `cls`, so metaclass interference is irrelevant. Metaclasses control class creation, not instance attribute lookup, so the static method resolves correctly on both the class and its instances.
The metaclass will treat the method as an instance method.
You are implementing the Observer pattern. Why should you avoid using a strong reference to the observers in the subject's list?
It causes circular dependency issues.
It makes the notify method thread-unsafe.
It violates the principle of encapsulation.
It prevents the observer from being garbage collected when it is no longer needed.
A strong reference held by the subject keeps each observer alive, so reference counting never reaches zero and the garbage collector cannot reclaim observers that are no longer needed. Weak references let them be collected once external references disappear.
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?
The class will be created, but calling the missing method will raise an AttributeError.
The class will be marked as abstract and will raise a TypeError upon instantiation.
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__`.
The missing method will default to a 'pass' statement.
The parent ABC will automatically provide a NotImplementedError.
Which magic method should you implement to make your objects support the 'with' statement context manager?
__context__
__enter__ and __exit__
The with statement calls __enter__ on entry and __exit__ on exit, the latter receiving exception details for cleanup or suppression. Implementing both satisfies the stem's context manager requirement, since neither method alone enables the protocol.
__open__ and __close__
__init__ and __del__
Want more Advanced Object Oriented Programming practice?
Practice this domainYou have a Checkbutton and you need to track its state. What is the recommended way to associate a variable with the Checkbutton?
Use the 'onvalue' parameter.
Pass a BooleanVar object to the 'variable' parameter.
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.
Use the state attribute directly.
Use the 'command' parameter to set a global flag.
You want to bind a function 'on_click' to a left mouse button click on a Button widget. Which event sequence string is correct?
<Button-1>
Tkinter encodes mouse events as <MODIFIER-BUTTON-NUM>, where Button-1 denotes the left mouse button. Binding <Button-1> to the Button widget therefore fires on_click precisely on a left click, satisfying the stem's requirement without capturing middle or right button presses.
<Mouse-1>
<Left-Click>
<Click-1>
You need to add a label that displays static text in your GUI. Which widget is most appropriate for this purpose?
tk.Message()
tk.Entry()
tk.Display()
tk.Label()
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.
tk.Text()
In a Tkinter grid layout, you want a button to span across two columns. Which parameter should you use?
columnspan=2
columnspan=2 instructs Tkinter's grid geometry manager to allocate two adjacent column cells to the widget, satisfying the stem's requirement that the button span two columns. The parameter is passed directly to grid(), and Tkinter merges the specified cells horizontally without altering other widgets' placements.
span_cols=2
merge=2
cols=2
You have a Tkinter Entry widget and want to retrieve the text currently entered by the user. Which method do you call on the Entry instance?
entry.get()
Entry.get() reads the widget's current contents as a string, satisfying the requirement to retrieve user-entered text. It accepts optional index arguments, but with none it returns the entire field, which is the standard Tkinter approach.
entry.content()
entry.text()
entry.value()
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?
root.show()
root.render()
root.mainloop()
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.
root.run()
Want more Graphical User Interface Programming practice?
Practice this domainAccording to PEP 257, what is the standard format for a single-line docstring?
Use a single quote for the entire block.
The docstring should span three lines including the summary.
The summary should start on the next line.
Use triple quotes and keep the summary on the same line, ending with a period.
PEP 257 specifies triple double quotes with the summary on the same line as the opening quotes, terminated by a period. This satisfies the stem's single-line format requirement, keeping the docstring concise and consistent with the convention.
When naming a constant in Python, which convention does PEP 8 recommend?
UPPER_CASE_WITH_UNDERSCORES.
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.
PascalCase.
snake_case.
CamelCase.
You are debugging a legacy application and need to ensure that resources like file handles are always closed. Which construct is preferred?
Wrap the file operation in a try-except block.
Manually call file.close() in a finally block.
Use a context manager with the 'with' statement.
A context manager using 'with' guarantees __exit__ runs on block exit, including on exceptions, so file handles close deterministically. This satisfies the legacy-code constraint of always releasing resources, unlike relying on garbage collection or manual close calls that can be skipped.
Rely on the garbage collector to close the handle.
You are writing a library that expects a custom exception. Which practice aligns best with Python's exception handling hierarchy?
Use a mixin class without inheritance.
Inherit from StandardError.
Inherit from BaseException.
Inherit from Exception.
Inheriting from Exception satisfies the requirement that a custom exception integrates with Python's standard hierarchy, so `except Exception` handlers still catch it. Unlike BaseException subclasses, which bypass ordinary handlers, this keeps the library's errors catchable by callers while avoiding the overly broad BaseException branch.
When implementing secure coding practices in a web-facing Python application, how should you handle raw user input to prevent command injection?
Pass the entire input string to os.system().
Concatenate the input string into a shell command for execution.
Pass input arguments as a list to subprocess.run(args, shell=False).
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.
Sanitize input using a custom regex to remove special characters.
When documenting a complex function, which approach is most compliant with Google Style Python Docstrings regarding parameter types?
Use the 'Args:' section followed by the parameter name, type, and description.
Google Style mandates an `Args:` section where each parameter appears as `name (type): description`, satisfying the stem's requirement to document parameter types explicitly. This structured format lets tools such as Sphinx napoleon parse types reliably, unlike free-form prose or reStructuredText `:param:` fields, which Google Style does not use.
Embed the types directly in the function name.
Include type hints in the docstring but omit them from the function signature.
Avoid documenting types to prevent redundancy with type hints.
Want more Best Practices And Coding Conventions practice?
Practice this domainWhen using sqlite3.Row, what is the primary benefit over using a standard tuple?
It automatically commits transactions.
It provides dictionary-like access to columns by name.
sqlite3.Row wraps each result row so columns are addressable by name as well as index, unlike a plain tuple which only supports positional access. This satisfies the stem by removing the need to remember column order when reading query results.
It is faster to execute.
It supports multi-threading natively.
You are using configparser.ConfigParser to read a configuration file. You have a file where option names are case-sensitive. How do you ensure the parser respects this casing?
parser = ConfigParser(case_sensitive=True)
parser.set_case(True)
parser.optionxform = lambda x: x
Assigning an identity lambda to `optionxform` disables configparser's default lowercasing of option names, which is the mechanism that otherwise destroys case sensitivity. The stem's constraint — case-sensitive option names — is satisfied because keys are stored exactly as written in the file.
parser.read(file, case='preserve')
You are processing a CSV file using csv.DictReader. If your input file lacks a header row, how do you provide the field names?
csv.DictReader(f, headers=['a', 'b'])
csv.DictReader(f).map(['a', 'b'])
csv.DictReader(f, fieldnames=['a', 'b'])
DictReader normally consumes the first row as field names. Passing fieldnames explicitly overrides that behaviour, so each subsequent row is mapped to the supplied keys in order, satisfying the constraint of a headerless file without manual index lookups.
csv.DictReader(f, columns=['a', 'b'])
Which method in the xml.dom.minidom module is used to retrieve the value of a specific attribute of an element?
element.attr('attr_name')
element.getAttribute('attr_name')
getAttribute() reads a named attribute's value directly from an Element node, returning a string or empty string if absent. It satisfies the stem's requirement to retrieve one specific attribute by name, unlike attributes or childNodes, which expose whole collections rather than a single value.
element.getAttributeNode('attr_name').value
element.value('attr_name')
element['attr_name']
You need to configure the logging module to capture logs from multiple modules while ensuring that logs from third-party libraries (e.g., 'urllib3') are only captured at the WARNING level. How do you set this?
logging.getLogger('urllib3').setLevel(logging.WARNING)
Setting the level on the 'urllib3' logger object directly raises its effective threshold to WARNING, so DEBUG and INFO records from that library are discarded while your own modules keep their configured levels. This satisfies the constraint of suppressing third-party noise without altering root logger behaviour.
logging.config.dictConfig({'urllib3': 'WARNING'})
logging.basicConfig(level=logging.WARNING)
logging.setLevel('urllib3', logging.WARNING)
You are using the sqlite3 module to manage a database. You need to ensure that database changes are permanently saved even if your script terminates unexpectedly. Which method should you call after an INSERT operation?
connection.save()
cursor.flush()
connection.close()
connection.commit()
Calling connection.commit() writes the pending transaction to disk, making the INSERT durable. SQLite wraps changes in an implicit transaction, so without commit they are rolled back when the script terminates unexpectedly. This directly satisfies the stem's requirement that changes be permanently saved despite abnormal termination.
Want more Library Modules practice?
Practice this domainWhen working with raw sockets, what does the 'socket.SOCK_STREAM' constant represent?
UDP datagram sockets
Raw network sockets
TCP connection-oriented sockets
SOCK_STREAM selects a connection-oriented, reliable byte-stream transport, which on IP networks maps to TCP. It satisfies the stem's requirement by guaranteeing ordered, error-checked delivery, unlike SOCK_DGRAM, which provides connectionless UDP datagrams with no delivery guarantee.
Unix domain sockets only
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?
sock.bind(('192.168.1.50', 8080))
sock.accept()
sock.connect(('192.168.1.50', 8080))
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.
sock.listen(1)
You are consuming a REST API that returns data in JSON format. After calling response.json(), you notice the data contains nested dictionaries. What is the most Pythonic way to handle a missing key in the response dictionary safely?
Wrap the access in a try-except KeyError block
Check 'if 'key' in response.json():' before access
Use response.json()['key'] and assume the API schema is always correct
Use response.json().get('key', default_value)
dict.get returns the supplied default when the key is absent, avoiding a KeyError without try/except. This handles missing keys in the nested JSON-derived dictionary safely and concisely, satisfying the stem's requirement for the most Pythonic approach.
When using the 'socket' module, what is the effect of calling 'socket.settimeout(5.0)' on a socket object?
It sets the send buffer size to 5.0 bytes
It causes the operation to raise a socket.timeout after 5 seconds
Setting a socket timeout places the descriptor in non-blocking mode with a deadline: blocking calls such as `recv()`, `send()` or `accept()` raise `socket.timeout` once 5 seconds elapse without completing. This satisfies the stem's requirement that the operation itself fails after the specified interval rather than waiting indefinitely.
It blocks the thread for exactly 5 seconds
It forces the socket to close after 5 seconds of inactivity
In the 'requests' library, which HTTP method is typically used to update an existing resource on a server?
PUT
PUT replaces the entire target resource representation at its URI, making it the standard method for full updates. PATCH performs partial modification, while POST typically creates a new subordinate resource rather than updating an existing one.
POST
GET
DELETE
You are building a REST client that needs to handle 429 Too Many Requests status codes. Which strategy is most effective when implementing an automatic retry mechanism?
Implement an exponential backoff strategy with jitter
Exponential backoff with jitter progressively lengthens delays between retries while randomising them, preventing thundering-herd synchronisation. This directly addresses the 429 constraint by spacing retries so the client stops overwhelming the rate-limited server, unlike fixed-interval retries that keep colliding.
Switch to a different base URL immediately
Ignore 429 errors and continue execution
Retry immediately in a loop until successful
Want more Networking And Restful Apis practice?
Practice this domainThe PCPP1 exam has 45 questions and must be completed in 65 minutes. The passing score is 70%. Always confirm current details on the vendor's official exam page.
Scenario-based questions covering exam objectives with detailed answer explanations.
The exam covers 5 domains: Advanced Object Oriented Programming, Graphical User Interface Programming, Best Practices And Coding Conventions, Library Modules, Networking And Restful Apis. Questions are weighted by domain — higher-weight domains appear more on your actual exam.
No. These are original exam-style practice questions written against the official Python Institute PCPP1 exam objectives. They are not copied from the real exam. Courseiva focuses on genuine understanding, not memorisation of braindumps.
Courseiva tracks your accuracy per domain and routes you toward weak areas automatically. Free, no account required.