PCAP-31-03 — Python Institute PCAP - Certified Associate Python Programmer Quick Review
Quick Review for Python Institute PCAP-31-03 candidates: high-yield Python concepts, common traps, decision rules, and practice focus areas.
Quick Review purpose
This Quick Review is for candidates preparing for the Python Institute PCAP - Certified Associate Python Programmer (PCAP-31-03) exam from Python Institute. Use it as a final-pass review before moving into topic drills, mock exams, and detailed explanations.
This page is IT Mastery exam-prep support. It is not affiliated with Python Institute and does not replace the official exam syllabus or policies. Always verify registration rules, exam format, and current requirements with the official provider.
How to use this review efficiently
- Scan the tables first. They summarize the rules most likely to cause mistakes.
- Mark weak areas. Do not reread everything equally; target the rules you cannot explain quickly.
- Practice output prediction. Many Python exam questions reward exact reasoning about values, types, scope, mutation, and control flow.
- Use original practice questions immediately after review. The fastest improvement usually comes from topic drills with detailed explanations, not passive reading.
- Revisit mistakes by category. Track whether you missed syntax, object behavior, mutability, inheritance, exceptions, or standard-library behavior.
High-yield PCAP-31-03 review map
| Area | What to know cold | Common candidate mistake |
|---|---|---|
| Types and operators | Numeric operators, precedence, truthiness, comparison behavior | Confusing is with ==, or / with // |
| Control flow | if, loops, break, continue, loop else, nesting | Thinking loop else means “if condition was false” |
| Collections | Lists, tuples, dictionaries, sets, slicing, mutability | Forgetting list methods often mutate and return None |
| Strings | Indexing, slicing, immutability, methods, formatting basics | Expecting string methods to modify the original string |
| Functions | Parameters, return values, defaults, scope, *args, **kwargs | Using mutable default arguments unintentionally |
| Modules and packages | Import forms, namespaces, __name__, module search concepts | Not knowing what name is introduced by each import style |
| Exceptions | try, except, else, finally, raising exceptions, hierarchy | Catching broad exceptions before specific ones |
| Files | Open modes, text processing, context managers | Forgetting to close files or mishandling newline behavior |
| OOP | Classes, instances, attributes, methods, inheritance, overriding | Confusing class attributes with instance attributes |
| Iteration tools | Iterables, iterators, comprehensions, generators | Expecting a generator to restart automatically |
Python execution model and object basics
Python questions often test object behavior more than definitions.
| Concept | Review rule |
|---|---|
| Everything is an object | Values have identity, type, and value. |
| Assignment binds names | x = y makes x refer to the same object as y; it does not copy the object. |
| Mutability matters | Lists, dictionaries, and sets are mutable. Strings, tuples, numbers, and booleans are immutable. |
| Identity vs equality | is checks object identity; == checks value equality. |
| Namespaces | A name is resolved in a namespace; the same spelling can refer to different objects in different scopes. |
Identity, equality, and mutation traps
| Expression or pattern | Correct interpretation |
|---|---|
a == b | Do a and b have equal values? |
a is b | Are a and b the exact same object? |
b = a | b now refers to the same object as a. |
b = a[:] | For many sequences, creates a shallow copy. |
list1.append(x) | Mutates list1 and returns None. |
s.upper() | Returns a new string; s is unchanged. |
Quick check: if an operation mutates an object in place, be suspicious of assigning its return value. For example,
x = my_list.sort()makesxbecomeNone.
Operators, precedence, and expressions
Arithmetic and comparison rules
| Operator | Meaning | Trap |
|---|---|---|
+ | Addition or concatenation | Works differently by type; 1 + "1" is invalid. |
- | Subtraction or unary negative | Unary operators interact with exponentiation. |
* | Multiplication or sequence repetition | "ha" * 3 gives repeated string content. |
/ | True division | Result is a float. |
// | Floor division | Floors toward negative infinity, not toward zero. |
% | Modulo | Sign behavior follows Python’s floor-division relationship. |
** | Exponentiation | Right-associative: 2 ** 3 ** 2 means 2 ** (3 ** 2). |
==, != | Equality comparison | Do not confuse with identity checks. |
<, <=, >, >= | Ordering comparisons | Chained comparisons are evaluated mathematically. |
Boolean logic and truthiness
| Value | Truth value |
|---|---|
False, None | False |
0, 0.0 | False |
"", [], (), {}, set() | False |
| Most other objects | True |
Important rules:
andandorshort-circuit.andreturns the first falsy operand or the last operand.orreturns the first truthy operand or the last operand.notreturns a Boolean value.- Chained comparisons such as
a < b < care valid and do not mean(a < b) < c.
Operator precedence review
High-level order to remember:
- Parentheses and indexing/calls
- Exponentiation
- Unary
+,-,notwhere applicable - Multiplication, division, floor division, modulo
- Addition and subtraction
- Comparisons and membership/identity tests
- Boolean
and - Boolean
or
When in doubt, add parentheses mentally and test with small values in practice questions.
Control flow
if, elif, and else
| Pattern | Review point |
|---|---|
if condition: | Executes only if condition is truthy. |
elif condition: | Tested only if previous branches failed. |
else: | Executes when no earlier branch executed. |
Nested if | Indentation determines structure, not visual intention. |
Common trap: if x == 1 or 2: is almost always wrong because 2 is truthy. Use if x == 1 or x == 2: or if x in (1, 2):.
Loops
| Loop feature | Meaning |
|---|---|
while condition: | Repeats while condition is truthy. |
for item in iterable: | Iterates over items produced by iterable. |
break | Exits the nearest loop immediately. |
continue | Skips to the next iteration of the nearest loop. |
Loop else | Runs if the loop was not terminated by break. |
Loop else decision rule
Use this rule:
- If the loop finishes normally, the
elseblock runs. - If the loop exits by
break, theelseblock does not run. continuedoes not prevent the loopelsefrom running.
This is frequently misunderstood because loop else does not mean “the loop condition was false in the same way as an if statement.”
Collections: lists, tuples, dictionaries, and sets
Lists
Lists are ordered, mutable sequences.
| Operation | Result |
|---|---|
lst[i] | Element at index i |
lst[-1] | Last element |
lst[a:b] | Slice from a up to but not including b |
lst[a:b:c] | Slice with step c |
lst.append(x) | Adds one element at the end |
lst.extend(iterable) | Adds each item from iterable |
lst.insert(i, x) | Inserts before index i |
lst.pop() | Removes and returns last item |
lst.pop(i) | Removes and returns item at index i |
lst.remove(x) | Removes first matching value |
lst.sort() | Sorts in place and returns None |
sorted(lst) | Returns a new sorted list |
List slicing traps
| Slice | Meaning |
|---|---|
lst[:] | Shallow copy |
lst[::-1] | Reversed copy |
lst[:3] | First three elements |
lst[3:] | Elements from index 3 onward |
lst[-3:] | Last three elements |
lst[::2] | Every second element |
lst[5:1:-1] | Descending slice from index 5 down to above index 1 |
Remember: slicing tolerates out-of-range bounds more gracefully than direct indexing.
Tuples
Tuples are ordered and immutable, but they can contain mutable objects.
| Pattern | Meaning |
|---|---|
(1, 2, 3) | Tuple with three elements |
(1,) | One-element tuple |
(1) | Just the integer 1 |
tuple_obj[0] | Indexing works like lists |
tuple_obj[:] | Slicing works like lists |
Trap: tuple immutability means the tuple’s references cannot be changed, but a mutable object inside a tuple may still be mutated.
Dictionaries
Dictionaries store key-value pairs and preserve insertion order in modern Python versions.
| Operation | Review point |
|---|---|
d[key] | Returns value or raises KeyError if missing |
d.get(key) | Returns value or None if missing |
d.get(key, default) | Returns default if key missing |
d[key] = value | Adds or updates an entry |
del d[key] | Deletes key or raises KeyError |
key in d | Tests keys, not values |
d.keys() | View of keys |
d.values() | View of values |
d.items() | View of key-value pairs |
Dictionary traps:
- Keys must be hashable.
- Lists cannot be dictionary keys.
- Tuples can be keys only if all their elements are hashable.
inchecks keys by default.- Updating an existing key does not create a duplicate key.
Sets
Sets are unordered collections of unique hashable elements.
| Operation | Meaning |
|---|---|
set(iterable) | Creates a set from unique items |
| `a | b` |
a & b | Intersection |
a - b | Difference |
a ^ b | Symmetric difference |
x in s | Membership test |
s.add(x) | Adds one element |
s.remove(x) | Removes item or raises KeyError |
s.discard(x) | Removes item if present; no error if absent |
Trap: {} creates an empty dictionary, not an empty set. Use set() for an empty set.
Strings
Strings are immutable sequences of characters.
| Feature | Review point |
|---|---|
| Indexing | s[0], s[-1] work like sequence indexing. |
| Slicing | Returns a new string. |
| Immutability | You cannot assign to s[0]. |
| Methods | Most return new strings or other values. |
| Membership | "py" in "python" tests substring presence. |
String method review
| Method | Use |
|---|---|
s.lower() | New lowercase string |
s.upper() | New uppercase string |
s.strip() | Removes leading/trailing whitespace by default |
s.lstrip(), s.rstrip() | Remove from left or right |
s.find(sub) | Lowest index or -1 |
s.index(sub) | Lowest index or raises ValueError |
s.count(sub) | Counts non-overlapping occurrences |
s.replace(old, new) | Returns new string with replacements |
s.split(sep) | Returns list of substrings |
sep.join(iterable) | Joins strings using separator |
s.startswith(prefix) | Boolean result |
s.endswith(suffix) | Boolean result |
s.isalpha(), s.isdigit(), s.isspace() | Character classification checks |
String formatting basics
Know the difference between:
- Concatenation with
+ - Conversion with
str() - Format strings and placeholders
- f-string expression evaluation
Common trap: join() is called on the separator, not on the list. The pattern is ", ".join(items).
Functions
Defining and calling functions
| Feature | Review rule |
|---|---|
def name(...): | Creates a function object and binds it to a name. |
return value | Exits function and sends value back. |
| No explicit return | Function returns None. |
| Positional arguments | Matched by position. |
| Keyword arguments | Matched by parameter name. |
| Default parameters | Used when caller omits that argument. |
*args | Collects extra positional arguments as a tuple. |
**kwargs | Collects extra keyword arguments as a dictionary. |
Argument-order rule
A safe ordering model:
- Positional parameters
- Defaulted parameters
*args- Keyword-only parameters, if used
**kwargs
When calling a function:
- Positional arguments generally come before keyword arguments.
- Do not provide the same parameter twice.
- A required parameter must receive a value.
- Keyword names must match parameter names unless captured by
**kwargs.
Default argument trap
Default argument expressions are evaluated once when the function is defined, not each time it is called.
| Pattern | Risk |
|---|---|
def f(x, items=[]): | The same list may be reused across calls. |
def f(x, items=None): | Safer pattern; create a new list inside if needed. |
This is a classic exam and interview trap because the code may appear to “remember” values between calls.
Scope and name resolution
Python uses the LEGB rule:
| Level | Meaning |
|---|---|
| Local | Names assigned inside the current function |
| Enclosing | Names in enclosing function scopes |
| Global | Names at module level |
| Built-in | Python built-in names |
Important scope rules:
- Reading a global name from inside a function is allowed.
- Assigning to a name inside a function normally makes it local.
- If a local assignment exists, reading that name before assignment can cause
UnboundLocalError. globaltells Python that assignment should target the module-level name.nonlocaltargets a name in an enclosing function scope.
Lambda, higher-order functions, and comprehensions
| Feature | Review point |
|---|---|
lambda | Creates a small anonymous function with one expression. |
map() | Applies a function to items; returns an iterator. |
filter() | Keeps items for which function is truthy; returns an iterator. |
| List comprehension | Builds a list from an expression and iterable. |
| Generator expression | Lazy expression; produces items as needed. |
Candidate trap: in Python 3, functions such as map() and filter() produce iterators, not lists. If a question expects a list, conversion may be needed with list(...).
Modules, packages, and imports
Import forms
| Import statement | Name available afterward |
|---|---|
import math | math |
import math as m | m |
from math import sqrt | sqrt |
from math import sqrt as s | s |
from math import * | Many public names; avoid in production-style reasoning |
Import traps
| Trap | Correct understanding |
|---|---|
import module vs from module import name | The first imports the module name; the second imports a specific object name. |
| Aliasing | After import math as m, use m.sqrt(...), not math.sqrt(...) unless math was also imported. |
| Namespace pollution | from module import * can overwrite existing names and reduce clarity. |
| Module execution | Top-level module code executes when imported. |
| Repeated imports | Modules are cached after import in normal execution. |
__name__ and script behavior
The variable __name__ is:
"__main__"when the file is run directly.- The module’s name when imported.
Common pattern: if __name__ == "__main__": guards code that should run only when the module is executed as a script, not when imported.
Packages
A package organizes modules in directories. Review:
- Absolute vs relative import concepts.
- Why namespaces prevent name collisions.
- How package structure affects import paths.
- The role of module search paths at a conceptual level.
Do not spend all your review time memorizing obscure package mechanics. For PCAP-style readiness, prioritize understanding what names are available after imports and how module code executes.
Selected standard-library areas to recognize
| Module | Common purpose |
|---|---|
math | Mathematical functions and constants |
random | Pseudorandom choices and numbers |
datetime | Dates and times |
os | Operating-system interactions |
sys | Interpreter-related values and functions |
platform | Platform information |
json | JSON serialization and parsing |
Practice questions often test whether you recognize the purpose and basic use pattern of standard modules rather than deep memorization of every function.
Exceptions
Exception flow
| Construct | Meaning |
|---|---|
try | Code that may raise an exception |
except SomeError | Handles a matching exception |
except | Broad catch; should usually come last |
else | Runs if no exception occurred in try |
finally | Runs regardless of whether an exception occurred |
raise | Raises an exception |
assert condition | Raises AssertionError if condition is false |
Exception-order rule
Put specific exception handlers before general ones.
| Better order | Why |
|---|---|
except ValueError: before except Exception: | Specific handler gets a chance to run. |
| Broad handler first | Makes later specific handlers unreachable or ineffective. |
try / except / else / finally decision table
| Situation | except runs? | else runs? | finally runs? |
|---|---|---|---|
No exception in try | No | Yes | Yes |
Exception handled by matching except | Yes | No | Yes |
| Exception not handled | No matching handler | No | Yes, then exception propagates |
return inside try | Maybe not | Depends on flow | Yes before function exits |
Important: finally is for cleanup logic. It runs even when control flow is leaving the block.
Common built-in exceptions
| Exception | Typical cause |
|---|---|
ValueError | Correct type, invalid value |
TypeError | Operation or function used with inappropriate type |
IndexError | Sequence index out of range |
KeyError | Missing dictionary key |
ZeroDivisionError | Division or modulo by zero |
FileNotFoundError | File path cannot be found |
AttributeError | Attribute does not exist |
NameError | Name is not defined |
UnboundLocalError | Local variable referenced before assignment |
ImportError / ModuleNotFoundError | Import problem |
AssertionError | Failed assertion |
Files and input/output
File-opening basics
| Mode | Meaning |
|---|---|
"r" | Read text file |
"w" | Write text file; truncates existing file |
"a" | Append text |
"x" | Create new file; fail if it exists |
"b" | Binary mode modifier |
"t" | Text mode modifier |
"+" | Updating: reading and writing |
Use context managers when possible: with open(...) as f: ensures the file is closed after the block.
File method review
| Method | Use |
|---|---|
read() | Reads entire file or specified size |
readline() | Reads one line |
readlines() | Reads all lines into a list |
| Iterating over file object | Reads line by line |
write(text) | Writes string and returns number of characters written |
writelines(iterable) | Writes strings from iterable; does not automatically add newlines |
close() | Closes the file |
Common traps:
- Opening with
"w"can erase existing content. read()consumes from the current file position.- Newline characters may remain when reading lines.
- Text mode expects strings; binary mode expects bytes-like objects.
writelines()does not insert separators or newline characters for you.
Object-oriented programming
Class and object fundamentals
| Term | Meaning |
|---|---|
| Class | Blueprint for objects |
| Object / instance | A concrete object created from a class |
| Attribute | Data associated with an object or class |
| Method | Function associated with a class |
self | Conventional name for the current instance |
| Constructor initializer | __init__ initializes a new instance after creation |
Instance vs class attributes
| Attribute type | Where stored | Shared? |
|---|---|---|
| Instance attribute | On each object | No |
| Class attribute | On the class | Yes, unless shadowed by instance attribute |
Candidate trap: mutable class attributes can be shared by all instances. If each object needs its own list, create it as an instance attribute inside __init__.
Methods and binding
| Method pattern | Review point |
|---|---|
| Instance method | First parameter receives the instance, conventionally self. |
Calling obj.method() | Python passes obj as the first argument automatically. |
Calling Class.method(obj) | Equivalent explicit style for many instance methods. |
Missing self | Common cause of argument-count errors. |
Encapsulation conventions
Python uses conventions more than strict access controls.
| Name style | Convention |
|---|---|
name | Public |
_name | Internal-use convention |
__name | Name-mangled to reduce accidental collision in subclasses |
__name__ | Special “dunder” method or attribute |
Do not describe Python’s underscores as absolute privacy. They are primarily conventions and name-mangling mechanisms.
Inheritance and overriding
| Concept | Review point |
|---|---|
| Inheritance | A subclass can reuse and extend superclass behavior. |
| Override | Subclass defines a method with the same name as superclass method. |
super() | Accesses superclass behavior according to method resolution rules. |
isinstance(obj, Class) | Tests whether object is instance of class or subclass. |
issubclass(Sub, Base) | Tests class inheritance relationship. |
Inheritance decision points
Ask these questions when reading OOP code:
- Which class is used to create the object?
- Does the instance have the attribute directly?
- If not, does the class have it?
- If not, is it inherited from a superclass?
- If a method is called, which override is found first?
- Does the method call
super()and continue the chain?
Special methods
| Method | Purpose |
|---|---|
__init__ | Initialize instance state |
__str__ | User-friendly string representation |
__repr__ | Developer-oriented representation |
__len__ | Supports len(obj) |
__eq__ | Supports equality comparison |
__lt__ | Supports less-than comparison |
__iter__ | Supports iteration |
__next__ | Produces next item for iterator protocol |
Know the pattern: Python syntax and built-in functions often call special methods behind the scenes.
Iteration, iterators, and generators
| Concept | Review point |
|---|---|
| Iterable | Object that can produce an iterator |
| Iterator | Object with __next__() behavior |
iter(obj) | Gets an iterator |
next(iterator) | Gets next value or raises StopIteration |
| Generator function | Function using yield |
| Generator object | Lazy iterator produced by calling a generator function |
Generator traps
- A generator does not execute its body until iteration begins.
- Values are produced one at a time.
- Once exhausted, a generator does not restart automatically.
returninside a generator ends iteration.yieldpauses function state between values.
Comprehensions
| Form | Produces |
|---|---|
[expr for x in iterable] | List |
{expr for x in iterable} | Set |
{k: v for x in iterable} | Dictionary |
(expr for x in iterable) | Generator expression |
Review filter placement:
[x for x in nums if x > 0]keeps only positive values.[x * 2 for x in nums]transforms every value.[x * 2 for x in nums if x > 0]filters first by theif, then transforms kept values.
Nested comprehensions are easy to misread. Translate them into ordinary loops if needed.
Common PCAP-31-03 mistake patterns
Syntax and indentation
| Mistake | Correction |
|---|---|
Missing colon after if, for, while, def, class, try, except | Compound statements need :. |
| Incorrect indentation | Blocks are defined by indentation. |
| Mixing tabs and spaces | Avoid; can produce indentation errors. |
| Assuming braces define blocks | Python uses indentation, not braces. |
Type and conversion mistakes
| Mistake | Correction |
|---|---|
| Adding string and integer directly | Convert explicitly with str() or int() as appropriate. |
Expecting input() to return a number | input() returns a string. |
Confusing list("abc") with ["abc"] | The first gives individual characters. |
Expecting bool("False") to be false | Non-empty strings are truthy. |
Mutability mistakes
| Mistake | Correction |
|---|---|
| Thinking assignment copies a list | Assignment binds another name to the same list. |
| Expecting slicing to deep-copy nested lists | Slicing creates a shallow copy. |
| Using mutable default arguments | Use None and create inside function. |
| Sorting a list and assigning the result | list.sort() returns None; use sorted() for a new list. |
Scope mistakes
| Mistake | Correction |
|---|---|
Assigning to global name inside function without global | Creates a local name by default. |
| Reading local before assignment | Can raise UnboundLocalError. |
Shadowing built-ins like list or str | Avoid using built-in names as variables. |
Exception mistakes
| Mistake | Correction |
|---|---|
Catching Exception before ValueError | Put specific handlers first. |
Assuming finally runs only on errors | It runs regardless. |
Assuming else runs after an exception is handled | else runs only if no exception occurred in try. |
Quick decision rules for exam questions
Use these fast checks when answering code-based questions.
| If the question involves… | Ask yourself… |
|---|---|
| Assignment | Are two names pointing to the same object? |
| A list or dictionary | Is it being mutated in place? |
| A method call | Does this method return a value or mutate and return None? |
| A function | What is returned if no return executes? |
| Defaults | Was the default object created once at definition time? |
| Scope | Is the name local, enclosing, global, or built-in? |
| Imports | Which exact name is available after the import statement? |
| Exceptions | Which handler matches first? Does finally run? |
| Inheritance | Which method or attribute is found first? |
| Iterators | Has the iterator already been consumed? |
| Strings | Is a new string returned rather than modifying the original? |
| Dictionaries | Is membership checking keys or values? |
Mini review: output-prediction checklist
Before choosing an answer, walk through the code in this order:
- Parse the structure. Check indentation, blocks, and function/class definitions.
- Identify object creation. Lists, dictionaries, objects, iterators, and generators may carry state.
- Track name binding. Assignment changes what a name refers to.
- Track mutation. In-place operations affect all references to the same mutable object.
- Resolve scope. Apply LEGB for every non-obvious name.
- Follow control flow. Include
break,continue,return, exceptions, andfinally. - Check return values. Many methods return
Noneeven though they changed an object. - Confirm final type. A correct-looking value with the wrong type may still be wrong.
Practice priorities before the real exam
After this Quick Review, use a question bank with original practice questions, topic drills, and detailed explanations. Prioritize practice in this order if time is short:
| Priority | Practice focus | Why it matters |
|---|---|---|
| 1 | Output prediction with lists, dictionaries, functions, and scope | High error rate and easy to underestimate |
| 2 | Exceptions and file handling | Tests exact control flow and cleanup behavior |
| 3 | OOP inheritance and attributes | Requires methodical lookup reasoning |
| 4 | Modules and imports | Small syntax differences change available names |
| 5 | Strings and slicing | Many questions hide off-by-one or immutability traps |
| 6 | Iterators, generators, comprehensions | Lazy evaluation and exhaustion can surprise candidates |
Final readiness check
You are closer to ready for PCAP-31-03 when you can:
- Explain the difference between equality and identity.
- Predict the result of list mutation through multiple references.
- Trace function calls with positional, keyword, default,
*args, and**kwargs. - Apply LEGB without guessing.
- Explain when loop
else,tryelse, andfinallyexecute. - Identify what each import form makes available.
- Distinguish class attributes from instance attributes.
- Follow inheritance and method overriding.
- Read and reason about file modes and common file methods.
- Solve timed original practice questions without relying on trial-and-error execution.
Practical next step
Move from review into IT Mastery practice: start with targeted topic drills for your weakest areas, then take mixed mock exams and study the detailed explanations for every missed or guessed question.
Continue in IT Mastery
Use this Quick Review as a final concept map, then move into IT Mastery for focused topic drills, mixed practice sets, timed mock exams, and detailed explanations. The practice questions are original IT Mastery practice items; they are not official Python Institute questions, copied live-exam content, or exam dumps.