Certified Associate Python Programmer PCAP (PCAP) — Questions 151225

511 questions total · 7pages · All types, answers revealed

Page 2

Page 3 of 7

Page 4
151
MCQhard

A developer writes a class 'Logger' with a class method 'log(msg)' that writes to a file. Another class 'AppLogger' inherits from 'Logger'. The developer expects both classes to share the same file handle. However, after creating an instance of 'AppLogger', the file handle is different. What is the most likely cause?

A.The 'log' method is defined as a class method using @classmethod
B.The file handle is opened in the __init__ method of the base class
C.The file handle is stored as a private attribute __file
D.The subclass overrides the 'log' method
AnswerB

Opening in __init__ creates a new handle per instance, not shared.

Why this answer

Option B is correct because if the file handle is opened in the `__init__` method of the base class, each time a new instance is created (including when an `AppLogger` instance is created), a new file handle is opened. This means the `Logger` class and the `AppLogger` class do not share the same file handle; instead, each instance gets its own handle. To share a single file handle across all instances, the file handle should be opened as a class attribute or in a class method, not in `__init__`.

Exam trap

The trap here is that candidates often confuse instance attributes with class attributes, assuming that inheritance automatically shares instance-level resources, when in fact each instance gets its own copy of attributes defined in `__init__`.

How to eliminate wrong answers

Option A is wrong because using `@classmethod` for the `log` method does not cause different file handles; it simply means the method receives the class as the first argument, not the instance. The file handle sharing issue is about where the handle is opened, not the method decorator. Option C is wrong because storing the file handle as a private attribute `__file` (name mangling) does not inherently cause different handles; it only affects attribute access from subclasses.

The core issue remains that the handle is opened per instance in `__init__`. Option D is wrong because overriding the `log` method in the subclass would change the behavior of logging, but it would not cause the file handle to be different unless the override itself opens a new handle. The question states the developer expects both classes to share the same handle, and the problem is that after creating an instance of `AppLogger`, the handle is different—this points to the handle being created per instance, not to an override.

152
MCQmedium

An engineer is debugging an application that uses inheritance. The base class 'Vehicle' defines a method 'start()' that prints 'Vehicle started'. The subclass 'Car' overrides 'start()' to print 'Car started'. The code contains a function that accepts a Vehicle object and calls 'start()'. What is the output if a Car object is passed?

A.'Car started Vehicle started'
B.'Vehicle started'
C.'Car started'
D.AttributeError
AnswerC

Polymorphism: the overridden method in Car is called.

Why this answer

When a Car object is passed to a function expecting a Vehicle reference, Python uses dynamic dispatch (late binding) to call the overridden `start()` method defined in the Car class. Since the actual runtime type is Car, the overridden version executes, printing 'Car started'. This is a fundamental principle of polymorphism in Python.

Exam trap

Python Institute often tests the misconception that the declared parameter type (Vehicle) determines which method runs, leading candidates to pick 'Vehicle started', when in fact Python always uses the actual object's type at runtime.

How to eliminate wrong answers

Option A is wrong because it suggests both the base and subclass methods execute, which would require explicit super() calls or chained execution not present in the code. Option B is wrong because it assumes static binding based on the parameter type, ignoring Python's runtime method resolution. Option D is wrong because no AttributeError occurs; Car inherits from Vehicle and correctly overrides start(), so the method exists and is callable.

153
MCQeasy

In Python, if you have a try block followed by an except clause that catches all exceptions, which of the following is true about the else clause?

A.The else clause runs only if no exception is raised in the try block.
B.The else clause runs only if an exception occurs.
C.The else clause runs before the finally block regardless of exceptions.
D.The else clause is used to specify additional exception handlers.
AnswerA

Correct: else executes when try block completes without exception.

Why this answer

In Python, the `else` clause in a `try` statement executes only if no exception was raised in the `try` block. This is true regardless of whether the `except` clause catches all exceptions (e.g., bare `except:` or `except Exception:`). The `else` block is specifically designed for code that should run only when the `try` block completes successfully without any exception.

Exam trap

The trap here is that candidates often confuse the `else` clause with a second chance to handle exceptions or think it runs unconditionally before `finally`, when in fact it is strictly tied to the successful execution of the `try` block and is skipped entirely if any exception occurs.

How to eliminate wrong answers

Option B is wrong because the `else` clause runs only when no exception occurs, not when an exception occurs; code that runs on an exception belongs in the `except` block. Option C is wrong because the `else` clause runs before the `finally` block only if no exception was raised, but if an exception is raised, the `else` block is skipped entirely and the `finally` block still runs; the order is not guaranteed to be `else` before `finally` in all cases. Option D is wrong because the `else` clause is not used to specify additional exception handlers; additional exception handlers are specified by additional `except` clauses, while the `else` clause is for code that executes only on successful completion of the `try` block.

154
MCQmedium

What is the output of the code?

A.20
B.AttributeError: 'Derived' object has no attribute 'get_x'
C.10
D.AttributeError: 'Derived' object has no attribute '_x'
AnswerA

Derived.__init__ sets _x to 20, and get_x returns it.

Why this answer

Option A is correct because the `Derived` class inherits the `get_x` method from the `Base` class, which returns `self._x`. When `obj.get_x()` is called, `self` refers to the `Derived` instance, and `self._x` accesses the `_x` attribute set in `Derived.__init__` (value 20). The `_x` attribute in `Derived` shadows the one in `Base`, so the output is 20.

Exam trap

Python Institute often tests the distinction between attribute shadowing and method inheritance, specifically that a derived class can override an attribute without calling the base class constructor, leading to unexpected values when inherited methods access that attribute.

How to eliminate wrong answers

Option B is wrong because `Derived` inherits `get_x` from `Base`, so the object does have that method; no AttributeError occurs. Option C is wrong because the `Derived` constructor sets `self._x = 20`, overriding the `_x = 10` set in `Base.__init__` (since `Derived.__init__` is called and does not call `super().__init__()`), so the value returned is 20, not 10. Option D is wrong because `_x` is a regular attribute (not a private name-mangled attribute), so it is accessible directly; no AttributeError occurs for `_x`.

155
MCQeasy

A developer creates a package named 'mypkg' with an __init__.py file. Inside the package, there is a module 'utils.py'. Which of the following is the correct way to import the function 'helper' from 'utils' from outside the package?

A.import mypkg.utils.helper
B.import mypkg; mypkg.utils.helper
C.from mypkg.utils import helper
D.from mypkg import utils.helper
AnswerC

Correct dot notation to import from a submodule.

Why this answer

Option C is correct because it uses the standard Python syntax for importing a specific name from a submodule within a package: `from package.module import name`. This directly imports the `helper` function into the current namespace, making it callable without any prefix. The `__init__.py` file marks `mypkg` as a package, and `utils.py` is a module inside it, so `from mypkg.utils import helper` is the proper way to access `helper` from outside the package.

Exam trap

Python Institute often tests the distinction between importing a module versus importing an attribute from a module, and the trap here is that candidates confuse the `import` statement (which only accepts modules/packages) with the `from ... import` statement (which can import any object), leading them to choose Option A or D.

How to eliminate wrong answers

Option A is wrong because `import mypkg.utils.helper` attempts to import a module named `helper`, but `helper` is a function, not a module; Python's import system only supports importing modules or packages, not individual objects like functions or classes, via the `import` statement. Option B is wrong because `mypkg.utils.helper` is not a valid attribute access after `import mypkg`; `import mypkg` only imports the top-level package, and to access `utils` you would need to import `mypkg.utils` explicitly (e.g., `import mypkg.utils`), otherwise `mypkg.utils` is undefined. Option D is wrong because `from mypkg import utils.helper` uses dot notation in the import name, which is invalid syntax; the `from ... import` statement expects a single module or a comma-separated list of names, not a dotted path to an attribute.

156
MCQmedium

A programmer uses a class method to create an alternative constructor for a `Point` class. The method should parse a string like "10,20" and return a `Point` instance with x=10, y=20. Which code snippet correctly implements this?

A.`def from_string(self, s):\n parts = s.split(',')\n return Point(int(parts[0]), int(parts[1]))`
B.`@staticmethod\ndef from_string(s):\n parts = s.split(',')\n return Point(int(parts[0]), int(parts[1]))`
C.`def from_string(cls, s):\n parts = s.split(',')\n return cls(int(parts[0]), int(parts[1]))`
D.`@classmethod\ndef from_string(cls, s):\n parts = s.split(',')\n return cls(int(parts[0]), int(parts[1]))`
AnswerD

This correctly uses `@classmethod` and calls `cls` to create a new instance.

Why this answer

A class method receives the class as the first argument (`cls`) and can be used to create instances via `cls(...)`. The `@classmethod` decorator is required.

157
MCQhard

You are a Python developer at a financial firm. Your team maintains a high-frequency trading system that reads real-time market data from a binary file 'market_feed.bin'. The file is updated every millisecond by an external process. Your script uses a `with` statement to open the file in binary read mode and reads exactly 1024 bytes each iteration in an infinite loop. Recently, the script has been crashing intermittently with an `OSError` with message '[Errno 9] Bad file descriptor'. The error occurs at random times, sometimes after minutes, sometimes after hours. The system runs on Linux. The script runs as a daemon. You suspect the issue is related to file descriptor exhaustion or the external process manipulating the file. What is the most likely cause and the best course of action?

A.Open the file without using a context manager and manually close it after each read.
B.Increase the read buffer size to 4096 bytes to reduce the number of read operations.
C.Catch OSError and re-open the file within the except block, then continue reading.
D.Use file locking (e.g., fcntl.flock) to coordinate access with the external process, and re-open the file if a lock cannot be acquired.
AnswerD

File locking prevents the external process from truncating the file while your script is reading, avoiding the bad file descriptor.

Why this answer

The most likely cause is that the external process overwrites or truncates 'market_feed.bin' between reads, causing the file descriptor held by the Python script to become invalid (stale). On Linux, when a file is replaced or truncated by another process, the original file descriptor may point to a deleted inode, and subsequent reads yield 'Bad file descriptor'. Option D is correct because file locking (e.g., fcntl.flock with LOCK_SH or LOCK_EX) coordinates access, and re-opening the file after a lock failure ensures a fresh, valid descriptor.

Exam trap

Python Institute often tests the misconception that catching and retrying an OSError (Option C) is sufficient, but the trap is that it ignores the underlying race condition and can lead to infinite loops or data corruption, whereas proper synchronization (Option D) prevents the error from occurring in the first place.

How to eliminate wrong answers

Option A is wrong because opening without a context manager and manually closing does not address the root cause—the external process invalidates the descriptor regardless of how it was opened. Option B is wrong because increasing the buffer size to 4096 bytes only reduces the number of read operations but does not prevent the descriptor from becoming stale; the error can still occur on the next read. Option C is wrong because catching OSError and re-opening within the except block is a reactive fix that does not prevent the race condition; it may also lead to infinite error loops if the external process continuously replaces the file.

158
Matchingmedium

Match each exception to its cause.

Drag a concept onto its matching description — or click a concept then click the description.

Concepts
Matches

Operation on incompatible type

Function receives argument with correct type but invalid value

Sequence subscript out of range

Mapping key not found

Attribute reference or assignment fails

Why these pairings

These are standard Python exceptions.

159
MCQmedium

A developer wants to remove all leading and trailing whitespace from a string, but preserve internal spaces. Which line of code accomplishes this?

A.s = s.lstrip()
B.s = s.strip().lstrip()
C.s = s.replace(' ', '')
D.s = s.strip()
AnswerD

Removes leading and trailing whitespace only.

Why this answer

Option D is correct because `s.strip()` removes all leading and trailing whitespace characters (spaces, tabs, newlines) from the string while preserving internal spaces. This is the exact requirement: eliminate whitespace at the boundaries only, leaving the internal content unchanged.

Exam trap

Python Institute often tests the distinction between `strip()`, `lstrip()`, and `rstrip()`, and the trap here is that candidates may confuse `strip()` with `replace(' ', '')` or think that `lstrip()` alone is sufficient, failing to recognize that `strip()` handles both ends in one call.

How to eliminate wrong answers

Option A is wrong because `s.lstrip()` only removes leading whitespace, leaving trailing whitespace intact. Option B is wrong because `s.strip().lstrip()` is redundant — `strip()` already removes both leading and trailing whitespace, so calling `lstrip()` afterward does nothing extra and is unnecessary. Option C is wrong because `s.replace(' ', '')` removes all spaces in the string, including internal ones, which destroys the internal spacing the developer wants to preserve.

160
Multi-Selectmedium

Which TWO methods are valid ways to import a function named 'foo' from a module 'bar' that is part of a package 'pkg'?

Select 2 answers
A.import bar
B.from pkg.bar import foo
C.import pkg; pkg.bar.foo
D.from pkg import bar; bar.foo
E.import pkg.bar.foo
AnswersB, D

Correct absolute import.

Why this answer

Option B is correct because the 'from pkg.bar import foo' syntax directly imports the 'foo' function from the 'bar' submodule within the 'pkg' package, making 'foo' available in the current namespace. Option D is also correct because it first imports the 'bar' module from 'pkg' using 'from pkg import bar', then accesses 'foo' as an attribute of 'bar' (bar.foo), which is a valid two-step approach.

Exam trap

Python Institute often tests the distinction between importing a module versus importing an attribute from a module, and the trap here is that candidates mistakenly think 'import pkg.bar.foo' (Option E) is valid syntax, when in fact you can only import modules or packages with the dotted-path import statement, not functions or classes.

161
MCQhard

Refer to the exhibit. If both data.txt and backup.txt do not exist, what is the output?

A.Prints contents of backup.txt
B.Nothing
C.FileNotFoundError
D.'No file found'
AnswerD

Correct output from inner except.

Why this answer

Option D is correct because the code uses a try-except block to catch FileNotFoundError when attempting to open 'data.txt'. In the except block, it prints 'No file found' and then attempts to open 'backup.txt'. Since both files do not exist, the except block executes and prints 'No file found' before the second open attempt raises another FileNotFoundError, which is unhandled and terminates the program.

However, the question asks for the output, which is the print statement executed before the error.

Exam trap

Python Institute often tests the distinction between output produced before an unhandled exception and the exception itself, tricking candidates into thinking the program crashes without any output.

How to eliminate wrong answers

Option A is wrong because backup.txt does not exist, so its contents cannot be printed; the code would raise a FileNotFoundError on the second open attempt. Option B is wrong because the except block explicitly prints 'No file found' before the second open attempt, so something is output. Option C is wrong because while a FileNotFoundError does occur on the second open, the question asks for the output, not the exception; the print statement executes first, producing output.

162
Multi-Selecthard

Given s = 'Python', which THREE of the following expressions evaluate to True? (Choose three.)

Select 3 answers
A.'th' in s
B.s[0] == 'p'
C.s.isupper()
D.s.isalpha()
E.s.istitle()
AnswersA, D, E

Correct: 'th' is a substring of 'Python'.

Why this answer

'th' is a substring of 'Python', so 'th' in s is True. s.isalpha() returns True because all characters are alphabetic. s.istitle() returns True because the string is titlecased (first uppercase, rest lowercase). s.isupper() is False because not all letters are uppercase. s[0] == 'p' is False because the first character is 'P', not 'p'.

163
MCQeasy

A beginner programmer writes: name = "Alice"; print("Hello " + name). Which string method alternative is more efficient and recommended for Python 3?

A.print("Hello {}".format(name))
B.print("Hello %s" % name)
C.print(f"Hello {name}")
D.print("Hello " + name) is fine
AnswerC

f-strings are concise, readable, and the preferred method in modern Python.

Why this answer

Option C is correct because f-strings (formatted string literals) are the most efficient and readable string formatting method introduced in Python 3.6. They evaluate expressions at runtime and directly interpolate variables into the string, avoiding the overhead of method calls or the older %-formatting, making them both faster and more Pythonic.

Exam trap

Python Institute often tests the distinction between older formatting methods (%-formatting and str.format()) and the modern f-string syntax, trapping candidates who think any valid method is equally recommended, when in fact f-strings are the preferred and most efficient choice in Python 3.6+.

How to eliminate wrong answers

Option A is wrong because str.format() is less efficient than f-strings due to the overhead of a method call and additional parsing, and it is not the recommended approach for simple variable interpolation in modern Python 3. Option B is wrong because the %-formatting style is the legacy C-style printf approach, which is less readable, less flexible, and deprecated in favor of f-strings and str.format(). Option D is wrong because simple concatenation with + creates multiple intermediate string objects and is less efficient and less readable than f-strings, especially when combining multiple variables or expressions.

164
MCQhard

A function processes a Unicode string that may contain combining characters (e.g., 'é' as 'e' plus combining acute accent). The function must return the number of visible grapheme clusters (user-perceived characters). Which of the following is the most reliable built-in approach?

A.import unicodedata; len(unicodedata.normalize('NFC', s))
B.len(s)
C.sum(1 for c in s if not unicodedata.combining(c))
D.len(s.encode('utf-8'))
AnswerA

Normalizes to composed form, so combining sequences become single code points, improving accuracy for many common cases.

Why this answer

Option C normalizes to NFC, which composes many combining sequences into single code points, allowing len() to return a closer count of visible characters. Option A counts code points individually, overcounting. Option B counts bytes.

Option D filters out combining characters, undercounting.

165
MCQmedium

What is the output of the code?

A.Prints all lines in the file.
B.Raises an unhandled exception.
C.Prints all lines containing 'ERROR'
D.Error found: 2025-03-15 10:23:45 ERROR: Division by zero in module calc.py line 42
AnswerD

First ERROR line is raised and printed.

Why this answer

The code reads a log file line by line and checks if the line contains the substring 'ERROR'. When it finds the line '2025-03-15 10:23:45 ERROR: Division by zero in module calc.py line 42', it prints 'Error found: ' followed by that line. After printing, it breaks out of the loop, so only the first matching line is output.

Option D correctly describes this behavior.

Exam trap

Python Institute often tests the subtlety of the `break` statement inside a loop, leading candidates to mistakenly think all matching lines are printed instead of only the first.

How to eliminate wrong answers

Option A is wrong because the code does not print all lines; it only prints lines containing 'ERROR' and then breaks after the first match. Option B is wrong because no exception is raised; the file is opened with a context manager, read line by line, and the substring check is safe. Option C is wrong because although the code does print lines containing 'ERROR', it only prints the first such line (due to the break statement), not all of them.

166
MCQeasy

A developer is building a simulation of different types of vehicles. They have a base class Vehicle with an attribute speed initialized in __init__. They also have a subclass Car that inherits from Vehicle and adds an attribute fuel_type. The developer wants to ensure that every time a Car object is created, it also initializes the speed attribute from the Vehicle class. Which approach should the developer use?

A.Override the __new__ method of Vehicle.
B.In Car.__init__, call Vehicle.__init__(self) manually.
C.Use the @staticmethod decorator for initialization.
D.In Car.__init__, define speed directly without calling parent's __init__.
AnswerB

This ensures the parent's __init__ executes, initializing speed.

Why this answer

Option B is correct because in Python, when a subclass overrides __init__, the parent class's __init__ is not automatically called. To ensure the speed attribute from Vehicle is initialized, the developer must explicitly call Vehicle.__init__(self) inside Car.__init__. This is a fundamental requirement of Python's inheritance mechanism for proper initialization of inherited attributes.

Exam trap

Python Institute often tests the misconception that subclass __init__ automatically calls the parent __init__, leading candidates to incorrectly assume no explicit call is needed or to choose a wrong option like D.

How to eliminate wrong answers

Option A is wrong because overriding __new__ is used for controlling object creation (e.g., singletons) and is not the standard way to initialize inherited instance attributes; __init__ is the correct place for initialization. Option C is wrong because the @staticmethod decorator defines a method that does not receive self or cls, and cannot be used to initialize instance attributes like speed or fuel_type; it is unrelated to inheritance initialization. Option D is wrong because defining speed directly in Car.__init__ without calling the parent's __init__ duplicates logic and breaks the principle of code reuse; it also risks missing any additional initialization that Vehicle.__init__ might perform in the future.

167
MCQmedium

A developer is designing a system where a `Car` class needs to reuse functionality from `Engine` and `Transmission` without creating a deep hierarchy. Which OOP principle should be applied?

A.Aggregation, where Car is part of Engine.
B.Singleton pattern for Engine.
C.Multiple inheritance to inherit from both.
D.Composition over inheritance.
AnswerD

Car has an Engine and a Transmission, favoring composition.

Why this answer

Option D, 'Composition over inheritance,' is correct because it advocates building the Car class by composing it with Engine and Transmission objects (has-a relationships) rather than inheriting from them. This avoids a deep class hierarchy and provides flexibility to change or swap components at runtime, which is a key design principle in Python and OOP.

Exam trap

Python Institute often tests the distinction between 'is-a' (inheritance) and 'has-a' (composition) relationships, and the trap here is that candidates mistakenly choose multiple inheritance (Option C) because they think reusing functionality requires inheritance, ignoring the complexity and the explicit instruction to avoid a deep hierarchy.

How to eliminate wrong answers

Option A is wrong because Aggregation defines a 'has-a' relationship where the part (Engine) can exist independently of the whole (Car), but the statement 'Car is part of Engine' reverses the relationship and is semantically incorrect. Option B is wrong because the Singleton pattern ensures only one instance of a class, which is irrelevant to reusing functionality from Engine and Transmission; it solves a different problem (global state control). Option C is wrong because multiple inheritance can lead to the diamond problem and increased complexity, and the question explicitly wants to avoid a deep hierarchy; composition is the recommended alternative.

168
MCQmedium

A developer needs to parse a log file where each line contains a timestamp followed by a message. The timestamp format is 'YYYY-MM-DD HH:MM:SS'. Which string method is most appropriate to split the timestamp from the message?

A.str.rsplit()
B.str.splitlines()
C.str.partition()
D.str.split()
AnswerD

str.split() by default splits on whitespace, which can separate the timestamp and message when the timestamp contains no internal spaces.

Why this answer

Option D, str.split(), is the most appropriate because it splits a string on whitespace by default, and the timestamp 'YYYY-MM-DD HH:MM:SS' contains a space between the date and time. Using split() with maxsplit=1 would separate the line into exactly two parts: the timestamp and the rest of the message, which is exactly what the developer needs.

Exam trap

Python Institute often tests the distinction between str.split() and str.partition(), where candidates mistakenly choose str.partition() because they think it splits on the first space, but fail to realize that the timestamp itself contains a space, causing an incorrect split.

How to eliminate wrong answers

Option A is wrong because str.rsplit() splits from the right side of the string, which would incorrectly separate the last word of the message rather than the first space after the timestamp. Option B is wrong because str.splitlines() splits on line boundaries (newline characters), not on whitespace within a single line, so it cannot separate the timestamp from the message on the same line. Option C is wrong because str.partition() splits on the first occurrence of a specific separator string, but the timestamp contains spaces (between date and time), so using a space as the separator would split the timestamp itself, not separate it from the message.

169
MCQeasy

A developer creates a Python class with a method that is intended to be overridden in subclasses. Which approach best ensures that the method is not accidentally called on the base class?

A.Use 'pass' as the method body
B.Delete the method from the base class using 'del'
C.Add a comment '# override in subclass' inside the method body
D.Raise NotImplementedError inside the method body
AnswerD

Raising NotImplementedError clearly signals the method must be overridden.

Why this answer

Raising NotImplementedError inside the base class method is the standard Python idiom for defining an abstract-like method that must be overridden in subclasses. If a subclass fails to override the method and it is called, Python will raise an explicit error at runtime, preventing accidental use of the base implementation. This approach enforces the contract that the method is intended only for subclasses, without requiring the `abc` module.

Exam trap

Python Institute often tests the distinction between documentation-based approaches (comments) and runtime enforcement (exceptions), leading candidates to mistakenly choose a comment or 'pass' as sufficient for preventing accidental base class usage.

How to eliminate wrong answers

Option A is wrong because using 'pass' as the method body creates a no-op method that silently does nothing when called on the base class, which defeats the purpose of preventing accidental invocation. Option B is wrong because deleting the method from the base class with 'del' would cause an AttributeError when the method is called on a base class instance, but it also prevents subclasses from inheriting and overriding the method, breaking the intended design. Option C is wrong because adding a comment '# override in subclass' inside the method body has no runtime effect; it is merely a documentation hint that does not enforce or prevent any behavior.

170
MCQhard

A developer wants a class 'LoggedDict' that behaves like a dict but logs all attribute access in the console. Which method override correctly implements this for getting an attribute?

A.def __get__(self, instance, owner): print(f'Access'); return self
B.def __getattribute__(self, name): print(f'Access {name}'); return super().__getattribute__(name)
C.def __getattr__(self, name): print(f'Access {name}'); return self.__dict__[name]
D.def __getitem__(self, key): print(f'Access {key}'); return dict.__getitem__(self, key)
AnswerB

This intercepts all attribute accesses, logs them, and then delegates to the normal lookup.

Why this answer

Option B is correct because `__getattribute__` is the universal method called for every attribute access on an object. By overriding it, the developer can log the attribute name before delegating to the superclass implementation via `super().__getattribute__(name)`, which preserves the normal attribute lookup chain. This ensures that all attribute accesses (including those that exist and those that don't) are logged, which is the requirement for 'LoggedDict'.

Exam trap

Python Institute often tests the distinction between `__getattribute__` (called for every attribute access) and `__getattr__` (called only as a fallback when the attribute is not found), leading candidates to mistakenly choose `__getattr__` because it seems simpler or because they confuse it with the general 'get attribute' concept.

How to eliminate wrong answers

Option A is wrong because `__get__` is the descriptor protocol method, invoked when an attribute is accessed on a class that owns a descriptor instance, not for general attribute access on a dict-like object. Option C is wrong because `__getattr__` is only called when normal attribute lookup fails (i.e., when `__getattribute__` raises an AttributeError), so it would not log successful accesses; additionally, using `self.__dict__[name]` bypasses the dict's own storage and can cause infinite recursion or missing keys. Option D is wrong because `__getitem__` is used for subscription access (e.g., `obj[key]`), not for attribute access (e.g., `obj.attr`); it would log dictionary key lookups, not attribute accesses.

171
MCQmedium

A function attempts to write to a file and needs to ensure the file is closed even if an exception occurs. Which code snippet guarantees closure?

A.f = open('file.txt', 'w'); f.write('data'); f.close()
B.with open('file.txt', 'w') as f: f.write('data')
C.f = open('file.txt', 'w'); try: f.write('data'); except: pass; f.close()
D.f = open('file.txt', 'w'); try: f.write('data'); finally: f.close()
AnswerB

Context manager ensures closure automatically.

Why this answer

Option A is correct because the 'with' statement provides a context manager that automatically closes the file, ensuring closure even if an exception occurs. Option B also guarantees closure but is less idiomatic. Option C does not handle exceptions.

Option D may not close on some exceptions.

172
MCQeasy

A developer uses the .index() method on a string to find the position of a substring. If the substring is not found, what exception is raised?

A.KeyError
B.IndexError
C.ValueError
D.TypeError
AnswerC

.index() raises ValueError if the substring is not found.

Why this answer

Option B is correct; .index() raises ValueError when the substring is not found. Option A (IndexError) is for out-of-range indexing. Option C (KeyError) is for dictionary keys.

Option D (TypeError) is for type mismatches.

173
MCQmedium

A developer needs to combine a list of 10,000 strings into a single string. Which approach is most efficient in terms of memory and performance?

A.Use ''.join(string_list)
B.Use a loop with str += to concatenate each string
C.Use str.replace() to merge the strings
D.Use str.format() to build the string step by step
AnswerA

''.join() allocates a single string with the total length and fills it, making it the most efficient.

Why this answer

The `''.join(string_list)` method is the most efficient because it pre-allocates memory for the final string by first calculating the total length of all strings in the list, then building the result in a single pass. This avoids the quadratic time complexity and repeated memory reallocations caused by string immutability in Python when using `+=` in a loop.

Exam trap

Python Institute often tests the misconception that `+=` is efficient for string concatenation because it works in other languages, but in Python, string immutability makes it a performance disaster for large lists.

How to eliminate wrong answers

Option B is wrong because using `str +=` in a loop creates a new string object for each concatenation, leading to O(n²) time complexity and excessive memory allocation due to Python's immutable strings. Option C is wrong because `str.replace()` is designed for substring replacement, not concatenation, and would require an initial string to operate on, making it unsuitable and inefficient for merging a list of strings. Option D is wrong because `str.format()` is intended for formatting placeholders, not for concatenating an arbitrary list of strings, and using it iteratively would still involve repeated string creation and poor performance.

174
MCQeasy

A developer wants to check if a string contains only alphabetic characters. Which string method should be used?

A.isalnum()
B.isspace()
C.isalpha()
D.isdigit()
AnswerC

Correct: Returns True if all characters are alphabetic.

Why this answer

The isalpha() method returns True if all characters in the string are letters. isalnum() allows digits, isdigit() only digits, and isspace() only whitespace.

175
MCQhard

A team is developing a large application that consists of multiple components, each housed in separate directories. They want to organize these components under a common namespace package called 'app'. The directory structure is as follows: /opt/project/ ├── components/ │ ├── auth/ (contains __init__.py and modules) │ └── billing/ (contains __init__.py and modules) ├── main.py └── another_location/ └── reports/ (contains __init__.py and modules) The team wants to allow all these components to be imported as subpackages of 'app', e.g., 'import app.auth', 'import app.billing', 'import app.reports'. They have ensured that none of the directories named 'app' exist; instead, they plan to use namespace packages. They create a directory '/opt/project/app/' with an __init__.py file, and move the auth and billing directories under it. However, the reports directory must remain at '/opt/project/another_location/reports/', but they want it to be accessible as 'app.reports'. They attempt to achieve this by adding '/opt/project/another_location/' to the sys.path. When they run main.py, they get an ImportError: No module named 'app.reports'. The auth and billing modules work fine. What is the most likely issue and the correct fix?

A.The sys.path modification is not persistent; they need to set the PYTHONPATH environment variable.
B.The reports package needs to be moved under the app directory physically.
C.The reports directory has an __init__.py file, which conflicts with the namespace package.
D.The app directory has an __init__.py file, which prevents it from being a namespace package. Remove the __init__.py from the app directory.
AnswerD

A namespace package must not have __init__.py; removing it allows the package to be split across multiple directories on sys.path.

Why this answer

Option A is correct because the 'app' directory has an __init__.py file, making it a regular package. Namespace packages must not have __init__.py in the top-level directory to allow extending via sys.path. Removing __init__.py from app/ turns it into a namespace package, allowing reports from another_location to be found.

Option B is incorrect because subpackages can have __init__.py. Option C is incorrect because sys.path modifications are effective for the session. Option D is incorrect because namespace packages are designed to span multiple directories without moving files.

176
MCQmedium

A developer is creating a package that contains a subpackage. The subpackage has an __init__.py file that imports a module named 'helper' from the parent package. Which import statement in the subpackage's __init__.py will correctly import 'helper'?

A.from mypackage import helper
B.from . import helper
C.from ... import helper
D.from .. import helper
AnswerA

This absolute import explicitly specifies the package hierarchy.

Why this answer

Option A is correct because the subpackage's __init__.py needs to import the 'helper' module from the parent package using an absolute import. The statement 'from mypackage import helper' explicitly references the parent package by its name, which is the standard way to import from a parent package when the package structure is known and avoids ambiguity with relative imports.

Exam trap

Python Institute often tests the confusion between relative import syntax (dots) and absolute imports, tricking candidates into thinking that 'from .. import helper' is the correct way to import from a parent package in a subpackage's __init__.py, when in fact the absolute import is the correct and intended answer for this scenario.

How to eliminate wrong answers

Option B is wrong because 'from . import helper' uses a relative import that refers to the current package (the subpackage itself), not the parent package, so it would look for 'helper' inside the subpackage, not the parent. Option C is wrong because 'from ... import helper' uses three dots, which would go up two levels (grandparent), not one level to the parent, and is incorrect for importing from the immediate parent. Option D is wrong because 'from .. import helper' uses two dots, which in Python relative imports means going up one level from the current package, but this syntax is used within a module inside the subpackage, not in the subpackage's __init__.py itself; in __init__.py, '..' refers to the parent of the subpackage, but the correct relative import would be 'from .. import helper' only if the subpackage is a direct child of the parent, but the question specifies the subpackage's __init__.py, and the absolute import is the safer and intended approach.

177
MCQhard

You are working on a legacy system that processes financial transactions. The system uses a class hierarchy: Transaction (base), Deposit, Withdrawal, Transfer. Each subclass overrides a method 'process()' to handle its specific logic. The code often runs in a multi-threaded environment and you notice intermittent errors where a transaction is processed twice. The logging shows that the same transaction object is being passed to the process method multiple times. The transaction objects are created from a factory function that caches recently used transactions. The errors seem to occur when two threads call the factory at the same time with the same parameters. After investigating, you find that the factory uses a class-level dictionary to cache objects. Which of the following is the most appropriate solution to prevent double processing?

A.Add a lock around the cache lookup and creation in the factory function
B.Add a flag to each transaction object to indicate if it has been processed, and check it at the start of process()
C.Remove the caching mechanism from the factory function to ensure new objects are always created
D.Make the process() method idempotent by checking if the transaction has already been applied to the account (e.g., check balance changes)
AnswerD

Idempotency ensures that repeated calls do not cause duplicate effects, which is the safest approach in a multi-threaded environment.

Why this answer

Option D is correct because the core issue is that the same transaction object can be processed multiple times in a multi-threaded environment, even if the factory is fixed. Making process() idempotent by checking whether the transaction has already been applied (e.g., verifying account balance changes) ensures that repeated calls with the same object do not cause duplicate financial effects, directly addressing the symptom of double processing regardless of how the object is cached or retrieved.

Exam trap

Python Institute often tests the misconception that preventing object reuse or adding locks in the factory is sufficient to fix double processing, when the real requirement is to make the operation itself idempotent to handle any scenario where the same object is processed more than once.

How to eliminate wrong answers

Option A is wrong because adding a lock around the cache lookup and creation only prevents race conditions in the factory, but does not prevent the same transaction object from being passed to process() multiple times after it has been created; the double processing can still occur if the object is reused or if the calling code erroneously invokes process() again. Option B is wrong because adding a processed flag to the transaction object is not thread-safe without additional synchronization; two threads could both check the flag before either sets it, leading to a race condition where both proceed to process the transaction, and it also violates the principle of keeping processing logic separate from state management. Option C is wrong because removing the caching mechanism eliminates the performance benefit of reusing objects but does not solve the fundamental problem: the same transaction object could still be passed to process() multiple times from other parts of the code, and without idempotency, double processing would still occur.

178
Multi-Selectmedium

Which TWO of the following methods return a boolean value?

Select 2 answers
A.str.upper()
B.str.isspace()
C.str.split()
D.str.join()
E.str.isalpha()
AnswersB, E

Returns True if all characters are whitespace.

Why this answer

The methods `str.isspace()` and `str.isalpha()` are both string methods that return a boolean value (`True` or `False`) based on whether the string meets specific character classification criteria. `isspace()` returns `True` if all characters in the string are whitespace, while `isalpha()` returns `True` if all characters are alphabetic.

Exam trap

Python Institute often tests the distinction between methods that return a new string or list versus those that return a boolean, leading candidates to mistakenly select methods like `str.upper()` or `str.split()` because they appear to perform a 'check' but actually return a transformed object.

179
Multi-Selecteasy

Which TWO of the following statements about class attributes in Python are true?

Select 2 answers
A.Class attributes are always immutable.
B.Class attributes are shared by all instances.
C.Class attributes are defined inside methods.
D.Modifying a class attribute via an instance modifies it for all instances.
E.Class attributes can be accessed via the class name.
AnswersB, E

True – all instances see the same class attribute unless shadowed by an instance attribute.

Why this answer

Class attributes are accessible via the class name and are shared across all instances. Options C, D, and E are false because class attributes can be mutable (e.g., lists), modifying via an instance creates an instance attribute if assigned, and they are defined directly in the class body, not inside methods.

180
MCQmedium

A company is developing a scientific simulation framework where many different solvers must be interchangeable. The framework should enforce that each solver implements methods 'initialize' and 'step'. Developers want to use abstract base classes. Which approach should the team take to ensure that any subclass of 'Solver' cannot be instantiated unless it defines both methods?

A.Define an interface in a separate module and check using isinstance
B.Use @abstractmethod without inheriting from ABC
C.Inherit from ABC and decorate both methods with @abstractmethod
D.Define Solver with methods that raise NotImplementedError
AnswerC

This enforces that subclasses must provide implementations; they cannot be instantiated otherwise.

Why this answer

Option C is correct because inheriting from `ABC` (from the `abc` module) and decorating both `initialize` and `step` with `@abstractmethod` enforces that any concrete subclass must override these methods. Attempting to instantiate a subclass that does not implement all abstract methods raises a `TypeError`, ensuring compile-time-like safety at runtime.

Exam trap

Python Institute often tests the misconception that `@abstractmethod` alone (without inheriting from `ABC`) is sufficient to prevent instantiation, or that raising `NotImplementedError` is equivalent to abstract base class enforcement.

How to eliminate wrong answers

Option A is wrong because using `isinstance` checks against an interface in a separate module does not enforce method implementation at instantiation time; it only checks type membership, and the developer would have to manually verify methods. Option B is wrong because `@abstractmethod` without inheriting from `ABC` has no effect — Python's abstract mechanism only works when the class's metaclass is `ABCMeta` (provided by inheriting from `ABC`). Option D is wrong because defining methods that raise `NotImplementedError` only catches missing implementations at runtime when the method is called, not at instantiation time, and does not prevent instantiation of the class itself.

181
MCQhard

You are designing a class that should behave like a sequence and support slicing. Which special methods must be implemented?

A.__len__ and __contains__
B.__iter__ and __next__
C.__getitem__ alone
D.__getitem__ and __len__
E.__getitem__ and __setitem__
AnswerD

These two methods are the minimum for a sequence that supports slicing.

Why this answer

For a class to support slicing in Python, it must implement both `__getitem__` (to handle indexing and slice objects) and `__len__` (to define the sequence length, which is required for proper slice boundary handling). Together, these satisfy the sequence protocol, enabling Python's slicing syntax like `obj[start:stop:step]`.

Exam trap

Python Institute often tests the misconception that `__getitem__` alone is enough for slicing, but the trap is that `__len__` is also required for the interpreter to handle slice defaults and negative indices correctly.

How to eliminate wrong answers

Option A is wrong because `__len__` and `__contains__` are not sufficient for slicing; `__contains__` only supports the `in` operator, not indexing or slicing. Option B is wrong because `__iter__` and `__next__` make an object iterable but do not provide indexed access or slicing capabilities. Option C is wrong because `__getitem__` alone can handle basic indexing, but without `__len__`, Python cannot properly compute slice defaults (e.g., `None` for start/stop) or support negative indices in slicing.

Option E is wrong because `__setitem__` is for item assignment, not required for read-only slicing; the sequence protocol for slicing only mandates `__getitem__` and `__len__`.

182
MCQhard

A development team is building a real-time chat application using Python. The application uses a class 'ChatRoom' that maintains a list of 'User' objects as active participants. Each User object holds a reference back to its ChatRoom to send messages. Over time, the application runs out of memory. Profiling reveals that User objects are not being garbage collected even after users disconnect. The team suspects circular references. Which solution would effectively resolve the memory leak without breaking the functionality?

A.Use weakref.WeakSet for the participants list in ChatRoom, so that when a User is no longer referenced elsewhere, it is automatically removed
B.Increase the Python heap size using PYTHON_MALLOC_DEBUG to avoid memory issues
C.Store the ChatRoom reference in User using a weakref.ref, so that the cycle is broken
D.Manually call gc.collect() every time a user disconnects
AnswerA

WeakSet allows the chat room to hold references without preventing garbage collection; when the only strong references to a User are gone, it is cleaned up.

Why this answer

Option A is correct because using a `weakref.WeakSet` for the participants list in `ChatRoom` means the `ChatRoom` holds only weak references to `User` objects. When a user disconnects and all external references to that `User` are removed, the `User` object becomes unreachable and can be garbage collected, even though the `User` still holds a strong reference back to the `ChatRoom`. This breaks the circular reference without requiring manual intervention or altering the `User`-to-`ChatRoom` relationship.

Exam trap

Python Institute often tests the distinction between breaking a cycle from one side versus the other; the trap here is that candidates think weakening the `User`'s reference to `ChatRoom` (Option C) is sufficient, but they overlook that the `ChatRoom`'s strong reference to `User` keeps the `User` alive, so the cycle is still unbreakable from the garbage collector's perspective.

How to eliminate wrong answers

Option B is wrong because increasing the Python heap size does not resolve the underlying issue of circular references preventing garbage collection; it only delays the inevitable memory exhaustion. Option C is wrong because storing the `ChatRoom` reference in `User` using `weakref.ref` would break the cycle from the `User` side, but the `ChatRoom` still holds strong references to `User` objects in its participants list, so `User` objects would never become unreachable and would still leak. Option D is wrong because manually calling `gc.collect()` does not fix the root cause; the garbage collector can already collect cycles (by default), but if the `User` objects are still strongly referenced from the `ChatRoom` list, they are not garbage, and `gc.collect()` will not remove them.

183
MCQmedium

Your company has two separate Python packages: 'app' and 'lib'. They are maintained by different teams. 'app' depends on 'lib', but 'lib' is still under development and its API changes frequently. To avoid breaking 'app', the team decides to use a virtual environment and install a specific version of 'lib'. However, during development, they need to test 'app' with the latest 'lib' changes from the Git repository. The current workflow is: (1) activate virtual env, (2) install 'lib' from local source using `pip install -e /path/to/lib`. This installs 'lib' as a development package. But one developer reports that after pulling latest 'lib' changes, importing 'lib' in 'app' still uses the old version even after re-running pip install -e. What is the most likely reason?

A.Python caches imported modules in sys.modules, so importing again does not reload the module from disk.
B.The package 'lib' is being imported as a namespace package, so changes are not picked up.
C.The .pyc files are not being invalidated because the timestamps are not updated.
D.The editable install may still point to an old copy of the library if the source directory was moved or if there is a stray .egg-link file.
AnswerD

Editable installs use .egg-link or .pth files that can become stale if the source path changes.

Why this answer

The most likely reason is D. When using `pip install -e` (editable install), pip creates a special `.egg-link` file (or similar pointer) in the site-packages directory that points to the source directory. If the source directory was moved, renamed, or if a stale `.egg-link` file remains from a previous install, pip may still reference the old location, causing the old version to be imported even after re-running the install command.

This is a known subtlety of editable installs, especially when the source code is managed under version control and the directory structure changes.

Exam trap

Python Institute often tests the subtle difference between a stale import cache (sys.modules) and a stale install pointer (editable install link), leading candidates to incorrectly choose the caching option when the real issue is a broken or outdated path reference in the development install.

How to eliminate wrong answers

Option A is wrong because Python's `sys.modules` cache only affects modules already imported in the current interpreter session; re-running `pip install -e` and then starting a fresh Python process would not be affected by this cache. Option B is wrong because namespace packages are a different concept (PEP 420) and do not relate to the failure to pick up changes after an editable install; the issue is about the install pointer, not the package type. Option C is wrong because `.pyc` file invalidation is based on source file timestamps or hash comparison, and `pip install -e` does not modify `.pyc` files; the problem is that the import system is loading from a different location entirely, not that bytecode is stale.

184
MCQmedium

A Python script processes a log file line by line. If a line cannot be decoded due to an encoding error, the script should skip the line and continue. Which exception handling approach is best?

A.Wrap the entire file reading in a try-except block without specifying exception type.
B.Use a try-except-else block to handle success and failure separately, exiting on failure.
C.Inside the loop, wrap the line decoding in a try-except UnicodeDecodeError block and continue.
D.Catch Exception in the outer loop and break on error.
AnswerC

This isolates decoding issues and continues processing.

Why this answer

Option C is correct because it places the try-except block inside the loop, specifically catching `UnicodeDecodeError` for each line. This allows the script to skip only the problematic line and continue processing subsequent lines, which matches the requirement exactly.

Exam trap

Python Institute often tests the distinction between catching exceptions at the loop level versus the file level, and the trap here is that candidates choose a broad catch-all or an outer try-except that stops the loop, missing the requirement to skip only the problematic line and continue.

How to eliminate wrong answers

Option A is wrong because a bare `except:` clause catches all exceptions, including `KeyboardInterrupt` and `SystemExit`, which is poor practice and may hide critical errors; it also wraps the entire file reading, so any error would abort the loop entirely. Option B is wrong because it exits on failure, which contradicts the requirement to skip the line and continue; the `else` block runs only if no exception occurs, but the overall structure still stops on error. Option D is wrong because catching `Exception` in the outer loop and breaking on error would stop processing the entire file upon the first encoding error, rather than skipping just that line.

185
MCQeasy

A data entry application reads a CSV file where each line contains fields separated by commas. However, some fields are enclosed in double quotes and contain commas inside, e.g., 'John,"Doe, Jr.",30'. The developer currently uses line.split(',') to parse each line, which incorrectly splits the quoted field. The developer wants a solution using only the Python standard library (no third-party packages). Which of the following is the best approach?

A.Use the csv module's reader: import csv; next(csv.reader([line]))
B.Use line.strip().split(',') and then manually merge fields that start with a quote
C.Iterate through each character, track whether inside quotes, and split on commas outside quotes
D.Write a regular expression that matches commas outside quotes
AnswerA

Standard library solution that correctly handles quoted CSV fields.

Why this answer

The csv module (specifically csv.reader) is part of the standard library and is designed to handle quoted fields correctly. It is the recommended approach. Option A does not fix the issue.

Option B is possible but requires careful regex and is more error-prone. Option D is tedious and error-prone. Therefore, using csv.reader is the best practice.

186
MCQeasy

Refer to the exhibit. What is the output?

A.20
B.18
C.17
D.19
AnswerB

Correct: after strip, the string length is 18.

Why this answer

The code uses the `find()` method on the string 'Python programming' to locate the substring 'ogr'. The `find()` method returns the lowest index where the substring is found, starting from 0. 'ogr' begins at index 8 (P=0, y=1, t=2, h=3, o=4, n=5, space=6, p=7, r=8, o=9, g=10...), so the output is 8. However, the question shows the code `print(18)`? Wait, the exhibit is missing, but based on the answer being 18, the code likely uses `len()` or slicing.

Actually, re-evaluating: the correct answer is 18, which suggests the code prints the length of a string or the result of an expression like `len('Python programming')` which is 18 (including the space). Thus, the output is 18.

Exam trap

Python Institute often tests whether candidates remember to count spaces as characters in string length calculations, leading to off-by-one errors like picking 17 instead of 18.

How to eliminate wrong answers

Option A (20) is wrong because it likely results from counting characters incorrectly, e.g., including an extra space or misreading the string length. Option C (17) is wrong because it might come from forgetting to count the space character in 'Python programming', which has 18 characters total. Option D (19) is wrong because it could be from counting the string as 'Pythonprogramming' (no space) plus one extra, or a miscalculation of index positions.

187
MCQeasy

A class `Point` has an `__init__` that sets `self.x` and `self.y`. They want to compare points by equality (i.e., `p1 == p2` should work correctly). Which method should they implement?

A.`__same__`
B.`__eq__`
C.`__compare__`
D.`__cmp__`
AnswerB

`__eq__` is the correct method to override for the equality operator.

Why this answer

In Python, the `__eq__` method is the correct way to define equality comparison for objects. When you implement `__eq__(self, other)`, it is automatically called by the `==` operator, allowing `p1 == p2` to return a Boolean based on custom logic (e.g., comparing `self.x` and `self.y`). This is the standard Python protocol for equality testing.

Exam trap

Python Institute often tests the distinction between Python 2's `__cmp__` and Python 3's `__eq__`; the trap here is that candidates familiar with older Python may incorrectly choose `__cmp__`, not realizing it is obsolete in Python 3.

How to eliminate wrong answers

Option A is wrong because `__same__` is not a Python special method; Python uses `__eq__` for equality, not `__same__`. Option C is wrong because `__compare__` is not a Python dunder method; Python uses `__eq__` for equality and `__lt__`, `__gt__`, etc. for ordering. Option D is wrong because `__cmp__` was used in Python 2 for comparison (returning -1, 0, 1) but was removed in Python 3; the PCAP exam focuses on Python 3, where `__eq__` is the correct method for equality.

188
MCQhard

Which of the following correctly uses an abstract base class to enforce that all subclasses implement a 'make_sound' method? (Assume ABC imported)

A.from abc import ABC, abstractmethod\nclass Animal(ABC):\n @abstractmethod\n def make_sound(self):\n pass
B.from abc import abstractmethod\nclass Animal:\n @abstractmethod\n def make_sound(self):\n pass
C.class Animal:\n def make_sound(self):\n return None
D.class Animal:\n def make_sound(self):\n raise NotImplementedError
AnswerA

Proper ABC with abstractmethod.

Why this answer

Option A is correct because it imports both `ABC` and `abstractmethod` from the `abc` module, defines `Animal` as a subclass of `ABC`, and decorates `make_sound` with `@abstractmethod`. This combination prevents instantiation of `Animal` and forces any concrete subclass to override `make_sound`, or else a `TypeError` is raised at instantiation time.

Exam trap

Python Institute often tests whether candidates know that `@abstractmethod` alone does not make a class abstract — the class must explicitly inherit from `ABC` (or have its metaclass set to `ABCMeta`), otherwise the decorator is ignored and instantiation is allowed.

How to eliminate wrong answers

Option B is wrong because it does not make `Animal` a subclass of `ABC`; without inheriting from `ABC`, the `@abstractmethod` decorator has no effect and the class can be instantiated directly, so no enforcement occurs. Option C is wrong because it defines a concrete method that simply returns `None`; subclasses are free to ignore it, and there is no abstract mechanism to require overriding. Option D is wrong because raising `NotImplementedError` is a runtime convention, not a compile-time or instantiation-time enforcement; a subclass that forgets to override `make_sound` will only fail when the method is called, not when the object is created, and the base class is not abstract.

189
MCQmedium

Which method returns the lowest index where a specified substring is found, or -1 if not found?

A.find()
B.locate()
C.search()
D.index()
AnswerA

find returns the lowest index or -1 if not found.

Why this answer

Option A (find) returns -1 if not found. Option B (index) raises ValueError. Option C (search) is from re module.

Option D (locate) is not a Python method.

190
Multi-Selecthard

Which THREE methods must be implemented to create an immutable object that supports iteration and membership testing?

Select 3 answers
A.__init__
B.__getitem__
C.__len__
D.__contains__
E.__iter__
AnswersB, C, E

Supports indexing and slicing, and can be used for iteration.

Why this answer

Option B is correct because implementing __getitem__ allows indexing and slicing, which is essential for iteration in Python when __iter__ is not defined; Python falls back to __getitem__ for iteration. This method also supports membership testing via the 'in' operator when __contains__ is absent, as Python will iterate through the object to check membership.

Exam trap

Python Institute often tests the fallback behavior of Python's iteration and membership protocols, leading candidates to incorrectly assume __contains__ is mandatory for membership testing when it is actually optional if __iter__ or __getitem__ is implemented.

191
MCQhard

A programmer is writing a script to generate SQL queries safely. They need to escape single quotes in user-provided strings to prevent injection. Which approach is most robust?

A.s.replace("\\'", "'")
B.s.replace("'", "\\'")
C.s.strip("'")
D.s.replace("'", "''")
AnswerD

In SQL, single quotes are escaped by doubling them.

Why this answer

Option D is correct because in SQL, single quotes are escaped by doubling them (''), not by using backslashes. This is the standard escape mechanism defined by the SQL standard (ISO/IEC 9075) and is supported by databases like PostgreSQL, SQLite, and Oracle. Using `s.replace("'", "''")` ensures that a single quote in user input becomes two single quotes in the SQL string, preventing injection while preserving the literal quote.

Exam trap

Python Institute often tests the misconception that backslash escaping is universal in SQL, leading candidates to choose Option B, but the PCAP exam expects knowledge of the standard SQL escape mechanism (doubling quotes) as the most robust method.

How to eliminate wrong answers

Option A is wrong because it replaces the backslash-quote sequence with a single quote, which does not escape anything and actually removes the escape character. Option B is wrong because it uses a backslash to escape the quote, which is not the standard SQL escape method and may not work in all databases (e.g., MySQL with NO_BACKSLASH_ESCAPES mode disables it). Option C is wrong because `strip("'")` only removes leading and trailing single quotes, leaving internal quotes unescaped and vulnerable to injection.

192
Multi-Selecteasy

Which TWO of the following are special methods in Python?

Select 2 answers
A.`__bar__`
B.`__main__`
C.`__init__`
D.`__str__`
E.`__foo__`
AnswersC, D

This is the instance initializer method.

Why this answer

Option C is correct because `__init__` is a predefined special method in Python used as a constructor to initialize an object's state when an instance of a class is created. It is automatically invoked by the Python runtime upon object instantiation, making it a core part of the object-oriented programming model in Python.

Exam trap

Python Institute often tests the distinction between actual special methods (like `__init__` and `__str__`) and arbitrary dunder-named attributes that are not part of Python's language specification, leading candidates to mistakenly think any name with double underscores is a special method.

193
MCQmedium

Refer to the exhibit. A developer runs 'pip install pandas==2.0.0' but gets an error stating that the required version is not available. Which command should be used to list all available versions of pandas?

A.pip index versions pandas
B.pip search pandas
C.pip show pandas
D.pip list --all pandas
AnswerA

Correct. This command queries PyPI and shows all available versions.

Why this answer

Option A is correct because `pip index versions pandas` is the command that queries the Python Package Index (PyPI) for all available versions of the specified package. This command was introduced in pip 21.1 and is the proper way to list version history without attempting to install.

Exam trap

Python Institute often tests the distinction between commands that query the remote index (`pip index`) versus commands that inspect the local environment (`pip show`, `pip list`), and candidates frequently confuse `pip search` (which searches package names) with listing versions.

How to eliminate wrong answers

Option B is wrong because `pip search pandas` is a deprecated command that searches for packages by name or description in PyPI, not for listing available versions of a specific package; it was removed in pip 23.0 due to XMLRPC API issues. Option C is wrong because `pip show pandas` displays metadata for an already installed package (version, location, dependencies), not available versions from the remote index. Option D is wrong because `pip list --all pandas` is not a valid pip syntax; `pip list` lists installed packages, and `--all` shows outdated packages, but it cannot filter by a specific package name in that way.

194
MCQmedium

What is the length of string s?

A.16
B.17
C.19
D.18
AnswerD

The string has 18 characters.

Why this answer

The string s is defined as s = "Hello\nWorld!" in Python. The escape sequence \n represents a single newline character, not two separate characters. Counting the characters: H(1), e(2), l(3), l(4), o(5), \n(6), W(7), o(8), r(9), l(10), d(11), !(12) — that's 12 characters.

However, the correct answer is 18, which indicates the string actually contains additional characters or the question involves a different string. Given the options, the string must be something like s = "Hello\nWorld!" with extra spaces or characters, or the count includes the backslash and n as separate characters (which is incorrect in Python). The correct length is 18, meaning the string likely has 18 characters including the escape sequence interpreted as two characters (backslash and 'n') or additional characters not shown.

In Python, len("Hello\nWorld!") returns 12, so the question's string must be different, e.g., s = "Hello\\nWorld!" where \\ is a literal backslash, making the length 13, or the string includes other characters. Since the answer is 18, the string probably contains 18 characters, such as "Hello\nWorld!" with extra spaces or a different escape. The core reasoning: the length of a string is the number of characters, and escape sequences like \n count as one character in Python, but the question's string must have 18 characters total.

Exam trap

The trap here is that candidates often miscount escape sequences like \n as two characters instead of one, leading them to choose an incorrect length like 19 (if they count \n as two) or 16/17 if they miss other characters, while the correct answer (18) requires careful counting of all characters including spaces and escape sequences.

How to eliminate wrong answers

Option A (16) is wrong because it underestimates the length by 2 characters, possibly miscounting the escape sequence as one character when the actual string has more characters. Option B (17) is wrong because it is one short of the correct length, likely due to forgetting to count a character like a space or misinterpreting an escape sequence. Option C (19) is wrong because it overcounts by 1, perhaps counting an escape sequence as two characters or adding an extra character that isn't present.

195
MCQmedium

Given s = 'Python', what is s[1:4]?

A.'pyt'
B.'yth'
C.'ytho'
D.'Pyt'
AnswerB

Correct: indices 1 to 3 inclusive of start, exclusive of end.

Why this answer

In Python, string slicing with `s[start:stop]` extracts characters from index `start` up to but not including index `stop`. Since indexing starts at 0, `s[1:4]` on 'Python' takes indices 1 ('y'), 2 ('t'), and 3 ('h'), resulting in 'yth'. Option B is correct because it exactly matches this slice.

Exam trap

Python Institute often tests the half-open interval behavior of slicing, where candidates mistakenly include the character at the stop index (e.g., choosing 'ytho' by including index 4) or confuse zero-based indexing with one-based indexing (e.g., choosing 'pyt' or 'Pyt' by starting at index 0).

How to eliminate wrong answers

Option A is wrong because 'pyt' would result from `s[0:3]` (lowercase 'p' at index 0, 'y' at 1, 't' at 2), not from `s[1:4]`. Option C is wrong because 'ytho' would require `s[1:5]` (including index 4 which is 'o'), exceeding the stop index of 4. Option D is wrong because 'Pyt' would result from `s[0:3]` (uppercase 'P' at index 0, 'y' at 1, 't' at 2), not from `s[1:4]` which starts at index 1.

196
MCQmedium

A developer is writing a script that processes user-uploaded CSV files. The script should attempt to read the file, and if a UnicodeDecodeError occurs, log a warning and skip the file. Which code snippet correctly achieves this without stopping the entire process?

A.try: read_file() except (UnicodeDecodeError, OSError): pass
B.try: read_file() except UnicodeDecodeError: log.warning('Skipping file')
C.try: read_file() except Exception: log.warning('Skipping file')
D.try: read_file() except UnicodeEncodeError: log.warning('Skipping file')
AnswerB

Correctly catches only UnicodeDecodeError and continues with next file.

Why this answer

Option B is correct because it catches only UnicodeDecodeError, which is the specific exception raised when a file contains invalid UTF-8 or other encoding issues. It logs a warning and then continues execution (the 'pass' is implied by the log statement, but the key is that the exception is handled without re-raising). This matches the requirement to skip the file without stopping the entire process.

Exam trap

Python Institute often tests the distinction between UnicodeDecodeError (input decoding) and UnicodeEncodeError (output encoding), and the trap here is that candidates confuse the two or use an overly broad except clause that hides bugs.

How to eliminate wrong answers

Option A is wrong because it catches both UnicodeDecodeError and OSError, but uses 'pass' instead of logging a warning, which fails the requirement to log a warning. Option C is wrong because it catches the broad Exception class, which would suppress all exceptions (including critical ones like KeyboardInterrupt or SystemExit) and violates best practices by being too broad. Option D is wrong because it catches UnicodeEncodeError, which is raised when encoding output (e.g., writing to a file), not when reading/decoding input; the correct exception for reading is UnicodeDecodeError.

197
Multi-Selecteasy

Which TWO of the following statements about Python class inheritance are correct? (Select exactly two.)

Select 2 answers
A.If a subclass does not define __init__, it automatically inherits the parent's __init__.
B.A subclass can override a parent class method.
C.A subclass cannot define methods with the same name as a parent class method.
D.A subclass inherits all private attributes and methods from the parent class.
E.A class can inherit from multiple base classes.
AnswersB, E

Method overriding is a key OOP feature.

Why this answer

Option B is correct because Python allows a subclass to define a method with the same name as a method in its parent class, which overrides the parent's implementation. When the method is called on an instance of the subclass, Python's method resolution order (MRO) will find the subclass's version first, effectively hiding the parent's method.

Exam trap

Python Institute often tests the misconception that private attributes (name-mangled with double underscore) are completely inaccessible from subclasses, but in reality they are only renamed and can still be accessed using the mangled name, so they are not truly private.

198
MCQmedium

A developer writes a log message with variables: name = 'Alice' and age = 30. Which of the following uses an f-string correctly?

A.f(Name: {name}, Age: {age})
B.f'Name: {name}, Age: {age}'
C.'Name: %s, Age: %d' % (name, age)
D.f.'Name: {name}, Age: {age}'
AnswerB

Valid f-string syntax with curly braces for variable interpolation.

Why this answer

Option A is correct because f-strings use the 'f' prefix and curly braces for variables. Option B is wrong because it uses a period after the 'f' instead of directly. Option C is wrong because it uses parentheses incorrectly.

Option D is wrong because it uses `%s` formatting without proper operator.

199
MCQmedium

Refer to the exhibit. What is the output when the code is executed?

A.Default x
B.HELLO
C.hello
D.AttributeError
AnswerB

Correct: __setattr__ converts to uppercase.

Why this answer

Option B is correct because the code defines a class `X` with a class attribute `x = 'Default x'` and a `__str__` method that returns `'HELLO'`. When `print(obj)` is called, Python invokes the `__str__` method of the object, which returns `'HELLO'`, so the output is `HELLO`. The class attribute `x` is never accessed in the `__str__` method, so it is ignored.

Exam trap

Python Institute often tests the distinction between class attributes and the `__str__` method, trapping candidates who assume that a class attribute named `x` will be printed automatically, rather than recognizing that `__str__` defines the output explicitly.

How to eliminate wrong answers

Option A is wrong because the `__str__` method overrides the default string representation; the class attribute `x` is not printed unless explicitly referenced. Option C is wrong because the `__str__` method returns the uppercase string `'HELLO'`, not the lowercase `'hello'`. Option D is wrong because no `AttributeError` occurs; the `__str__` method is defined correctly and returns a string, so the print statement executes without error.

200
MCQmedium

Refer to the exhibit. A script executes 'from mypackage import *'. Which functions are available in the global namespace?

A.Only func from module_a
B.It raises an ImportError because __all__ should contain function names
C.None, because __all__ lists modules, not functions
D.func from both module_a and module_b
AnswerC

Correct. __all__ defines what names are imported; here it imports the modules, so functions remain in the module namespace.

Why this answer

Option C is correct because when `from mypackage import *` is executed, Python looks for the `__all__` list in the package's `__init__.py` file. In this exhibit, `__all__` is defined as `['module_a', 'module_b']`, which are module names, not function names. The `import *` statement imports the modules listed in `__all__` into the global namespace, not their individual functions.

Therefore, `func` from either module is not directly available; you would need to reference them as `module_a.func` or `module_b.func`.

Exam trap

The trap here is that candidates often assume `__all__` must contain function or variable names, but it can also list submodule names, and `import *` only imports those listed names—not their nested contents—into the global namespace.

How to eliminate wrong answers

Option A is wrong because `func` from `module_a` is not directly imported into the global namespace; only the module `module_a` itself is imported. Option B is wrong because `__all__` can contain module names or attribute names; it does not raise an `ImportError` when it contains module names—it simply imports those modules. Option D is wrong because `func` from both modules is not directly available; only the modules `module_a` and `module_b` are imported into the global namespace.

201
MCQhard

A Python program uses multiple inheritance. Class A defines method 'foo', class B also defines 'foo', and class C(A, B) inherits from both. The developer expects that calling 'foo' on an instance of C should invoke the method from class A. However, it invokes the method from class B. What is the most likely cause?

A.The method resolution order (MRO) is not as expected due to the order of base classes
B.Python always calls the method from the last base class
C.The 'foo' method in class B is defined after class A's 'foo' in the same file
D.Python uses depth-first, left-to-right resolution
AnswerA

MRO uses C3 linearization; if B's method is called, the MRO likely lists B before A, possibly due to a different inheritance structure.

Why this answer

Option A is correct because Python's Method Resolution Order (MRO) uses the C3 linearization algorithm, which respects the order of base classes as listed in the class definition. When class C(A, B) is defined, the MRO is C → A → B, so 'foo' from A should be found first. However, if the developer mistakenly wrote C(B, A), the MRO becomes C → B → A, causing B's 'foo' to be invoked.

The question states the developer expected A's method but got B's, indicating the base class order was reversed.

Exam trap

Python Institute often tests the misconception that Python uses simple depth-first, left-to-right resolution (like some older languages), when in fact it uses the C3 linearization algorithm, and the order of base classes in the class definition is the primary factor determining which method is called.

How to eliminate wrong answers

Option B is wrong because Python does not always call the method from the last base class; it follows the MRO computed by C3 linearization, which depends on the order of base classes and the inheritance hierarchy. Option C is wrong because the order in which methods are defined in the source file has no effect on MRO; Python resolves methods based on the class hierarchy and the C3 algorithm, not lexical order. Option D is wrong because Python does not use simple depth-first, left-to-right resolution; it uses the C3 linearization algorithm, which ensures monotonicity and handles diamond inheritance correctly, avoiding the issues of naive DFS.

202
MCQeasy

What is the output of the above code?

A.Alice is 30, years old.
B.Name is 30 years old.
C.Alice is 30 years old..
D.Alice is 30 years old.
AnswerD

Correct interpolation.

Why this answer

The code uses an f-string with a placeholder `{name}` and `{age}`. When `name = 'Alice'` and `age = 30`, the f-string evaluates to `'Alice is 30 years old.'` because the period is part of the string literal outside the placeholder. Option D matches this exact output.

Exam trap

Python Institute often tests whether candidates notice subtle punctuation differences (like missing commas or extra periods) in f-string output, tricking those who focus only on the variable values and ignore exact string formatting.

How to eliminate wrong answers

Option A is wrong because it adds a comma after '30' and an extra space before 'years', which is not present in the f-string. Option B is wrong because it replaces the actual name with the literal string 'Name', showing a misunderstanding that f-string placeholders are evaluated, not left as variable names. Option C is wrong because it has two periods at the end (a double dot), while the f-string produces only one period.

203
MCQmedium

A function receives a string and needs to return a new string with all vowels removed. Which code snippet accomplishes this efficiently?

A.for v in 'aeiou': s = s.replace(v, '')
B.return ''.join([c for c in s if c.lower() not in 'aeiou'])
C.return s.translate(str.maketrans('', '', 'aeiou'))
D.return re.sub('[aeiou]', '', s, flags=re.I)
AnswerC

translate with a deletion table removes all vowels efficiently.

Why this answer

Option C is correct because `str.translate` with `str.maketrans('', '', 'aeiou')` removes all occurrences of the characters 'a', 'e', 'i', 'o', 'u' in a single pass using an internal translation table, which is highly efficient (O(n) time and minimal overhead). It avoids creating intermediate strings or performing repeated replacements, making it the fastest approach for this task in CPython.

Exam trap

Python Institute often tests the distinction between `str.replace` (which creates a new string per call) and `str.translate` (which performs bulk removal in one pass), leading candidates to choose the more familiar but less efficient `replace` loop or the regex approach, which is overkill for simple character removal.

How to eliminate wrong answers

Option A is wrong because it mutates the string `s` inside the loop using `s.replace(v, '')`, which creates a new string for each vowel (5 replacements) and has O(n*m) complexity where m is the number of vowels, leading to unnecessary memory allocation and slower performance. Option B is wrong because it only removes lowercase vowels (due to `c.lower() not in 'aeiou'`), but the problem statement does not specify case-insensitivity; additionally, it builds a list comprehension and joins it, which is correct functionally but less efficient than `translate` due to the overhead of list creation and per-character lowercasing. Option D is wrong because `re.sub('[aeiou]', '', s, flags=re.I)` uses a regular expression engine that compiles a pattern and performs backtracking, which is overkill and slower than `translate` for simple character removal, and the `re.I` flag makes it case-insensitive, which may be unintended if only lowercase vowels should be removed.

204
MCQmedium

Given: class A: def method(self): print('A'); class B(A): def method(self): super().method(); print('B'); class C(A): def method(self): super().method(); print('C'); class D(B, C): pass. What is printed by D().method()?

A.A B C
B.A C B
C.C A B
D.B A C
AnswerB

Correct call order via MRO.

Why this answer

Option B is correct because Python's MRO (Method Resolution Order) for class D, which inherits from B and C (both inheriting from A), follows the C3 linearization algorithm. The MRO for D is D -> B -> C -> A, so calling D().method() triggers B.method(), which calls super().method() (resolving to C.method()), which calls super().method() (resolving to A.method()), printing 'A', then back to C prints 'C', then back to B prints 'B', resulting in 'A C B'.

Exam trap

Python Institute often tests the misconception that super() always calls the immediate parent class (A) in a linear chain, rather than following the full MRO, leading candidates to pick 'A B C' instead of the correct 'A C B'.

How to eliminate wrong answers

Option A is wrong because it assumes a simple left-to-right depth-first order without considering that super() in B resolves to C (the next class in MRO), not directly to A, so the output is not 'A B C'. Option C is wrong because it incorrectly suggests C.method() is called first, but the MRO starts with D, then B, not C. Option D is wrong because it implies B.method() prints 'B' before its super() chain completes, but the actual order is A (from A.method), then C (from C.method), then B (from B.method).

205
Multi-Selectmedium

Which TWO of the following string methods return a boolean value (True or False)?

Select 2 answers
A.str.upper()
B.str.split()
C.str.startswith()
D.str.isdigit()
E.str.find()
AnswersC, D

Returns True if string starts with given prefix.

Why this answer

Option C is correct because `str.startswith()` returns a boolean value (`True` or `False`) indicating whether the string starts with a specified prefix. This method is designed specifically for conditional checks, not for transforming or searching the string.

Exam trap

Python Institute often tests the distinction between methods that return a boolean versus those that return a new string or an integer, trapping candidates who confuse `str.find()` (returns index) with `str.startswith()` (returns boolean).

206
Multi-Selecteasy

Which TWO string methods raise an exception when the searched substring is not found?

Select 2 answers
A.rfind()
B.find()
C.rindex()
D.count()
E.index()
AnswersC, E

rindex() raises ValueError if substring is not found.

Why this answer

Option C (rindex()) is correct because the rindex() method, like index(), raises a ValueError exception when the searched substring is not found. This is in contrast to rfind() and find(), which return -1 instead of raising an exception.

Exam trap

Python Institute often tests the distinction between methods that return -1 (find, rfind) versus those that raise an exception (index, rindex), and the trap is that candidates confuse rfind() with rindex() because both perform a right-to-left search.

207
Multi-Selecthard

Which TWO statements about Python strings are correct? (Choose exactly 2 correct answers.)

Select 2 answers
A.Strings are mutable; you can change individual characters via indexing.
B.Strings have an .append() method to add characters at the end.
C.Strings are immutable; operations like concatenation produce a new string.
D.The + operator on strings creates a new string object containing the concatenated result.
E.You can assign a new character to a position in a string using indexing: s[0] = 'a'.
AnswersC, D

Immutable means the string object cannot be modified; concatenation returns a new string.

Why this answer

Option B (strings are immutable) and Option D (concatenation creates a new string) are correct. Option A is wrong because strings are immutable, not mutable. Option C is wrong because .append() is not a method of strings; it belongs to lists.

Option E is wrong because item assignment is not allowed on strings (immutable).

208
Multi-Selectmedium

Which TWO of the following statements about Python packages are true?

Select 2 answers
A.A package can contain subpackages.
B.An __init__.py file can be empty.
C.Packages cannot be imported using the import statement with dot notation.
D.An __init__.py file is required in every directory to make it a package.
E.A package is a single .py file.
AnswersA, B

Packages can be nested.

Why this answer

Option A is correct because Python packages are directories that can contain subpackages (nested directories with their own __init__.py files), forming a hierarchical namespace. This allows for organized module grouping, such as `package.subpackage.module`, which is a core feature of Python's module system.

Exam trap

Python Institute often tests the misconception that an __init__.py file is always required for a directory to be a package, but since Python 3.3, namespace packages without __init__.py are valid, making option D a classic trap.

209
MCQeasy

A developer wants to check if a string 'racecar' is a palindrome by comparing it to its reverse. Which code completes the task correctly?

A.reversed(s) == s
B.s[::1] == s
C.s[::-1] == s
D.s.reverse() == s
AnswerC

Slice with negative step reverses the string; comparison works.

Why this answer

Option B uses slicing with default step -1 to reverse the string and compares. Option A uses reversed() which returns an iterator, so comparison to a string fails. Option C uses .reverse() which is a list method.

Option D uses slicing but with step 1, which does not reverse.

210
MCQeasy

A developer needs to check if a string contains only alphanumeric characters. Which string method should be used?

A.s.isnumeric()
B.s.isalnum()
C.s.isdigit()
D.s.isalpha()
AnswerB

Returns True if all characters are alphanumeric (letters or digits).

Why this answer

Option B is correct because the `isalnum()` method returns `True` if all characters in the string are alphanumeric (letters or digits) and the string is non-empty. This directly matches the requirement to check for only alphanumeric characters, covering both letters and digits without any other characters.

Exam trap

The trap here is that candidates often confuse `isalnum()` with `isalpha()` or `isdigit()`, mistakenly thinking that checking for letters only or digits only is sufficient, when the question explicitly requires both letters and digits (alphanumeric).

How to eliminate wrong answers

Option A is wrong because `isnumeric()` returns `True` only for numeric characters (including Unicode numeric values like fractions, Roman numerals, etc.), not for letters, so it fails to check for alphanumeric content. Option C is wrong because `isdigit()` returns `True` only for decimal digit characters (0-9 and certain Unicode digits), excluding letters entirely. Option D is wrong because `isalpha()` returns `True` only for alphabetic characters (letters), excluding digits, so it would reject strings containing numbers.

211
MCQhard

Which of the following correctly raises a new exception while preserving the original traceback?

A.raise original_exception
B.raise ValueError('new')
C.raise ValueError('new') from original_exception
D.raise
AnswerC

Correct chaining syntax.

Why this answer

Option C is correct because the `raise ... from original_exception` syntax in Python allows you to raise a new exception while chaining it to the original exception, preserving the original traceback. This is essential for debugging, as it shows both the new error and the root cause.

Exam trap

Python Institute often tests the distinction between re-raising the same exception (bare `raise` or `raise original_exception`) and raising a new exception with chaining (`raise ... from original_exception`), trapping candidates who think any `raise` preserves the traceback.

How to eliminate wrong answers

Option A is wrong because `raise original_exception` re-raises the exact same exception object, not a new one, so it does not create a new exception. Option B is wrong because `raise ValueError('new')` raises a brand-new exception without any reference to the original, losing the original traceback entirely. Option D is wrong because a bare `raise` can only be used inside an except block to re-raise the current exception; outside an except block it raises a RuntimeError, and it does not create a new exception.

212
MCQhard

Refer to the exhibit. The script stops with this error. Which exception type should be caught to handle this error gracefully?

A.ValueError
B.OSError
C.FileNotFoundError
D.IOError
AnswerB

FileNotFoundError inherits from OSError, so catching OSError handles it.

Why this answer

The error is FileNotFoundError, which is a subclass of OSError. Catching OSError or FileNotFoundError would handle it.

213
MCQhard

A developer is tasked with validating user input that must be a 10-digit phone number. The input may contain spaces, dashes, and parentheses. Which approach best ensures the input contains exactly 10 digits?

A.if len([c for c in s if c.isdigit()]) == 10:
B.if len(s) >= 10 and s.isdigit():
C.if s[:10].isdigit():
D.if s.isdigit() and len(s) == 10:
AnswerA

This extracts all digits and checks if there are exactly 10, ignoring non-digits.

Why this answer

Option A uses a list comprehension to filter only digit characters from the input string `s` and then checks if the count of those digits is exactly 10. This correctly handles any non-digit characters (spaces, dashes, parentheses) by ignoring them, ensuring the validation focuses solely on the presence of exactly ten digits.

Exam trap

Python Institute often tests the distinction between checking if a string *contains* a certain number of digits versus checking if the string *itself* is entirely composed of digits, leading candidates to mistakenly choose options that require the entire string to be numeric.

How to eliminate wrong answers

Option B is wrong because `s.isdigit()` returns `True` only if *all* characters in the string are digits, so it would reject valid inputs containing spaces, dashes, or parentheses. Option C is wrong because `s[:10].isdigit()` only checks the first ten characters, ignoring any non-digit characters that might appear later, and also fails to verify that the entire string contains exactly ten digits (e.g., a 15-digit string with first ten digits would incorrectly pass). Option D is wrong because `s.isdigit()` again requires the entire string to consist solely of digits, which would reject any input with formatting characters, even if it contains exactly ten digits.

214
MCQhard

What is the output of the code?

A.['support@example', 'sales@example']
B.[]
C.['support@example.com', 'sales@example.org']
D.['support@example.com']
AnswerC

Both email addresses match the pattern.

Why this answer

The code uses `re.findall()` with the pattern `r'\b\w+@\w+\.\w{2,4}\b'`. This pattern matches word boundaries, one or more word characters, an '@', one or more word characters, a dot, and 2-4 word characters (the TLD). The string contains 'support@example.com' and 'sales@example.org', both of which satisfy the pattern, so they are returned as a list.

Option C is correct because the regex correctly extracts both email addresses.

Exam trap

Python Institute often tests the misconception that `re.findall()` returns only the first match or that the regex fails due to the dot not being escaped, but here the dot is correctly escaped with `\.` and the pattern matches all occurrences, so candidates who think the dot is a wildcard or that the pattern is invalid may incorrectly choose B or D.

How to eliminate wrong answers

Option A is wrong because it omits the TLDs '.com' and '.org', suggesting the regex stopped at the dot, but the pattern explicitly requires a dot followed by 2-4 word characters. Option B is wrong because it assumes no matches occur, but the pattern does match both valid email addresses in the string. Option D is wrong because it includes only 'support@example.com', missing 'sales@example.org', which also matches the pattern; the regex is not case-sensitive or selective in a way that would exclude the second address.

215
MCQhard

Refer to the exhibit. What is the likely outcome of running this code?

A.The program raises a SyntaxError due to invalid escape sequences.
B.The program runs but the file contents are incorrect.
C.The program raises a FileNotFoundError because the path is invalid after escape interpretation.
D.The file is opened successfully because backslashes are ignored.
AnswerA

Correct: \U is an invalid escape sequence in Python.

Why this answer

Option A is correct because the code contains backslash sequences like `\n` and `\t` that are not valid escape sequences in Python. Python 3.12+ raises a `SyntaxError: invalid escape sequence` by default, and in earlier versions it emits a `DeprecationWarning` that will become an error in future versions. The raw string prefix `r` or escaping the backslash (`\\`) is required to avoid this.

Exam trap

Python Institute often tests the misconception that backslashes in strings are always treated literally or that invalid escape sequences are silently ignored, leading candidates to choose options about file operations instead of recognizing the compile-time SyntaxError.

How to eliminate wrong answers

Option B is wrong because the program does not run at all; a SyntaxError prevents execution, so no file is written or read. Option C is wrong because the error is a SyntaxError at compile time, not a runtime FileNotFoundError; the path string is never evaluated as a file path. Option D is wrong because backslashes are not ignored; they are interpreted as escape sequences, and invalid ones cause a SyntaxError.

216
Multi-Selecteasy

Which TWO of the following are valid ways to import specific names from a module?

Select 2 answers
A.from module import * (only names listed in __all__)
B.from module import name1, name2
C.from module import name as alias
D.import name1, name2 from module
E.import module.name1
AnswersB, C

Correct. This imports specific names from the module.

Why this answer

Option B is correct because the `from module import name1, name2` syntax allows importing specific names from a module directly into the current namespace. Option C is also correct because `from module import name as alias` provides the same functionality while allowing you to rename the imported name to avoid naming conflicts.

Exam trap

Python Institute often tests the distinction between `import module.name` (which is invalid for importing a specific name) and `from module import name` (which is correct), leading candidates to mistakenly think dot notation can import individual attributes.

217
MCQhard

A developer is creating a custom exception hierarchy for a library. The base exception is `LibraryError`. Which definition ensures that subclasses can be caught using the parent exception, but also allows distinguishing between different error types?

A.class LibraryError: pass class FileError(LibraryError): pass class ParseError(LibraryError): pass
B.class LibraryError(BaseException): pass class FileError(LibraryError): pass class ParseError(LibraryError): pass
C.class LibraryError(Exception): pass class FileError(LibraryError): pass class ParseError(LibraryError): pass
D.class LibraryError(Exception): pass class FileError(Exception): pass class ParseError(Exception): pass
AnswerC

Standard practice: library base inherits from Exception, specific errors inherit from base.

Why this answer

Option C is correct because it defines `LibraryError` as a subclass of `Exception`, which is the proper base class for all user-defined exceptions in Python. Subclasses `FileError` and `ParseError` inherit from `LibraryError`, so they can be caught with `except LibraryError` while still being distinguishable by their own type. This follows the standard Python exception hierarchy, where custom exceptions should derive from `Exception`, not `BaseException` or no base class.

Exam trap

Python Institute often tests the distinction between `Exception` and `BaseException`, and the trap here is that candidates mistakenly think any class named 'Error' is automatically an exception, or they choose Option B thinking `BaseException` is the correct base for all custom exceptions.

How to eliminate wrong answers

Option A is wrong because `LibraryError` does not inherit from `Exception`; it is a plain class, so it cannot be caught by a standard `except Exception` clause and does not integrate with Python's exception handling mechanism. Option B is wrong because `LibraryError` inherits from `BaseException`, which is reserved for system-exiting exceptions like `SystemExit` and `KeyboardInterrupt`; catching `BaseException` is discouraged as it can suppress critical signals. Option D is wrong because `FileError` and `ParseError` both inherit directly from `Exception` rather than from `LibraryError`, so they cannot be caught collectively as `LibraryError` and break the intended hierarchy.

218
MCQmedium

You are a data analyst working with a dataset of customer reviews. Each review is stored as a string in a list. You need to count how many reviews contain the word 'excellent' (case-insensitive). However, the word might appear as 'Excellent', 'EXCELLENT', or even with punctuation like 'excellent!'. The current code uses 'excellent' in review.lower(), but this fails if 'excellent' is part of another word like 'unexcellent'. You need to ensure that only the whole word 'excellent' is counted. Which code modification will correctly count whole word occurrences?

A.Use re.search(r'\bexcellent\b', review, re.IGNORECASE)
B.Use 'excellent' in review.lower().split()
C.Use review.lower().count('excellent') > 0
D.Use review.lower().find('excellent') != -1
AnswerA

Word boundary regex ensures whole word match regardless of case.

Why this answer

Option A is correct because `re.search(r'\bexcellent\b', review, re.IGNORECASE)` uses the `\b` word boundary anchor to ensure that 'excellent' is matched as a whole word, not as part of another word like 'unexcellent'. The `re.IGNORECASE` flag handles case-insensitive matching, covering 'Excellent', 'EXCELLENT', etc. This approach also correctly handles punctuation attached to the word, such as 'excellent!', because the word boundary matches between a word character and a non-word character.

Exam trap

Python Institute often tests the distinction between substring matching and whole-word matching, and the trap here is that candidates assume `in` with `split()` or `count()` handles whole words, but they fail to account for punctuation or compound words, leading to incorrect counts.

How to eliminate wrong answers

Option B is wrong because `'excellent' in review.lower().split()` splits the string on whitespace only, so it would fail if 'excellent' is followed by punctuation like 'excellent!' (the split would keep the exclamation mark attached, making the word 'excellent!' not equal to 'excellent'). Option C is wrong because `review.lower().count('excellent') > 0` counts substring occurrences, so it would match 'excellent' inside 'unexcellent' and count it incorrectly. Option D is wrong because `review.lower().find('excellent') != -1` also performs a substring search, matching 'excellent' as part of a larger word like 'unexcellent'.

219
MCQmedium

A developer is troubleshooting a Python application that fails to import a custom module named 'utils'. The file 'utils.py' exists in the same directory as the main script. Which of the following is the most likely cause of the import failure?

A.There is a circular import between utils.py and the main script.
B.The directory containing utils.py is not in sys.path.
C.The directory lacks an __init__.py file.
D.The utils.py file contains a syntax error.
AnswerB

Python searches for modules in directories listed in sys.path. If the script's directory is not included, the import will fail unless the script is run from that directory.

Why this answer

When Python imports a module, it searches for it in the directories listed in sys.path. Even if 'utils.py' is in the same directory as the main script, that directory may not be automatically included in sys.path if the script is not run as a module (e.g., using python main.py from a different working directory). The most common cause of such a failure is that the script's directory is missing from sys.path, which prevents Python from locating the file.

Exam trap

Python Institute often tests the misconception that files in the same directory are always importable, but the trap is that Python's import search path depends on how the script is executed, not just file location.

How to eliminate wrong answers

Option A is wrong because a circular import would cause an ImportError only if the modules depend on each other at the top level, but the question states the file exists and the failure is on import, not a runtime error; circular imports typically raise an ImportError with a specific message, not a simple failure to find the module. Option C is wrong because __init__.py is required only for directories to be treated as packages (for implicit namespace packages in Python 3.3+ it is optional), and the question involves a single module file, not a package directory. Option D is wrong because a syntax error in utils.py would cause an ImportError only when the module is actually loaded and executed, not a failure to find the module; the error would be a SyntaxError, not a missing module error.

220
Multi-Selecthard

Which three of the following statements about Python strings are true? (Choose three.)

Select 3 answers
A.The join() method is called on the separator string.
B.The string '123.45' can be converted to integer using int('123.45').
C.Strings support indexing with integers.
D.Strings are mutable.
E.The len() function returns the number of characters including spaces.
AnswersA, C, E

For example: ','.join(list) joins list elements with comma.

Why this answer

B is true: strings support integer indexing. C is true: len() counts all characters. D is true: join() is called on the separator.

A is false: strings are immutable. E is false: int() cannot convert a string with a decimal point.

221
MCQeasy

What is the output of the code in the exhibit?

A.{name} is {age} years old.
B.Alice is 30 years old.
C.Alice is 30 years old.
D.30 is Alice years old.
AnswerB

The f-string correctly interpolates the variables.

Why this answer

Option A is correct because the f-string substitutes the variables name and age. Option B has incorrect formatting with curly braces. Option C places age before name.

Option D uses incorrect variable names.

222
MCQmedium

A developer is working on a project that requires the use of a third-party package hosted on a private repository. The developer wants to ensure that the package can be imported without specifying the full repository URL each time. Which approach should be taken?

A.Append the repository path to sys.path in the script.
B.Place the package files in the site-packages directory manually.
C.Configure the repository URL in pip's configuration file or in requirements.txt.
D.Use os.system to run a pip install command from within the script.
AnswerC

pip configuration allows specifying extra index URLs for package resolution.

Why this answer

Option C is correct because configuring the repository URL in pip's configuration file (e.g., `pip.conf`, `pip.ini`, or `~/.config/pip/pip.conf`) or in `requirements.txt` using the `--index-url` or `--extra-index-url` option allows pip to resolve the package from the private repository automatically. This approach ensures that the package can be installed and imported without manually specifying the full URL each time, as pip will use the configured index to locate and download the package.

Exam trap

Python Institute often tests the distinction between runtime import path manipulation (like `sys.path`) and package installation configuration, trapping candidates who confuse adding a directory to `sys.path` with configuring a remote package index for pip.

How to eliminate wrong answers

Option A is wrong because appending the repository path to `sys.path` only adds a directory to Python's module search path, which is used for importing already-installed modules; it does not install the package from a remote repository or resolve dependencies. Option B is wrong because manually placing package files in `site-packages` bypasses pip's dependency resolution, version management, and integrity checks, leading to potential conflicts or incomplete installations. Option D is wrong because using `os.system` to run a pip install command from within the script is a fragile, non-portable approach that mixes installation logic with runtime code, and it does not provide a persistent configuration for future imports.

223
MCQeasy

Which of the following is the correct way to open a file for writing in binary mode?

A.open('data.dat', 'wb')
B.open('data.dat', 'bw')
C.open('data.dat', 'br')
D.open('data.dat', 'w')
AnswerA

Correctly opens for binary writing.

Why this answer

Option A is correct because the mode string 'wb' specifies both write ('w') and binary ('b') mode, which is the proper way to open a file for writing binary data in Python. The order of characters in the mode string is fixed: the file mode character ('r', 'w', 'a', etc.) must come first, followed by the optional 'b' for binary mode.

Exam trap

Python Institute often tests the strict ordering of mode characters in the open() function, expecting candidates to know that 'b' must always follow the read/write/append character, not precede it.

How to eliminate wrong answers

Option B is wrong because 'bw' reverses the required order — the mode character ('w') must precede the binary modifier ('b'), and Python will raise a ValueError for an invalid mode string. Option C is wrong because 'br' opens the file for reading in binary mode, not writing. Option D is wrong because 'w' opens the file for writing in text mode, not binary mode, which can cause data corruption when writing non-text data (e.g., images or serialized objects) due to newline translation.

224
Drag & Dropmedium

Drag and drop the steps to read a CSV file using the csv module in Python into the correct order.

Drag steps to the numbered slots on the right, or tap a step then tap a slot.

Steps
Order

Why this order

Reading a CSV file requires importing csv, opening the file, creating a reader, iterating rows, and closing the file.

Page 2

Page 3 of 7

Page 4

All pages