Free Python Institute PCEP Practice Questions: Block 4: Functions and Exceptions
Practice 10 free Python Institute PCEP - Certified Entry-Level Python Programmer (PCEP-30-02) questions on Block 4: Functions and Exceptions, with answers, explanations, and the IT Mastery next step.
Try the IT Mastery web app for a richer interactive practice experience with mixed sets, timed mocks, topic drills, explanations, and progress tracking.
Topic snapshot
| Field | Detail |
|---|---|
| Practice target | Python Institute PCEP |
| Topic area | Block 4: Functions and Exceptions |
| Blueprint weight | 28% |
| Page purpose | Focused sample questions before returning to mixed practice |
How to use this topic drill
Use this page to isolate Block 4: Functions and Exceptions for Python Institute PCEP. Work through the 10 questions first, then review the explanations and return to mixed practice in IT Mastery.
| Pass | What to do | What to record |
|---|---|---|
| First attempt | Answer without checking the explanation first. | The fact, rule, calculation, or judgment point that controlled your answer. |
| Review | Read the explanation even when you were correct. | Why the best answer is stronger than the closest distractor. |
| Repair | Repeat only missed or uncertain items after a short break. | The pattern behind misses, not the answer letter. |
| Transfer | Return to mixed practice once the topic feels stable. | Whether the same skill holds up when the topic is no longer obvious. |
Blueprint context: 28% of the practice outline. A focused topic score can overstate readiness if you recognize the pattern too quickly, so use it as repair work before timed mixed sets.
Sample questions
These are original IT Mastery practice questions aligned to this topic area. They are not official Python Institute questions, copied live-exam content, or exam dumps. Use them to preview question style and explanation depth before continuing with topic drills, mixed sets, and timed mocks in IT Mastery.
Question 1
Topic: Block 4: Functions and Exceptions
Examine this code:
price = 50
def show_price(price):
print(price)
show_price(30)
print(price)
Which statement is correct?
Options:
A. The
priceparameter shadows the outer name; output is30then50.B. Only the outer
priceis used; output is50then50.C. Using
priceglobally and as a parameter causes an error.D. The
priceparameter updates the outer name; output is30then30.
Best answer: A
Explanation: Function parameters are local to the function. Here, the parameter price receives 30 and hides the outer price only inside show_price(), so the function prints 30 while the global variable stays 50.
Shadowing happens when a local name inside a function matches a name from an outer scope. In this example, show_price(price) creates a local parameter named price. When the function is called with 30, that local parameter gets the value 30, and it hides the global price only while the function runs. It does not replace or modify the global variable, because the parameter is a separate local name. After the function finishes, print(price) refers again to the global variable, which is still 50. The key idea is that the same spelling does not mean the same variable in every scope.
- The option claiming the outer name becomes
30confuses passing an argument with changing a global variable. - The option claiming both outputs are
50ignores that the function uses its local parameter first. - The option claiming an error is wrong because Python allows a parameter to have the same name as a global variable.
Question 2
Topic: Block 4: Functions and Exceptions
What is printed by this Python 3 code?
try:
print(int("7a"))
except Exception:
print("general")
except ValueError:
print("value")
Options:
A. The program stops with
ValueErrorB. general
C. value
D. general
thenvalue
Best answer: B
Explanation: Python checks except clauses from top to bottom and runs the first matching handler. int("7a") raises ValueError, but ValueError is a subclass of Exception, so the broader handler runs first and prints general.
In a try/except statement, handler order matters. Python does not search for the most specific match first; it uses the first except clause that can handle the raised exception.
int("7a")raisesValueError.ValueErroris a subclass ofException.- The
except Exceptionclause appears first, so it handles the error. - The later
except ValueErrorclause is never reached.
That is why the only output is general. To avoid hiding specific handlers, place more specific exceptions before broader ones.
- The option showing
valueassumes Python automatically prefers the most specific handler, but it does not. - The option showing both outputs fails because only one matching
exceptblock runs for one exception. - The option claiming the program stops with
ValueErrorignores that the earlierexcept Exceptionalready catches it.
Question 3
Topic: Block 4: Functions and Exceptions
A student writes this function:
def report(title, pages=1, color=False):
pass
Which TWO calls are invalid because the same parameter gets a value more than once?
Options:
A.
report("Guide", title="Notes")B.
report("Guide", 3, color=True)C.
report(title="Guide", pages=3)D.
report(color=True, title="Guide")E.
report("Guide", pages=3, color=True)F.
report("Guide", 3, pages=4)
Correct answers: A and F
Explanation: A parameter can receive a value by position or by keyword, but not both in the same call. The invalid calls are the ones where pages or title is assigned positionally first and then assigned again with a keyword.
Python matches positional arguments first, from left to right, and then applies keyword arguments. A call is invalid when one parameter ends up receiving two values.
In report("Guide", 3, pages=4), the value 3 already fills pages as the second positional argument, so pages=4 tries to fill pages again. In report("Guide", title="Notes"), the first positional argument already fills title, so title="Notes" duplicates that parameter.
Calls that use only keywords, only positionals, or a mix that targets different parameters are valid. The key check is simple: after matching the arguments, no parameter may have been assigned twice.
report("Guide", pages=3, color=True)is valid becausetitle,pages, andcolorare each supplied once.report(title="Guide", pages=3)is valid because both arguments are keywords and neither parameter is repeated.report(color=True, title="Guide")is valid because keyword arguments can appear in any order when each parameter is used once.report("Guide", 3, color=True)is valid becausetitleandpagesare filled positionally, andcoloris filled once by keyword.
Question 4
Topic: Block 4: Functions and Exceptions
A beginner runs this program. Assume there is no other try/except in the program.
def pick(items, n):
return items[n]
def show(items, n):
try:
print(pick(items, n))
except KeyError:
print("missing key")
names = ["Ann", "Bob"]
show(names, 2)
The program crashes. Which statement best explains the crash?
Options:
A.
pick()returnsNone, andprint()crashes on that value.B.
pick()raisesIndexError, butshow()only catchesKeyError.C. The
except KeyErrorblock catches the error and printsmissing key.D.
pick()raisesKeyErrorbecause list position2is missing.
Best answer: B
Explanation: names[2] is outside the valid list indexes, so Python raises IndexError. The active handler in show() is only for KeyError, so the exception is not caught and continues upward until the program stops.
Python handles an exception only when an active except clause matches the actual exception type. Here, pick(items, n) tries to read names[2], but the list has only two elements, so the real error is IndexError. The try block in show() is active, but its handler is except KeyError, which is for missing dictionary keys, not out-of-range list indexes.
Because no matching handler exists in show(), the IndexError propagates back to the caller. The stem says there is no other try/except, so the exception remains unhandled and the program crashes. The key idea is to identify both the real exception type and whether any active handler matches it.
- The option claiming a missing list position raises
KeyErrorconfuses list indexing with dictionary lookup. - The option saying
missing keyis printed ignores thatexcept KeyErrordoes not matchIndexError. - The option saying
pick()returnsNoneis wrong because out-of-range indexing raises an exception before any value is returned.
Question 5
Topic: Block 4: Functions and Exceptions
A student is making study notes and stores exception names as strings in a dictionary.
notes = {
"root": "?",
"examples": ["TypeError", "ValueError", "ZeroDivisionError"]
}
Which string should replace ? to make the note about Python’s built-in exception hierarchy correct?
Options:
A.
RuntimeErrorB.
ArithmeticErrorC.
ExceptionD.
BaseException
Best answer: D
Explanation: In Python’s built-in hierarchy, BaseException sits above Exception and all standard exception branches. Since the dictionary stores class names as strings, the root entry must be BaseException.
BaseException is the top-level built-in exception base class in Python. Most exceptions beginners commonly use, such as TypeError, ValueError, and ZeroDivisionError, are descendants of Exception, and Exception itself inherits from BaseException. That makes BaseException the only correct value for the dictionary’s root key.
A simple way to view the hierarchy is:
BaseExceptionException- specific subclasses such as
TypeErrorandValueError
The closest distractor is Exception, because it is a very common base class in try/except code, but it is still one level below BaseException.
Exceptionis close but lower: it is a major base class, but it inherits fromBaseException.ArithmeticErroris a branch: it groups numeric-related exceptions and is not the root of all built-in exceptions.RuntimeErroris too specific: it is one ordinary exception class, not a top-level base class.
Question 6
Topic: Block 4: Functions and Exceptions
Consider this function:
def fetch(data, item):
return data[item]
If numbers is a list, fetch(numbers, 10) can raise IndexError. If prices is a dictionary, fetch(prices, "milk") can raise KeyError when the key is missing. Which except clause catches both through their common built-in exception family?
Options:
A.
except ArithmeticError:B.
except TypeError:C.
except ValueError:D.
except LookupError:
Best answer: D
Explanation: Use except LookupError: because both examples are lookup failures caused by data[item]. Python places IndexError and KeyError under the same built-in exception family, so one handler can catch either case.
When a function uses data[item], Python performs a lookup in a container. If the container is a list and the index does not exist, Python raises IndexError. If the container is a dictionary and the key is absent, Python raises KeyError. Those two specific exceptions share the same parent class: LookupError.
That is why except LookupError: can handle both situations with one clause. The other choices name different exception families: ArithmeticError is for math-related errors, ValueError is for an unacceptable value, and TypeError is for using an operation with an incompatible type. The key takeaway is that failed indexing and failed key access are both lookup-related exceptions.
- Arithmetic family is unrelated because the function is not doing a numeric operation.
- Bad value is not the right match here; missing keys and invalid indexes are classified as lookup failures.
- Wrong type would apply to an incompatible type being used, not to an absent element in a valid container.
Question 7
Topic: Block 4: Functions and Exceptions
What is printed by this Python 3 code?
def total(n):
if n <= 0:
return 0
return n + total(n - 2)
print(total(5))
Options:
A. 9
B. 15
C. 8
D. RecursionError
Best answer: A
Explanation: This recursive function has a clear base case: when n <= 0, it returns 0. Starting from 5, each call adds the current value and then calls itself with n - 2, producing 5 + 3 + 1 + 0.
In recursion, you need a base case and a recursive case. Here, the base case is n <= 0, which stops the function and returns 0. The recursive case returns the current n plus the result of calling the function again with n - 2.
So the calls unfold like this:
total(5)returns5 + total(3)total(3)returns3 + total(1)total(1)returns1 + total(-1)total(-1)returns0
When the calls finish, the values are added during the return phase: 5 + 3 + 1 + 0 = 9. The closest wrong idea is adding every number from 1 to 5, but this function skips even numbers because it subtracts 2 each time.
- One term missed The value
8ignores one of the recursive additions, but both3and1are included before the base case returns0. - Adds every number The value
15would come from5 + 4 + 3 + 2 + 1, but the function decreases by 2, not by 1. - No stop condition
RecursionErrorwould happen without a reachable base case, butn <= 0is reached after a few calls.
Question 8
Topic: Block 4: Functions and Exceptions
A beginner wrote this program:
values = ["3", "two", "4"]
total = 0
for v in values:
total += int(v)
print(total)
print("done")
The goal is to skip any value that cannot be converted with int() and continue processing the rest of the list. Which revision is the best fix?
Options:
- A. Replace the loop with:
for v in values:
try:
total += int(v)
except ValueError:
continue
- B. Replace the loop with:
for v in values:
if v:
total += int(v)
- C. Replace the loop with:
for v in values:
try:
total += int(v)
except TypeError:
continue
- D. Replace the loop with:
try:
for v in values:
total += int(v)
except ValueError:
pass
Best answer: A
Explanation: int("two") raises a ValueError, so the risky conversion must be handled with try-except. Putting that handler inside the loop lets the program skip only the bad item and keep processing later values.
The core idea is to catch the specific runtime exception at the point where it can happen. Here, int(v) is the risky operation, and a non-numeric string like "two" raises ValueError.
When the try-except is inside the for loop, each list element is handled independently. If one conversion fails, the except ValueError block runs and continue moves to the next iteration, so later values such as "4" are still added to total.
If the whole loop is wrapped in one try, the first bad value ends the loop early. Catching TypeError does not help because the actual exception is ValueError. Checking whether a string is truthy only tests whether it is empty, not whether it contains digits.
Handle the smallest risky statement with the correct exception type when you want the loop to keep running.
- Whole-loop handler catches the error after the loop has already stopped, so later values are not processed.
- Wrong exception type fails because
int("two")raisesValueError, notTypeError. - Truthiness check only rejects empty strings; a non-empty invalid string still crashes at
int(v).
Question 9
Topic: Block 4: Functions and Exceptions
What is printed when this Python code runs?
def third():
print("third")
return 10 / 0
def second():
print("second")
third()
print("after")
def first():
try:
second()
except ZeroDivisionError:
print("handled")
first()
Options:
A.
second,third,after,handledB.
second,handledC.
second,third, then an unhandledZeroDivisionErrorD.
second,third,handled
Best answer: D
Explanation: The error happens inside third(), but neither third() nor second() handles it. The exception propagates back to first(), where the except ZeroDivisionError block runs, so after is never printed.
An unhandled exception moves outward through function calls until Python finds a matching except block or the program ends. Here, second() calls third(), and third() prints third before raising ZeroDivisionError during 10 / 0.
second()printssecondthird()printsthird- the exception leaves
third()and thensecond() first()catches it and printshandled
Because the call to third() does not finish normally, control never reaches print("after") in second(). The key idea is that exceptions cross function boundaries when they are not handled locally.
- The option including
afterfails because execution insecond()stops as soon asthird()raises the exception. - The option omitting
thirdfails because that line is printed before the division error occurs. - The option claiming the error is unhandled fails because
first()has a matchingexcept ZeroDivisionErrorblock.
Question 10
Topic: Block 4: Functions and Exceptions
What is the output of this program?
def check():
print("check")
return False
if check:
print("go")
else:
print("stop")
Options:
A. Only
gois printed.B. Only
stopis printed.C.
checkand thenstopare printed.D.
checkand thengoare printed.
Best answer: A
Explanation: The code uses check instead of check(), so Python treats it as a reference to the function object, not a function call. The function body never runs, and the condition is truthy, so only go is printed.
In Python, a function name by itself refers to the function object. To execute the function, you must add parentheses, such as check(). Here, the condition is if check:, so Python does not run the function body at all.
Because the function is never called:
print("check")does not execute.return Falseis never reached.- The condition tests the function object itself.
- A function object is truthy, so the
ifbranch runs.
That is why the program prints only go. The closest mistake is reading if check: as though it were if check():.
- The option claiming
checkand thengofails because the function body never runs without parentheses. - The option claiming
checkand thenstopfails becausereturn Falseis never reached. - The option claiming only
stopfails because a function object used in a condition is truthy.
Continue in the web app
Use IT Mastery for interactive Python Institute PCEP practice with mixed sets, timed mocks, topic drills, explanations, and progress tracking.
Try Python Institute PCEP on Web