Try 30 free PCEP-30-02 questions across the exam domains, with explanations, then continue with full IT Mastery practice.
This free full-length PCEP-30-02 practice exam includes 30 original IT Mastery questions across the exam domains.
These questions are for self-assessment. They are not official exam questions and do not imply affiliation with the exam sponsor.
Count note: this page uses the full-length practice count maintained in the Mastery exam catalog. Some certification vendors publish total questions, scored questions, duration, or unscored/pretest-item rules differently; always confirm exam-day rules with the sponsor.
Need concept review first? Read the PCEP-30-02 Cheat Sheet on Tech Exam Lexicon, then return here for timed mocks and full IT Mastery practice.
Open the matching IT Mastery practice page for timed mocks, topic drills, progress tracking, explanations, and full practice.
| Domain | Weight |
|---|---|
| Block 1: Computer Programming and Python Fundamentals | 18% |
| Block 2: Control Flow - Conditional Blocks and Loops | 29% |
| Block 3: Data Collections - Tuples, Dictionaries, Lists, and Strings | 25% |
| Block 4: Functions and Exceptions | 28% |
Use this as one diagnostic run. IT Mastery gives you timed mocks, topic drills, analytics, code-reading practice where relevant, and full practice.
Topic: Block 4: Functions and Exceptions
A beginner wants this program to print Hello Mia three times, but the last line fails.
def repeat_msg(name, count):
for _ in range(count):
print("Hello", name)
repeat_msg("Mia")
Without changing the function definition, which change best fixes the program?
Options:
A. repeat_msg(name="Mia")
B. repeat_msg(3, "Mia")
C. repeat_msg("Mia", 3)
D. repeat_msg()
Best answer: C
Explanation: repeat_msg has two required parameters: name and count. The call currently passes only one value, so the fix is to supply the missing second argument, such as 3.
In Python, a function call must provide a value for every required parameter unless that parameter has a default value. Here, repeat_msg(name, count) defines two required parameters, and neither has a default. That means repeat_msg("Mia") raises a TypeError because count is missing.
The program is supposed to print the same greeting three times, so the call needs both pieces of information:
"Mia"3So the working call is repeat_msg("Mia", 3). Calls that still omit count remain invalid, and swapping the argument order sends the wrong values into the parameters. Match the function call to the function definition exactly.
3 first swaps the values, so count receives "Mia", which breaks range(count).name="Mia" still leaves the required count argument missing.Topic: Block 4: Functions and Exceptions
What happens when this Python 3 code runs?
def show(message):
print(message)
word = "Hi"
show(word, "!")
Options:
A. It raises TypeError
B. It prints Hi!
C. It raises NameError
D. It prints Hi
Best answer: A
Explanation: message is the only parameter in the function definition, so show() accepts one positional input. The call supplies two arguments, word and "!", so Python raises TypeError before the function body runs.
A parameter is the name listed in a function definition, and an argument is the actual value or expression supplied in the function call. In def show(message):, message is the single parameter, so the function expects exactly one positional argument.
In show(word, "!"), Python supplies two arguments:
word"!"Because the number of arguments does not match the number of parameters, Python stops with a TypeError. The print(message) line is never executed.
A common mistake is to think the function will print both values, but argument checking happens before the function body starts.
Hi! fails because show() is rejected before it can print anything.Hi fails because Python does not ignore the extra argument in a normal function call.NameError fails because word is defined; the problem is the argument count.Topic: Block 2: Control Flow - Conditional Blocks and Loops
A student wants this program to print Not found only when target is absent from the list. With the current code, nothing is printed for the shown values. What is the best fix?
numbers = [1, 3, 5]
target = 4
for n in numbers:
if n != target:
break
else:
print("Not found")
Options:
A. Replace break with continue
B. Delete the else and print after the loop
C. Move print("Not found") inside the loop
D. Change the condition to if n == target:
Best answer: D
Explanation: In Python, a loop else block runs only if the loop finishes without break. The current code breaks on the first non-matching value, so the search stops too early and the else block is skipped.
The core concept is Python’s for ... else behavior: the else block is tied to the loop, and it runs only when the loop ends normally. If break executes, the else block does not run.
Here, if n != target: is backwards for a search. Since the first value (1) is not equal to 4, the loop breaks immediately. The loop never finishes checking the whole list, so print("Not found") is skipped.
for n in numbers:
if n == target:
break
else:
print("Not found")
This pattern searches the list and uses else only when no match was found.
break with continue keeps the loop running, but the else block would still run even if the target exists.Not found inside the loop can happen after the first non-match, before all items are checked.Not found every time, including when a match was found.Topic: Block 3: Data Collections - Tuples, Dictionaries, Lists, and Strings
A student wants this program to print bAnana by changing only the character at index 1 and keeping text as a string:
text = "banana"
text[1] = "A"
print(text)
Which replacement for the broken assignment line is the best fix?
Options:
A. text = text[:1] + "A" + text[2:]
B. text = "A" + text[1:]
C. text[1:2] = "A"
D. text = text.replace("a", "A")
Best answer: A
Explanation: Strings are immutable in Python, so you cannot assign directly to a character position. The correct fix creates a new string by joining the part before index 1, the new character, and the part after index 1.
A Python string cannot be changed in place after it is created. That is why assigning to text[1] fails: indexing lets you read a character, but not overwrite it. To change one character, you must build a new string.
For this case:
text[:1] gives "b""A" is the replacement charactertext[2:] gives "nana"Combining those parts produces "bAnana". This keeps text as a string and changes only the character at the required position. A tempting alternative is using replace(), but that works by matching values, not by targeting one index.
replace("a", "A") changes every matching a, so it does not target only index 1."A" + text[1:] replaces the first character, not the second one.text[1:2] still tries to modify the existing string, which is not allowed.Topic: Block 2: Control Flow - Conditional Blocks and Loops
A student wants this program to print 3, 2, 1 and then stop, but it keeps printing larger numbers and never ends. What is the best cause of the problem?
count = 3
while count > 0:
print(count)
count += 1
Options:
A. count += 1 moves count away from 0, so the condition stays true.
B. The loop needs a break statement after print(count).
C. print(count) should be outside the loop.
D. The condition should be count >= 0.
Best answer: A
Explanation: The loop condition is count > 0, but count starts at 3 and is increased each time. Tracing the values gives 3, 4, 5, and so on, so the condition never becomes false and the loop is infinite.
To trace a while loop, follow the control variable from its initial value through each update. Here, count starts at 3, and the loop runs while count > 0. Inside the loop, count += 1 makes the value larger, not smaller, so every new value still satisfies the condition.
count is 3, so the loop begins.count becomes 4.count becomes 5.A while loop stops only when its condition becomes false. If the goal is to count down to 0, the update must move toward 0, such as count -= 1.
count >= 0 does not help, because 3, 4, 5, and later values still satisfy it.print(count) outside the loop changes the output behavior, but it does not fix the loop control problem.break could force an exit, but it does not identify the actual bug in the loop update.Topic: Block 3: Data Collections - Tuples, Dictionaries, Lists, and Strings
A ticket-check program stores valid ticket IDs in a list.
ticket_id = "B12"
valid_ids = ["A10", "B12", "C07"]
Which TWO expressions correctly evaluate to True when ticket_id is present in valid_ids? Select TWO.
Options:
A. ticket_id in valid_ids
B. ticket_id not in valid_ids
C. valid_ids in ticket_id
D. ticket_id == valid_ids
E. valid_ids[ticket_id]
F. bool(ticket_id in valid_ids)
Correct answers: A and F
Explanation: Python uses in to check whether a value appears as an element in a list. Both the plain membership expression and the same expression wrapped in bool() correctly return True here because "B12" is one of the items in valid_ids.
The core concept is list membership testing with in. In Python, the searched value goes on the left and the list goes on the right: value in some_list. That expression already evaluates to a Boolean value.
In this scenario, ticket_id is "B12", and valid_ids contains "B12", so the membership test is True.
ticket_id in valid_ids is the standard membership check.bool(ticket_id in valid_ids) is also correct because it converts an already Boolean result to True or False.Common mistakes are reversing the operands, comparing a single value to the whole list, or using not in, which checks the opposite condition.
not in is True only when the value is absent.Topic: Block 2: Control Flow - Conditional Blocks and Loops
A student is drafting a function and wants to leave one branch unfinished for now. The code must stay valid, and the later print() and return lines should still run normally.
def check_age(age):
if age < 0:
# validation will be added later
???
print("checked")
return age
Which statement should replace ????
Options:
A. continue
B. pass
C. return
D. break
Best answer: B
Explanation: pass is Python’s placeholder statement for an empty block. It satisfies the if body requirement without exiting the function or changing what runs next.
Python requires an indented statement after an if. When you want that block to exist for now but do nothing, use pass. In this function, pass lets the if age < 0 branch stay empty while control flow continues normally to print("checked") and then return age.
pass does nothing.The closest wrong choice is return, because it is valid inside a function, but it would end the function early instead of acting as a placeholder.
return changes the function’s flow by exiting immediately.continue can be used only inside a loop, not in this standalone if block.break also requires a loop and cannot be used here.Topic: Block 2: Control Flow - Conditional Blocks and Loops
A student wants to count all (row, col) pairs in a 3 x 2 grid, but the update line is indented as shown.
count = 0
for row in range(3):
for col in range(2):
print(row, col)
count += 1
print("count =", count)
What is the final line printed?
Options:
A. It raises IndentationError.
B. It prints count = 3.
C. It prints count = 6.
D. It prints count = 2.
Best answer: B
Explanation: Indentation decides which loop controls a statement. Here, count += 1 is outside the inner loop but inside the outer loop, so it runs once for each row. Since there are 3 outer iterations, the final line is count = 3.
In nested loops, a line runs only in the block where it is indented. The inner loop here contains only print(row, col). The line count += 1 is aligned with the inner for, so it is not part of the inner loop body.
That means this happens:
(row, col) pairs for one rowcount increases by 1So count changes from 0 to 3. To get 6, the increment would need to be indented one level deeper so it runs for every (row, col) pair.
count = 6 assumes the increment is inside the inner loop.count = 2 confuses the number of columns with the number of times the update runs.IndentationError is incorrect because the code is indented validly; the problem is logical, not syntactic.Topic: Block 4: Functions and Exceptions
A beginner is troubleshooting why this program does not end with an uncaught exception. What is the output?
def calc():
return 10 / 0
try:
calc()
print("try")
except ZeroDivisionError:
print("except")
print("end")
Options:
A. It ends with an uncaught ZeroDivisionError.
B. It prints only except.
C. It prints except and then end.
D. It prints try and then end.
Best answer: C
Explanation: The function call raises ZeroDivisionError inside the caller’s try block. That exception is caught by the matching except, so print("try") is skipped and execution continues to the final print("end").
When calc() runs, 10 / 0 raises ZeroDivisionError. Because that call happens inside the try block, control immediately leaves the rest of the try block, so print("try") never runs.
The caller has a matching except ZeroDivisionError, so the exception is handled there and print("except") runs. After the exception is handled, the program continues normally with the next statement after the try/except, so it also prints end.
An uncaught traceback would appear only if there were no matching handler in the caller.
try is printed fails because execution stops the try block as soon as calc() raises.except is printed fails because the program continues after a handled exception.ZeroDivisionError.Topic: Block 2: Control Flow - Conditional Blocks and Loops
What is printed by this code?
def check(values):
for v in values:
if v < 0:
break
else:
return "all non-negative"
return "negative found"
print(check([3, 1, 0]))
Options:
A. Nothing is printed
B. all non-negative
C. None
D. negative found
Best answer: B
Explanation: In Python, a loop else runs only when the loop finishes normally, not when it is ended by break. Here, no value in [3, 1, 0] is negative, so the function returns all non-negative and print() displays it.
The key concept is that a loop else belongs to the for loop, not to the if statement inside it. Python executes the loop else only if the loop completes all iterations without hitting break.
In this function, the values are 3, 1, and 0. For each value, the condition v < 0 is checked, and it is false every time. Because no break happens, the for loop finishes normally, so the else block runs and returns "all non-negative".
That returned string is then passed to print(). The common mistake is to think the else is paired with if, but here it is paired with the loop.
negative found fails because that return happens only after a break, and no negative value appears.None fails because both possible paths in the function return a string.print() always displays the function’s returned string here.Topic: Block 1: Computer Programming and Python Fundamentals
A beginner is testing a console checkout script. After the user enters data, the program has:
is_member = True
has_coupon = False
is_guest = False
Which TWO if conditions evaluate to True in Python?
Options:
A. is_member and not has_coupon or is_guest
B. not is_guest or has_coupon and not is_member
C. not is_member and has_coupon or is_guest
D. not is_member or has_coupon or is_guest
E. is_guest or has_coupon and is_member
F. not is_guest and has_coupon or not is_member
Correct answers: A and B
Explanation: Python evaluates logical operators in this order: not, then and, then or. Using is_member = True, has_coupon = False, and is_guest = False, only two expressions reduce to True after applying that precedence.
The key concept is Python’s logical operator precedence: not is evaluated first, then and, and finally or. That means you should simplify each expression in that order instead of reading straight from left to right.
is_member and not has_coupon or is_guest becomes True and True or False, then True or False, so it is True.not is_guest or has_coupon and not is_member becomes True or False and False, then True or False, so it is True.All other options reduce to False because their and parts or remaining or terms are false. A common mistake is to treat or as if it were checked before and, but Python does the opposite.
not is_member and has_coupon or is_guest fails because each part becomes False.not is_guest and has_coupon or not is_member fails because True and False becomes False, and not is_member is also False.is_guest or has_coupon and is_member fails because has_coupon is False, so both sides of or are false.not is_member or has_coupon or is_guest fails because all three terms evaluate to False.Topic: Block 3: Data Collections - Tuples, Dictionaries, Lists, and Strings
A student wants to label a collection as editable only when its elements can be changed in place.
collections = [(1, 2), [3, 4]]
for data in collections:
if type(data) == list:
print("editable")
else:
print("fixed")
Which statement correctly describes this control flow?
Options:
A. It raises an error because a for loop cannot iterate over a tuple and a list in one outer list.
B. It prints fixed then editable because tuples are immutable and lists are mutable.
C. It prints editable twice because both collections can store multiple values.
D. It prints fixed twice because both collections are sequences.
Best answer: B
Explanation: The for loop checks each collection one at a time. A tuple is not a list, so it prints fixed first; the second item is a list, so it prints editable next.
This question combines simple control flow with the difference between tuples and lists. The loop visits the first item, (1, 2), and the condition type(data) == list is false, so the else branch prints fixed. Then it visits the second item, [3, 4], and the condition is true, so the if branch prints editable.
The important collection concept is that tuples are immutable, meaning their elements cannot be reassigned after creation. Lists are mutable, so their elements can be changed in place. Being a sequence or holding multiple values does not make a collection mutable.
The key takeaway is that both tuples and lists can be looped over, but only lists are meant for later modification.
for loop can iterate over an outer list containing different collection types.Topic: Block 4: Functions and Exceptions
What is the output of this Python 3 code?
price = 20
def show_price():
price = 15
print(price)
show_price()
print(price)
Options:
A. First 20, then 20
B. It raises an error because price is defined twice
C. First 15, then 20
D. First 15, then 15
Best answer: C
Explanation: A variable assigned inside a function is local unless the function uses global. Here, the function prints its own local price, but the variable outside the function keeps its original value.
This code demonstrates local scope and shadowing. The name price exists outside the function with value 20, but price = 15 inside show_price() creates a separate local variable for that function call. That local variable is used only inside the function body, so the first print(price) shows 15.
After the function finishes, the local variable disappears. The outer price was never changed, so the final print(price) shows 20.
The closest wrong idea is that assigning price inside the function also updates the outer variable, but that would require using global.
15 twice assumes the assignment inside the function changes the outer variable, which it does not.20 twice ignores that the function prints its own local price.Topic: Block 1: Computer Programming and Python Fundamentals
What is the exact console output of this Python 3 code?
print("A", "B", sep=":", end="*")
print("C", "D", sep="-", end="!")
Options:
A. A:B*C D!
B. A:B*
C-D!
C. A B*C-D!
D. A:B*C-D!
Best answer: D
Explanation: The first print() joins A and B with : and ends with * instead of a newline. The second print() continues on the same line, joins C and D with -, and ends with !, so the display is A:B*C-D!.
print() has two optional arguments that matter here: sep changes the text placed between multiple values, and end changes what is printed after them. In the first call, sep=":" makes the output A:B, and end="*" adds * instead of the usual newline. Because no newline is printed, the next print() starts immediately after that *.
In the second call, sep="-" makes C-D, and end="!" adds the final exclamation mark. Putting both calls together produces A:B*C-D!.
A common mistake is to think end adds its text and then still moves to a new line, but it replaces the newline.
print() still moves to a new line after printing *.A B ignores sep=":" in the first print().C D ignores sep="-" in the second print().Topic: Block 3: Data Collections - Tuples, Dictionaries, Lists, and Strings
The program should add a new key-value pair to the user dictionary, but it uses the wrong operation. Which replacement line is the best fix?
user = {"name": "Lena", "age": 19}
user.append("city", "Paris")
print(user)
Options:
A. user["city"] = "Paris"
B. user.update("city", "Paris")
C. user.add("city", "Paris")
D. user.insert("city", "Paris")
Best answer: A
Explanation: Dictionaries add one new entry by key assignment with square brackets. Using user["city"] = "Paris" creates the city key and stores its value in the existing dictionary.
The core concept is dictionary mutation by item assignment. In Python, the normal way to add one key-value pair is dictionary[key] = value. If the key does not exist yet, Python creates it; if it already exists, Python updates its value.
In this program, append() is the problem because that method is used with lists, not dictionaries. Replacing that line with user["city"] = "Paris" correctly adds a new entry to the dictionary without changing the rest of the code.
This is the simplest and most direct fix for adding exactly one new key-value pair.
add() is not the method used to add a single key-value pair to a dictionary.insert() is associated with list-style position-based insertion, not dictionary keys.update("city", "Paris") uses a real dictionary method name, but the arguments are in the wrong form for update().Topic: Block 2: Control Flow - Conditional Blocks and Loops
A student wants to rewrite this loop so it uses sequence iteration because item positions are never needed. The program should print each code until STOP is found, then stop.
codes = ["A12", "B34", "STOP", "C56"]
for i in range(len(codes)):
if codes[i] == "STOP":
break
print(codes[i])
Which change is correct?
Options:
A. Use for i in codes, then test codes[i] against STOP before printing.
B. Use for i in range(len(codes)), but test i against STOP before printing.
C. Use for code in codes, compare code to STOP, and break when it matches.
D. Use for code in codes, but replace break with continue when code is STOP.
Best answer: C
Explanation: The loop only needs each list value, not its position, so direct iteration is the right control flow. Iterating with for code in codes keeps the same behavior: print each code in order and stop immediately when STOP is reached.
When indexes are not needed, Python code should usually iterate over the sequence elements directly with for item in sequence. In this case, the task is to examine each code value, print it, and stop when the sentinel value STOP appears. That means the loop variable should hold each string from the list, not a numeric position.
for code in codes gives each code directly.break ends the loop as soon as STOP is found.range(len(codes)) is unnecessary here because the index is never used for a separate purpose.The closest distractor changes break to continue, but that would skip STOP and keep processing later items.
for i in codes with codes[i] fails because the loop variable would be a code string, not a valid list index.break with continue changes the behavior from stopping at STOP to skipping it and continuing.range(len(codes)) to STOP fails because the index is an integer, not a list element.Topic: Block 2: Control Flow - Conditional Blocks and Loops
A student runs this script:
total = 0
for i in range(1, 5):
if i == 3:
break
total += i
else:
total += 10
print(total)
What is printed?
Options:
A. It prints 13
B. It prints 16
C. It prints 3
D. It prints 6
Best answer: C
Explanation: The script prints 3. The loop adds 1 and 2, then stops when i becomes 3. In a for loop, the else block runs only if the loop finishes without break, so it does not run here.
In a for loop, break immediately ends the loop, and a loop else runs only when the loop completes all iterations normally. Here, range(1, 5) produces 1, 2, 3, and 4. The variable total starts at 0, becomes 1 after the first pass, and 3 after the second pass. On the next pass, i is 3, so the if i == 3 condition is true and break executes before total += i can run. Because the loop ended with break, the else block is skipped, so 10 is not added. The final printed value is 3. The main trap is treating loop else like a normal if/else; it depends on whether the loop was broken early.
6 choice assumes 3 is added before break, but break happens first.13 choice assumes the loop else always runs, but break prevents it.16 choice combines both mistakes by adding 3 and also adding 10 from the skipped else block.Topic: Block 4: Functions and Exceptions
A beginner is writing helper functions for a console app. Which TWO headers could start a valid Python function definition?
Options:
A. function greet():
B. def class():
C. def 2greet():
D. greet def():
E. def print_total(value):
F. def greet():
Correct answers: E and F
Explanation: A valid Python function header uses def, then a legal identifier, then parentheses and a colon. greet and print_total follow those rules, so both can begin user-defined function definitions.
In Python, a user-defined function starts with a header in the form def name(parameters):. The function name must be a valid identifier: it may use letters, digits, and underscores, but it cannot start with a digit and it cannot be a reserved keyword such as class. Both greet and print_total satisfy those naming rules, and both headers use the required def keyword, parentheses, and trailing colon. Options that use a different keyword, an illegal name, or the wrong word order do not match Python syntax. The key check is simple: correct def syntax plus a legal function name.
function fails because Python defines functions with def.2greet fails because identifiers cannot begin with a number.class fails because Python keywords cannot be used as function names.greet before def does not follow Python’s function-definition syntax.Topic: Block 2: Control Flow - Conditional Blocks and Loops
A program should print adult for any user age 18 or older, and print adult member only when that outer age test has already succeeded. The code is broken:
age = 16
member = True
if age >= 18:
print("adult")
if member:
print("adult member")
What is the best fix?
Options:
A. Make if member: the outer test and nest the age test
B. Replace the second if with elif member:
C. Indent if member: under if age >= 18:
D. Change the first test to if age >= 18 and member:
Best answer: C
Explanation: The fix is to nest the membership check inside the age check. In Python, an inner if runs only when the outer if is true, so adult member cannot print for someone under 18 while adult still prints for any adult.
This tests nested conditional flow and indentation. Two separate if statements are independent, so the second condition is checked whether or not the first one passed. In the broken code, member is tested even when age >= 18 is false, which lets adult member print for a minor.
To make the second test depend on the first, put it inside the first block:
age >= 18memberadult prints for every adult, and adult member prints only for adult membersUsing elif is the opposite flow because it runs when the first test fails, and combining both conditions into one outer test removes the separate adult case.
elif member fails because elif is evaluated when age >= 18 is false.adult for adult non-members.Topic: Block 4: Functions and Exceptions
What is printed by this code?
def label(first, second, third):
print(first + "-" + second + "-" + third)
label("red", third="blue", second="green")
label("up", second="left", third="right")
Options:
A. First line: red-blue-green; second line: up-left-right
B. First line: red-green-blue; second line: up-right-left
C. First line: red-green-blue; second line: up-left-right
D. First line: red-blue-green; second line: up-right-left
Best answer: C
Explanation: Python assigns positional arguments first, then matches keyword arguments by name. That means the first call prints red-green-blue and the second prints up-left-right, even though the keyword arguments are written in a different order.
This tests how Python binds arguments in a valid mixed function call. A positional argument fills the next available parameter from left to right. After that, keyword arguments are matched to parameters by their names, not by the order they appear.
label("red", third="blue", second="green"), first gets "red", second gets "green", and third gets "blue".label("up", second="left", third="right"), first gets "up", second gets "left", and third gets "right".So the function prints red-green-blue on the first line and up-left-right on the second. The closest distractors come from treating keyword order as if it changed parameter order.
red-blue-green treats third="blue" as if it filled the second slot, but keywords match by name.up-right-left makes the same mistake in the second call by swapping second and third.Topic: Block 1: Computer Programming and Python Fundamentals
A beginner wants this program to print nananana Batman!, but it raises an error:
part = "na"
line = part + 4 + " Batman!"
print(line)
Which replacement for the second line is the best fix?
Options:
A. line = part + part + " Batman!"
B. line = part * "4" + " Batman!"
C. line = part * 4 + " Batman!"
D. line = part + str(4) + " Batman!"
Best answer: C
Explanation: Strings use + to join strings and * with an integer to repeat a string. The fixed expression must repeat "na" four times and then append " Batman!".
Python treats string concatenation and string repetition as different operations. The + operator joins one string to another string, while the * operator repeats a string only when the other operand is an integer. In the broken code, part + 4 fails because Python cannot concatenate a str and an int directly.
part * 4 becomes nananananananana + " Batman!" becomes nananana Batman!A common nearby mistake is turning 4 into the string "4"; that removes the type mismatch but still does not repeat the text.
4 to "4" avoids the original mismatch but produces na4 Batman!."4" is still invalid because string repetition needs an integer count.part only twice creates nana Batman!, which is too short.Topic: Block 4: Functions and Exceptions
A student wants this program to print True because "cat" is inside "concatenate", but it prints False. Without changing the function body, which replacement for the last line fixes the bug?
def has_fragment(text, fragment):
return fragment in text
print(has_fragment("cat", "concatenate"))
Options:
A. print(has_fragment("concatenate", "cat"))
B. print(has_fragment(fragment="concatenate", text="cat"))
C. print(has_fragment("cat", fragment="concatenate"))
D. print(has_fragment(text="cat", fragment="concatenate"))
Best answer: A
Explanation: The function expects the larger text first and the smaller fragment second because it checks fragment in text. The original call reverses those positional arguments, so it tests whether "concatenate" is inside "cat", which is False.
This bug comes from how positional arguments are matched: Python assigns them by order. In has_fragment(text, fragment), the first argument becomes text and the second becomes fragment.
The function returns fragment in text, so the call must provide:
textfragmentWith the original call, Python evaluates "concatenate" in "cat", which is False. Swapping the arguments makes the check "cat" in "concatenate", which is True.
Keyword arguments can also prevent order mistakes, but only if the correct values are assigned to the correct parameter names.
fragment="concatenate" and text="cat" is still reversed, even though the order on the line changes."cat" as the first argument, so text still gets the wrong value.Topic: Block 4: Functions and Exceptions
A student is writing a loop that should keep asking for an age. If the entry is not a valid integer, the program should print Invalid age and ask again. It should stop only when the entered age is 0. Which change correctly preserves that control flow and catches the right exception?
while True:
text = input("Age: ")
try:
age = int(text)
# replace here
if age == 0:
break
print(age)
Options:
A. Add except TypeError: then print Invalid age and continue.
B. Add except ValueError: then print Invalid age and continue.
C. Add except ValueError: then print Invalid age and break.
D. Add except IndexError: then print Invalid age and continue.
Best answer: B
Explanation: When int() cannot convert text like abc, Python raises ValueError. To keep the while loop asking again after bad input, the handler should catch ValueError and use continue, not break.
This item combines exception handling with loop control. In Python, int(text) raises ValueError when the string does not contain a valid integer. That means the handler should be specific to ValueError, not an unrelated exception such as TypeError or IndexError.
After printing the error message, continue skips the rest of the current loop iteration and goes back to the top of the while True loop for another prompt. Using break would end the loop immediately, which does not match the requirement to ask again after invalid input.
The key idea is to match the except clause to the actual failure that can happen, then choose loop control that fits the required behavior.
TypeError fails because invalid numeric text in int() does not raise that exception.break stops the loop after bad input instead of prompting again.IndexError fails because no indexing operation is involved here.Topic: Block 3: Data Collections - Tuples, Dictionaries, Lists, and Strings
A student wants this exact one-line output:
C:\new\test
But this program prints the text on two lines and includes a tab:
print("C:\new\test")
What is the best fix?
Options:
A. Add end="" to the print() call.
B. Use triple quotes around the same text.
C. Use single quotes around the same text.
D. Replace each \ with \\ in the string.
Best answer: D
Explanation: Backslashes in Python strings begin escape sequences like \n for newline and \t for tab. Because C:\new\test contains both patterns, Python changes the text before printing. Escaping each backslash as \\ keeps the output on one line and shows the path exactly.
When Python reads a string literal, it interprets backslash escapes before print() runs. In C:\new\test, the \n becomes a newline and the \t becomes a tab, so the text is not displayed as a normal path.
print("C:\\new\\test")
Each \\ in the source code represents one literal backslash in the output. After escaping both backslashes, Python prints C:\new\test exactly as written. The key idea is that the problem is inside the string literal, not in the print() function itself.
\n and \t are interpreted.end="" only changes what print() adds after the string, not the characters already inside the string.Topic: Block 1: Computer Programming and Python Fundamentals
A beginner writes this code to test whether a calculation equals 0.3:
total = 0.1 + 0.2
if total == 0.3:
print("match")
else:
print("different")
The program should treat tiny floating-point representation errors as equal. Which TWO replacements for the if line are appropriate?
Options:
A. if str(total) == "0.3":
B. if abs(total - 0.3) < 1e-9:
C. if total == float("0.3"):
D. if round(total, 10) == round(0.3, 10):
E. if int(total) == int(0.3):
F. if round(total) == round(0.3):
Correct answers: B and D
Explanation: Floating-point numbers such as 0.1 and 0.2 are not stored exactly in binary, so direct == comparisons can fail for values that are mathematically equal. Using a small tolerance with abs() or rounding both sides to a known precision are common ways to compare them safely.
The core issue is floating-point representation. In Python, 0.1 + 0.2 may be stored as a value very close to 0.3, not exactly 0.3, so == can report False even though the math result is what you expect. A tolerance check like abs(total - 0.3) < 1e-9 asks whether the numbers are close enough, which is a standard fix. Rounding both values to the same number of decimal places can also work when the required precision is known in advance. By contrast, converting to int, comparing strings, or creating another float value such as float("0.3") does not solve the underlying precision problem. The key takeaway is to avoid exact equality for simple float results when tiny representation errors are acceptable.
0, which is too imprecise for checking 0.3.Topic: Block 2: Control Flow - Conditional Blocks and Loops
A student wants to print each word in uppercase. Indexes are not needed for this task, but the program raises an error:
words = ["code", "loop", "list"]
for word in range(len(words)):
print(word.upper())
Which replacement for the for line is the best fix?
Options:
A. for word in range(words):
B. for word in len(words):
C. for word in range(len(words)):
D. for word in words:
Best answer: D
Explanation: When indexes are not needed, iterate directly over the sequence. Using for word in words: makes word hold each string from the list, so calling upper() works correctly.
The core idea is direct sequence iteration: use for item in sequence: when you need each element but not its position. In the broken code, range(len(words)) produces the integers 0, 1, and 2, so word becomes an integer instead of a string. Because integers do not have an upper() method, the loop fails.
Direct iteration fixes that immediately:
for word in words: assigns each list element to wordword.upper() then prints the uppercase versionUsing indexes is unnecessary here and makes the loop harder to read for this task.
len(words) returns one integer, so it cannot be used directly as the iterable in a for loop.range(words) is invalid because range() expects an integer argument, not a list.range(len(words)) still makes word an integer, so word.upper() still fails.Topic: Block 3: Data Collections - Tuples, Dictionaries, Lists, and Strings
A beginner says this program takes the wrong branch. With word = "python", they expected pypyn because "th" is in the word, but the program prints pypyp.
word = "python"
piece = word[0:2] * 2
if "th" in piece:
print(piece + word[-1])
else:
print(piece + word[0])
What is the best fix?
Options:
A. Build piece with word[0:3] * 2.
B. Concatenate word[-1] + piece instead.
C. Build piece with word[2:4] * 2.
D. Check "th" in word, not in piece.
Best answer: D
Explanation: The condition is checking the wrong string. piece becomes "pypy", so "th" in piece is False, even though "th" is in word; changing the condition to use word produces the expected pypyn.
The key concept is that the membership operator in checks only the string on its right. Here, word[0:2] gives "py", and * 2 repeats it to make piece = "pypy". Because "th" in "pypy" is False, Python runs the else branch and prints piece + word[0], which is "pypyp".
word[0:2] gets the first two characters.* 2 repeats that slice.word[-1] would correctly give "n", but that branch never runs.if "th" in word:.Changing the slice or the concatenation order changes the output text, but it does not fix the real cause of the wrong branch.
piece to word[2:4] * 2 makes the repeated text "thth", so it no longer matches the expected "pypy" part.piece to word[0:3] * 2 produces "pytpyt" and still leaves the condition tied to the wrong string.Topic: Block 1: Computer Programming and Python Fundamentals
A beginner wants latest_points to store the updated total after 4 points are added, using the current value of points. The program prints 10 instead of 14.
points = 10
latest_points = points
points = points + 4
print(latest_points)
Which change is the best fix?
Options:
A. Replace latest_points = points with latest_points = 14.
B. Change points = points + 4 to points == points + 4.
C. Move latest_points = points below points = points + 4.
D. Change print(latest_points) to print(points).
Best answer: C
Explanation: Assignment binds a name to the value it has at that moment. latest_points gets 10 before points is reassigned, so it stays 10. Moving the assignment after the update makes latest_points receive 14.
In Python, a variable name does not automatically follow later changes to another variable. When latest_points = points runs, latest_points is assigned the current value of points, which is 10. Then points = points + 4 reassigns points to 14, but latest_points is still 10 until it is assigned again.
A correct fix is to update points first and then assign that updated value to latest_points:
points = 10
points = points + 4
latest_points = points
print(latest_points)
The key takeaway is that reassignment changes the value bound to one name; it does not automatically change other names assigned earlier.
== compares values and does not reassign points.points would show 14, but latest_points still would not store the updated total.14 ignores the actual variable value and does not demonstrate correct reassignment.Topic: Block 3: Data Collections - Tuples, Dictionaries, Lists, and Strings
A student is debugging this code. The summarize() function must receive a list, even when it gets only one value.
temps = [18, 21, 19, 23]
summarize(???)
Which expression should replace ??? so that summarize() receives a list containing only 21?
Options:
A. temps[2:3]
B. temps[:1]
C. temps[1:2]
D. temps[1]
Best answer: C
Explanation: Use temps[1:2] because slicing returns a new list, even when the slice has just one item. Simple indexing with temps[1] returns the element itself, not a one-element list.
In Python, list indexing and list slicing look similar but produce different kinds of results. Indexing with one position, such as temps[1], returns a single element, so the result is the integer 21. Slicing with a start and stop, such as temps[1:2], returns a new list containing the selected range.
Because the stop index is excluded, 1:2 includes only the item at index 1. That makes the result [21], which matches a function that expects a list argument. A slice can contain one element, many elements, or even be empty, but it is still a list. The closest mistakes here use valid slices with the wrong boundaries, so they return the wrong value.
temps[1] gets the correct value, but it returns 21, not a list.temps[:1] is a slice, but it returns [18], which contains the first item.temps[2:3] is also a one-item slice, but it returns [19], not [21].Topic: Block 3: Data Collections - Tuples, Dictionaries, Lists, and Strings
A student is debugging a function that should change the first character of any non-empty string to J. The code fails because it treats a string like a mutable list.
def fix_name(name):
name[0] = "J"
return name
print(fix_name("mark"))
Which replacement for the two indented lines inside fix_name makes the function work as intended for any non-empty string?
Options:
A. return "J" + name[1:]
B. return name[:1] + "J" + name[1:]
C. return name[1:] + "J"
D. return name.replace(name[0], "J")
Best answer: A
Explanation: In Python, strings are immutable, so name[0] = "J" is invalid. The fix is to return a new string made from the replacement character and the rest of the original string.
A Python string cannot be changed in place with indexed assignment. That works for lists, but with strings it raises a TypeError. When a function needs an updated string, it must create and return a new one instead.
Here, name[1:] returns all characters after the first one. Concatenating "J" in front gives the same string except for index 0.
def fix_name(name):
return "J" + name[1:]
The key idea is to rebuild the string with slicing rather than trying to mutate it.
name[:1] keeps the original first character and inserts J after it.J changes the last position, not the first one.replace(name[0], "J") can change every matching character, not just index 0.Use the PCEP-30-02 Practice Test page for the full IT Mastery route, mixed-topic practice, timed mock exams, explanations, and web/mobile app access.
Try PCEP-30-02 on Web View PCEP-30-02 Practice Test
Read the PCEP-30-02 Cheat Sheet on Tech Exam Lexicon for concept review before another timed run.