Python Institute PCAP 31-03 Practice Questions with Explanations

Free Python Institute PCAP 31-03 practice questions. 18 of them, each with the correct answer, a full explanation, and the reason every other option is wrong. These are real questions from the 31-03 exam, not paraphrases, and every explanation is written out rather than just marking the right letter.

They are drawn from the same bank as the full 31-03 pack, which has 129 questions in total.

Get the full 31-03 question bank (129 questions) →

31-03 practice questions

Question 1

What is the expected output of the following code? import sys import math b1 = type(dir(math)) is list b2 = type(sys.path) is list print(b1 and b2)

  • A. None
  • B. True
  • C. 0
  • D. False
Show answer and explanation ▾

Correct answer: B

The dir() function returns a list of attributes, so type(dir(math)) is list evaluates to True. The sys.path variable is a list of directory paths where Python searches for modules, so type(sys.path) is list evaluates to True. Therefore b1 and b2 are both True, and True and True evaluates to True.

Why the other options are wrong:

  • A. None is not the output; the expression evaluates to a boolean value.
  • C. The integer 0 is not returned; boolean True is the result.
  • D. Both conditions are True, so the and operation returns True, not False.

Question 2

Assuming that the code below has been executed successfully, which of the following expressions will always evaluate to True? (Choose two.) import random v1 = random.random() v2 = random.random()

  • A. len(random.sample([1,2,3],1)) > 2
  • B. v1 == v2
  • C. random.choice([1,2,3]) > 0
  • D. v1>1
Show answer and explanation ▾

Correct answer: C

Option C is correct: random.choice([1,2,3]) always returns one of the three positive integers 1, 2, or 3, all of which are greater than 0, so this always evaluates to True. Option A is incorrect because random.sample([1,2,3],1) returns a list with exactly one element, and len() of that is 1, which is not greater than 2. Option B is incorrect because random.random() generates floats between 0.0 and 1.0, and the probability that two consecutive calls return identical values is virtually zero. Option D is incorrect because random.random() always returns a value in the range [0.0, 1.0), never greater than 1.

Why the other options are wrong:

  • A. random.sample([1,2,3],1) returns a list of length 1, and 1 is not greater than 2.
  • B. Two consecutive calls to random.random() produce different floating-point values with extremely high probability.
  • D. random.random() always returns a value in the range [0.0, 1.0), which is never greater than 1.

Question 3

Which one of the platform module functions should be used to determine the underlying platform name?

  • A. platform.processor()
  • B. platform.uname()
  • C. platform.python_version()
  • D. platform.platform()
Show answer and explanation ▾

Correct answer: D

Option D is correct: platform.platform() returns a string describing the underlying platform name, including the operating system and version information. Option A is incorrect because platform.processor() returns the processor name. Option B is incorrect because platform.uname() returns detailed system information as a named tuple but is more comprehensive than just the platform name. Option C is incorrect because platform.python_version() returns the Python version, not the platform name.

Why the other options are wrong:

  • A. platform.processor() returns processor information, not the platform name.
  • B. platform.uname() returns comprehensive system information including platform details, but is not the dedicated function for just the platform name.
  • C. platform.python_version() returns the Python interpreter version, not the underlying platform name.

Question 4

What is the expected behavior of the following code?

  • A. the code is erroneous and it will not execute
  • B. it outputs 1
  • C. it outputs 2
  • D. it outputs 0
Show answer and explanation ▾

Correct answer: C

The code attempts to convert the string '2A' to an integer using int(s). Since '2A' is not a valid decimal integer, this raises a ValueError (not an ArithmeticError). The except clauses are evaluated in order, so the ValueError is caught by the first except block, setting n = 2. This value is then printed. The subsequent except clauses are not evaluated because the exception has already been handled.

Why the other options are wrong:

  • A. The code is syntactically valid and will execute successfully without errors.
  • B. The ArithmeticError handler sets n = 1, but a ValueError is raised first, which is caught by the ValueError handler before reaching the ArithmeticError handler.
  • D. The bare except clause sets n = 0, but since the ValueError is caught by the specific ValueError handler, execution never reaches the bare except block.

Question 5

What is the expected behavior of the following code?

  • A. it outputs 3
  • B. it outputs 1
  • C. it outputs 2
  • D. the code is erroneous and it will not execute
Show answer and explanation ▾

Correct answer: A

The code executes foo(0), which attempts to return 1/0, causing a ZeroDivisionError (a subclass of ArithmeticError). This is caught by the outer except ArithmeticError block, which increments m by 2 (m becomes 2). However, the inner except clause in foo() also executes before the exception propagates: when the ArithmeticError occurs, m is incremented by 1 inside foo's except block (m becomes 1), then the raise statement re- raises the exception. The outer except ArithmeticError catches it and increments m by 2 again (m becomes 3). Finally, print(m) outputs 3.

Why the other options are wrong:

  • B. The inner exception handler in foo increments m by 1, but this is not the final value because the outer handler also executes.
  • C. While m is incremented to 2 by the outer ArithmeticError handler alone, the inner handler's increment of 1 occurs first, making the total 3.
  • D. The code is syntactically valid Python; the exception handling structure is correct and the code executes without errors.

Question 6

What is the expected behavior of the following code?

  • A. it outputs error
  • B. it outputs
  • C. the code is erroneous and it will not execute
  • D. it outputs list assignment index out of range
Show answer and explanation ▾

Correct answer: D

The code attempts to access index 3 of a list that only has 3 elements (indices 0, 1, 2). When my_list[3] is accessed, Python raises an IndexError with the message 'list assignment index out of range', which is caught by the except BaseException clause and printed. The code will execute successfully and output this error message.

Why the other options are wrong:

  • A. While an error is printed, the specific output is the IndexError message, not a generic 'error'
  • B. The code does not output nothing; it prints the IndexError exception message
  • C. The code is syntactically valid and will execute; the exception is properly handled by the try-except block

Question 7

What is the expected behavior of the following code?

  • A. it outputs 3
  • B. it outputs 'None'
  • C. it outputs 0
  • D. it raises an exception
Show answer and explanation ▾

Correct answer: A

The code converts 1/3 to a string using str(1/3), which in Python 3 produces '0.3333333333333333' (a float division result converted to string). The loop iterates through each character in this string, concatenating them into the dummy variable. After the loop completes, dummy contains the entire string. The print statement accesses dummy[-1], which is the last character of the string, which is '3'. Therefore, the output is 3.

Why the other options are wrong:

  • B. The str() function returns a string representation, not None, and the loop builds a concatenated string, not None.
  • C. The last character of '0.3333333333333333' is '3', not '0', so indexing with [-1] gives '3' not '0'.
  • D. The code is syntactically valid Python and executes without error; no exception is raised.

Question 8

What is the expected behavior of the following code? the_list = "alpha;beta;gamma".split(";") the_string = ''.join(the_list) print(the_string.isalpha())

  • A. it outputs True
  • B. it outputs False
  • C. it outputs nothing
  • D. it raises an exception
Show answer and explanation ▾

Correct answer: A

The code splits the string 'alpha;beta;gamma' by semicolon, producing ['alpha', 'beta', 'gamma']. The ''.join() method concatenates these without a separator, producing 'alphabetagamma'. The isalpha() method returns True if all characters in the string are alphabetic, and 'alphabetagamma' contains only letters, so the output is True.

Why the other options are wrong:

  • B. The joined string 'alphabetagamma' contains only alphabetic characters, so isalpha() returns True.
  • C. The code executes successfully and prints a result; it does not output nothing.
  • D. All operations are valid Python; no exception is raised.

Question 9

A property that stores information about a given class's super-classes is named:

  • A. __bases__
  • B. __super__
  • C. __upper__
  • D. __ancestors__
Show answer and explanation ▾

Correct answer: A

The __bases__ attribute is the correct Python property that stores information about a class's superclasses. It returns a tuple of the base classes from which a class is derived. The other options do not correspond to actual Python class properties.

Why the other options are wrong:

  • B. __super__ is not a valid Python class attribute for accessing superclasses.
  • C. __upper__ is not a valid Python class attribute.
  • D. __ancestors__ is not a valid Python class attribute.

Question 10

What is the expected behavior of the following code?

  • A. it outputs 1
  • B. it outputs 0
  • C. it raises an exception
  • D. it outputs 2
Show answer and explanation ▾

Correct answer: A

When a.doit() is called on the Sub_A instance, it executes Super's doit() method, which calls self.make(). Due to polymorphism, self refers to the Sub_A instance, so Sub_A's overridden make() method is called, returning 1. When b.doit() is called on the Sub_B instance, it executes Super's doit() method, which calls self.make(). Since Sub_B doesn't override make(), it uses Super's make() method, which returns 0. Therefore, 1 + 0 = 1 is printed.

Why the other options are wrong:

  • B. Sub_A's overridden make() method returns 1, not 0, so the sum cannot be 0.
  • C. No exception is raised; all methods exist and execute without error.
  • D. Sub_B inherits Super's make() which returns 0, not 1, so the sum is 1, not 2.

Question 11

What is the expected output of the following snippet?

  • A. False upper
  • B. True upper
  • C. False lower
  • D. True lower
Show answer and explanation ▾

Correct answer: B

The code creates an instance of the Lower class, which inherits from Upper. When Lower.__init__() is called, it invokes super().__init__(), which calls Upper.__init__() and sets self.property = 'upper'. The isinstance(Object, Lower) check returns True because Object is an instance of the Lower class (which inherits from Upper). Therefore, the output is 'True' followed by 'upper'.

Why the other options are wrong:

  • A. isinstance(Object, Lower) returns True, not False, because Object is created as an instance of Lower.
  • C. Object.property is set to 'upper' by the parent class Upper.__init__(), not 'lower'.
  • D. While isinstance(Object, Lower) is True, the property value is 'upper', not 'lower'.

Question 12

What is the expected behavior of the following code?

  • A. it raises an exception
  • B. it outputs 2
  • C. it outputs 0
  • D. it outputs 1
Show answer and explanation ▾

Correct answer: D

The code demonstrates the difference between class variables and instance variables in Python. `Variable = 0` is a class variable shared across all instances. When `object_1 = Class()` is created, `self.value = 0` creates an instance variable for object_1. Then `Class.Variable += 1` increments the class variable to 1. When `object_2 = Class()` is created, `self.value = 0` creates a separate instance variable for object_2. Finally, `object_2.Variable` accesses the class variable (since object_2 doesn't have its own Variable instance attribute), which equals 1, and `object_1.value` is 0 (the instance variable). Therefore, `1 + 0 = 1` is printed.

Why the other options are wrong:

  • A. The code is syntactically valid and runs without raising an exception.
  • B. The class variable is only incremented once (to 1), not twice, so the sum cannot be 2.
  • C. The class variable was explicitly incremented by 1, making it non-zero at the time of the print statement.

Question 13

What is the expected behavior of the following code?

  • A. it outputs 6
  • B. it raises an exception
  • C. it outputs 1
  • D. it outputs 3
Show answer and explanation ▾

Correct answer: D

The code demonstrates the difference between class variables and instance attributes. When `o1.foo()` is called, `Class._Class__Var` is incremented from 0 to 1, and `o1.__prop` is set to 1. When `o2.foo()` is called, `Class._Class__Var` is incremented from 1 to 2, and `o2.__prop` is set to 2. The final print statement accesses `o2._Class__Var` (which is 2) plus `o1.__prop` (which is 1), resulting in 2 + 1 = 3.

Why the other options are wrong:

  • A. The class variable reaches 2, not 6; the calculation 2 + 1 equals 3, not 6.
  • B. No exception is raised; the name mangling syntax is valid Python and the attribute access is correct.
  • C. The sum is 2 + 1 = 3, not 1; o2._Class__Var is 2 after two increments, not 1.

Question 14

What is the expected output of the following code? myli = range (-2,2) m = list(filter(lambda x: True if abs(x) < 1 else False, myli)) print(len(m))

  • A. 4
  • B. 1
  • C. an exception is raised
  • D. 16
Show answer and explanation ▾

Correct answer: B

range(-2, 2) produces the values [-2, -1, 0, 1]. The lambda function filters for values where abs(x) < 1, which is only true when x = 0 (since abs(-2)=2, abs(-1)=1, abs(0)=0, abs(1)=1). Therefore, m = [0], and len(m) = 1.

Why the other options are wrong:

  • A. The filter returns only one element (0), not four.
  • C. The code executes without raising an exception.
  • D. The length of the filtered list is 1, not 16.

Question 15

What is the expected behavior of the following code? x =3 % 1 y = 1 if x > 0 else 0 print(y)

  • A. the code is erroneus and it will not execute
  • B. it outputs 1
  • C. it outputs 0
  • D. it outputs -1
Show answer and explanation ▾

Correct answer: C

3 % 1 is 0 because 1 divides 3 exactly with no remainder, so x is 0. The conditional expression then tests x > 0, which is False, so y is assigned 0 and the program prints 0.

Why the other options are wrong:

  • A. Both the modulo operation and the conditional expression are valid, so the code runs normally.
  • B. y would only be 1 if x were greater than 0, but x is 0.
  • D. No operation in the code produces a negative value.

Question 16

What is the expected output of the following code if the file named zero_length_existing_file is a zero-length file located inside the working directory?

  • A. 2
  • B. -1
  • C. an errno value corresponding to file not found
  • D. 0
Show answer and explanation ▾

Correct answer: D

When reading from a zero-length file using readline(), the method returns an empty string because there is no data to read. The len() function applied to an empty string returns 0, which is then printed. The file exists and is accessible in the working directory, so no IOError exception is raised, and the code executes successfully through to completion, printing 0.

Why the other options are wrong:

  • A. readline() on a zero-length file returns an empty string, not a string of length 2.
  • B. The IOError exception is not triggered because the file exists and is readable; -1 would only print if an exception occurred.
  • C. No errno value is raised because the file exists in the working directory and can be opened without error.

Question 17

What is the expected output of the following code?

  • A. an exception is raised
  • B. 1
  • C. 0
  • D. -1
Show answer and explanation ▾

Correct answer: D

The code defines a function foo(x, y, z) that returns x(y) - x(z). The lambda function passed as x is 'lambda x: x % 2', which returns the remainder when x is divided by 2. When foo is called with this lambda, y=2, and z=1, it evaluates to: (2 % 2) - (1 % 2) = 0 - 1 = -1.

Why the other options are wrong:

  • A. No exception is raised; the syntax is valid and the lambda function executes successfully.
  • B. The calculation yields -1, not 1, since 2 % 2 equals 0 and 1 % 2 equals 1, giving 0 - 1.
  • C. The result is -1, not 0, because although 2 % 2 = 0, we must subtract 1 % 2 = 1 from it.

Question 18

What is the expected behavior of the following code? my_list = [i for i in range(5)] m = [my_list[i] for i in range(4, 0, -1) if my_list[i] % 2 != 0] print(m)

  • A. the code is erroneus and it will not execute
  • B. it outputs [4, 2, 0]
  • C. it outputs [3, 1]
  • D. it outputs [1, 3]
Show answer and explanation ▾

Correct answer: C

First, my_list = [0, 1, 2, 3, 4] from range(5). The list comprehension iterates with range(4, 0, -1), which produces [4, 3, 2, 1]. For each index i, it checks if my_list[i] % 2 != 0 (odd numbers). At i=4: my_list[4]=4 (even, skipped); i=3: my_list[3]=3 (odd, included); i=2: my_list[2]=2 (even, skipped); i=1: my_list[1]=1 (odd, included). The result is [3, 1].

Why the other options are wrong:

  • A. The code is syntactically correct and executes successfully.
  • B. The filter checks for odd numbers only, and it processes indices in reverse order [4,3,2,1], not forward.
  • D. The indices are processed in descending order [4,3,2,1], so 3 appears before 1 in the result.

Get the complete 31-03 bank

These 18 questions are roughly 29% of the bank. The full pack has 129 real 31-03 questions, each with the same depth of explanation, plus a questions-only PDF for timed practice and free updates forever.

View the full Python Institute PCAP 31-03 question bank →

Related exams

Browse free practice questions for every exam →

Back to blog