PCAP-31-03 — Python Institute PCAP - Certified Associate Python Programmer Quick Reference

Compact PCAP-31-03 review of Python syntax, data structures, functions, modules, exceptions, OOP, files, and common exam traps.

Quick Reference scope

This Quick Reference supports candidates preparing for the Python Institute PCAP - Certified Associate Python Programmer (PCAP-31-03) exam. It focuses on Python 3 concepts commonly tested at associate level: control flow, data aggregates, functions, modules, packages, strings, exceptions, files, generators, and object-oriented programming.

Use it as a compact review aid, not as a substitute for hands-on practice. PCAP-style questions often test exact runtime behavior, not just definitions.

High-yield exam mindset

If the question asks…Track this firstCommon trap
“What is printed?”Current values, aliases, mutation, exception flowAssuming methods return modified objects
List/dict/set behaviorWhether object is mutated in placeConfusing shallow copy with deep copy
Function outputArgument binding, scope, default valuesMutable default argument reused
Class behaviorInstance vs class attributes, method resolutionReading self.x as always instance-only
Exception flowFirst matching except, else, finallyfinally can run even after return
String methodsStrings are immutableMethods return new strings
Import questionsNamespace created by each import formimport module vs from module import name
Generator questionsLazy execution and StopIterationThinking generator body runs at creation

Core syntax and runtime rules

Truthiness and boolean logic

Value/typeFalse whenNotes
NoneAlways falseSingleton; compare with is None
boolFalsebool is a subclass of int
NumbersZero0, 0.0, 0j are false
StringsEmpty string ""Non-empty strings are true, even "False"
Lists, tuples, sets, dictsEmptyNon-empty containers are true
Custom objectsUsually trueCan define __bool__() or __len__()
print(bool("0"))     # True
print(bool([]))      # False
print(True + True)   # 2

Operators most likely to matter

OperatorMeaningExam notes
+, -, *Arithmetic; also sequence operations"a" * 3 == "aaa"
/True divisionAlways returns float
//Floor divisionFloors toward negative infinity
%RemainderSign follows divisor in Python
**ExponentiationRight-associative
andBoolean ANDReturns an operand, not forced bool
orBoolean ORReturns an operand
notBoolean negationAlways returns bool
isIdentitySame object, not same value
==EqualityValue comparison
inMembershipWorks on sequences, sets, dict keys
&, `, ^, ~`Bitwise operations
print(2 ** 3 ** 2)   # 512, because 2 ** (3 ** 2)
print(-7 // 3)       # -3
print(-7 % 3)        # 2
print("x" or 5)      # x
print("" or 5)       # 5

Operator precedence checkpoints

Higher to lowerExamples
Parentheses, indexing, callsf(x), a[i]
Exponentiation**
Unary+x, -x, not x has lower precedence than comparisons
Multiplicative*, /, //, %
Additive+, -
Comparisons<, <=, >, >=, ==, !=, is, in
Booleannot, then and, then or
print(1 < 2 < 3)       # True
print(1 < 2 > 3)       # False
print(not 1 == 1)      # False, parsed as not (1 == 1)

Control flow reference

if, loops, and loop else

ConstructRuns whenTrap
ifCondition truthyAssignment is not expression syntax in classic if usage
elifPrevious conditions false, this one trueOnly one branch runs
else after ifNo condition matchedNot related to exceptions
whileRepeats while condition truthyMay never run
forIterates over iterableDoes not require numeric index
Loop elseLoop ended normallySkipped if break occurred
breakExits nearest loopSkips loop else
continueNext iterationDoes not exit loop
for x in [1, 2, 3]:
    if x == 4:
        break
else:
    print("not found")     # prints

range() behavior

ExpressionValues
range(5)0, 1, 2, 3, 4
range(2, 5)2, 3, 4
range(5, 2, -1)5, 4, 3
range(2, 5, -1)Empty

Key rules:

  • Stop value is excluded.
  • Step cannot be zero.
  • range is iterable and lazy-like; convert to list() only if needed.

Built-in data types

Type comparison table

TypeMutable?Ordered/indexed?Allows duplicates?Literal
strNoYesYes"abc"
listYesYesYes[1, 2]
tupleNoYesYes(1, 2)
dictYesBy keyKeys unique{"a": 1}
setYesNoNo{1, 2}
frozensetNoNoNofrozenset({1, 2})

Mutability and aliasing

a = [1, 2]
b = a
b.append(3)
print(a)        # [1, 2, 3]

c = a[:]
c.append(4)
print(a)        # [1, 2, 3]
print(c)        # [1, 2, 3, 4]
OperationResult
b = aNew reference to same object
a[:]Shallow copy for list
list(a)Shallow copy
copy.copy(a)Shallow copy
copy.deepcopy(a)Recursive copy of nested objects

Trap: shallow copies still share nested mutable objects.

x = [[1], [2]]
y = x[:]
y[0].append(99)
print(x)        # [[1, 99], [2]]

Lists

List operations

OperationMeaningMutates?Return value
lst.append(x)Add one item at endYesNone
lst.extend(iterable)Add many itemsYesNone
lst.insert(i, x)Insert before indexYesNone
lst.remove(x)Remove first matching valueYesNone
lst.pop()Remove and return last itemYesRemoved item
lst.pop(i)Remove and return item at indexYesRemoved item
lst.clear()Remove all itemsYesNone
lst.sort()Sort in placeYesNone
sorted(lst)Return sorted listNoNew list
lst.reverse()Reverse in placeYesNone
reversed(lst)Return reverse iteratorNoIterator
nums = [3, 1, 2]
print(nums.sort())    # None
print(nums)           # [1, 2, 3]

Slicing reference

ExpressionMeaning
s[start:stop]From start up to but not including stop
s[:stop]From beginning to stop - 1
s[start:]From start to end
s[:]Shallow copy
s[::step]Every step item
s[::-1]Reversed copy
s = [0, 1, 2, 3, 4]
print(s[1:4])     # [1, 2, 3]
print(s[-1])      # 4
print(s[::-1])    # [4, 3, 2, 1, 0]

List comprehension pattern

squares = [x * x for x in range(5)]
evens = [x for x in range(10) if x % 2 == 0]
pairs = [(x, y) for x in [1, 2] for y in [3, 4]]

Evaluation order for nested comprehension:

result = []
for x in [1, 2]:
    for y in [3, 4]:
        result.append((x, y))

Tuples

ExpressionResult
(1, 2, 3)Tuple
1, 2, 3Tuple by comma
(1)Integer 1
(1,)One-element tuple
tuple([1, 2])(1, 2)

Tuples are immutable, but they can contain mutable objects.

t = ([1, 2], 3)
t[0].append(99)
print(t)        # ([1, 2, 99], 3)

Dictionaries

Dictionary essentials

OperationMeaning
d[k]Get value; raises KeyError if missing
d.get(k)Get value or None
d.get(k, default)Get value or default
d[k] = vAdd or replace
del d[k]Delete key; raises KeyError if missing
k in dTests keys, not values
d.keys()Dynamic view of keys
d.values()Dynamic view of values
d.items()Dynamic view of (key, value) pairs
d.update(other)Merge/update in place
d = {"a": 1, "b": 2}
print("a" in d)        # True
print(1 in d)          # False

Dictionary traps

TrapCorrect understanding
Keys can be listsFalse; keys must be hashable
in checks valuesFalse; checks keys
d.get(k) raises if missingFalse; returns default
dict.keys() is a listFalse; it is a view object
Duplicate literal keys remain duplicatedFalse; later value wins
d = {"x": 1, "x": 2}
print(d)        # {'x': 2}

Sets

OperationMeaning
`abora.union(b)`
a & b or a.intersection(b)Intersection
a - b or a.difference(b)Difference
a ^ b or a.symmetric_difference(b)In one set but not both
a.add(x)Add item
a.remove(x)Remove; raises KeyError if missing
a.discard(x)Remove if present; no error if missing
a.pop()Remove arbitrary item
a = {1, 2, 3}
b = {3, 4}
print(a & b)    # {3}
print(a | b)    # {1, 2, 3, 4}

Trap: {} creates an empty dictionary, not an empty set. Use set().

Strings

String fundamentals

FeatureRule
MutabilityStrings are immutable
IndexingSame indexing and slicing rules as sequences
Concatenation+ creates a new string
Repetition"ab" * 3 gives "ababab"
Membership"x" in "xyz"
ComparisonLexicographic by Unicode code points
s = "Python"
print(s[0])       # P
print(s[-1])      # n
print(s[1:4])     # yth

High-yield string methods

MethodUseTrap
s.lower() / s.upper()Case conversionReturns new string
s.strip()Remove surrounding whitespaceNot middle whitespace
s.strip(chars)Remove any listed chars from endschars is a set of characters, not substring
s.find(sub)Index or -1No exception if missing
s.index(sub)IndexRaises ValueError if missing
s.replace(old, new)Return replaced copyOriginal unchanged
s.split(sep)String to listDefault splits on whitespace
sep.join(iterable)List of strings to one stringSeparator is the caller
s.startswith(x)Prefix testReturns bool
s.endswith(x)Suffix testReturns bool
s.isalpha()All alphabetic and non-emptyEmpty string returns False
s.isdigit()All digits and non-emptyEmpty string returns False
s.isalnum()Alphabetic or digit and non-emptyEmpty string returns False
s.isspace()All whitespace and non-emptyEmpty string returns False
print("www.example.com".strip("w.com"))  # example
print("a,b,c".split(","))                # ['a', 'b', 'c']
print("-".join(["a", "b", "c"]))         # a-b-c

Character codes

FunctionMeaning
ord("A")Unicode code point integer
chr(65)Character for code point
print(ord("A"))    # 65
print(chr(65))     # A
print("A" < "a")   # True

Functions

Function definition and call binding

ConceptExampleNotes
Positional parameterdef f(a, b):Matched by position
Default parameterdef f(a=1):Evaluated once at definition time
Keyword argumentf(a=3)Name-based binding
Variadic positionaldef f(*args):args is a tuple
Variadic keyworddef f(**kwargs):kwargs is a dict
Return valuereturn xWithout return, returns None
def f(a, b=2, *args, **kwargs):
    print(a, b, args, kwargs)

f(1, 3, 4, 5, x=9)    # 1 3 (4, 5) {'x': 9}

Argument passing

Python uses object references. Mutating a passed mutable object affects the caller’s object; rebinding the local name does not.

def change(a, b):
    a.append(3)
    b = [9]

x = [1, 2]
y = [4]
change(x, y)
print(x)     # [1, 2, 3]
print(y)     # [4]

Mutable default argument trap

def add_item(x, bucket=[]):
    bucket.append(x)
    return bucket

print(add_item(1))    # [1]
print(add_item(2))    # [1, 2]

Safer pattern:

def add_item(x, bucket=None):
    if bucket is None:
        bucket = []
    bucket.append(x)
    return bucket

Scope: LEGB

LevelMeaningExample
LocalInside current functionAssignment creates local unless declared
EnclosingOuter nested function scopeUsed by closures
GlobalModule-level nameglobal can rebind
Built-inPython built-inslen, print, Exception
x = 10

def f():
    x = 20
    print(x)

f()             # 20
print(x)        # 10

global and nonlocal

x = 1

def set_global():
    global x
    x = 2

def outer():
    y = 10
    def inner():
        nonlocal y
        y = 20
    inner()
    return y

set_global()
print(x)          # 2
print(outer())    # 20
KeywordRebinds name inCannot create
globalModule scopeLocal-only rebinding
nonlocalNearest enclosing function scopeNew outer variable

Lambda, map, filter, sorted

nums = [3, 1, 2]

print(list(map(lambda x: x * 2, nums)))        # [6, 2, 4]
print(list(filter(lambda x: x > 1, nums)))     # [3, 2]
print(sorted(nums, key=lambda x: -x))          # [3, 2, 1]
ConstructReturnsExam note
lambda x: exprFunction objectExpression only, no statements
map(func, iterable)IteratorConvert with list() for display
filter(func, iterable)IteratorKeeps truthy results
sorted(iterable)New listDoes not mutate original
list.sort()NoneMutates list

Iterables, iterators, and generators

Iterable vs iterator

TermMeaning
IterableObject usable in for, provides iter()
IteratorObject with __next__(), remembers position
iter(obj)Returns iterator
next(iterator)Returns next item or raises StopIteration
items = [1, 2]
it = iter(items)
print(next(it))     # 1
print(next(it))     # 2

Generators

A generator function contains yield. Calling it returns a generator object; the body runs when iteration starts.

def gen():
    print("start")
    yield 1
    yield 2

g = gen()
print("created")
print(next(g))

Output:

created
start
1

yield vs return

StatementIn normal functionIn generator function
return valueEnds function and returns valueEnds generator; value becomes StopIteration detail
yield valueSyntax invalid outside generator contextPauses and emits value

Modules and packages

Import forms

SyntaxWhat name becomes available?Usage
import mathmathmath.sqrt(9)
import math as mmm.sqrt(9)
from math import sqrtsqrtsqrt(9)
from math import sqrt as sss(9)
from math import *Many public namesAvoid in real code; namespace collisions
import math
from random import randint

print(math.pi)
print(randint(1, 6))

Trap:

import math
print(sqrt(9))       # NameError

Correct:

import math
print(math.sqrt(9))

Module execution and __name__

Situation__name__ value
File run as script"__main__"
File imported as moduleModule name
def main():
    print("run directly")

if __name__ == "__main__":
    main()

Use this pattern to prevent script-only code from running on import.

Module search and packages

ItemMeaning
ModuleSingle .py file or built-in/extension module
PackageDirectory-based module grouping
sys.pathSearch locations for imports
__init__.pyPackage initialization file in traditional packages
dir(module)Inspect names in a module
help(obj)Interactive documentation aid
import sys
print(sys.path)

Common standard modules

ModuleTypical use
mathDeterministic math functions, constants
randomPseudorandom choices and numbers
platformRuntime/platform information
sysInterpreter/system interaction
osOperating system interfaces
datetimeDates and times
timeTime-related functions

Avoid assuming exact platform output in exam questions unless it is explicitly given.

Package management concepts

TermMeaning
pipPython package installer
PyPIPublic package index
Virtual environmentIsolated package environment
DependencyPackage required by another package

Exam emphasis is usually conceptual: know what package installation and isolation are for.

Exceptions

Basic flow

try:
    risky()
except ValueError:
    print("bad value")
except Exception as exc:
    print("other problem", exc)
else:
    print("no exception")
finally:
    print("always considered")
ClauseRuns when
tryProtected code block
exceptMatching exception raised in try
elseNo exception occurred in try
finallyAfter try/except/else, even during return or raise

Exception matching rules

RuleImpact
First matching except winsPut specific exceptions before general ones
Subclasses match parent handlersexcept Exception catches many ordinary errors
BaseException is broader than ExceptionUsually not used for application errors
Bare except: catches almost everythingDangerous in real code
Multiple exceptions can be groupedexcept (ValueError, TypeError):
try:
    int("x")
except Exception:
    print("general")
except ValueError:
    print("value")       # unreachable

Common built-in exceptions

ExceptionTypical cause
SyntaxErrorInvalid Python syntax
IndentationErrorInvalid indentation
NameErrorName not defined
TypeErrorOperation on inappropriate type
ValueErrorCorrect type, invalid value
IndexErrorSequence index out of range
KeyErrorMissing dictionary key
ZeroDivisionErrorDivision/modulo by zero
AttributeErrorMissing attribute
ImportErrorImport failed
ModuleNotFoundErrorModule cannot be found
FileNotFoundErrorFile path not found
AssertionErrorFailed assert

Raising and re-raising

raise ValueError("bad input")

Inside an except block:

try:
    int("x")
except ValueError:
    print("logging")
    raise
FormMeaning
raise SomeException()Raise a new exception
raise SomeExceptionInstantiate and raise exception class
raiseRe-raise current exception inside handler

assert

assert x > 0, "x must be positive"
FeatureMeaning
RaisesAssertionError if condition is false
PurposeDebugging/sanity checks
TrapDo not use as primary user-input validation in production reasoning

Custom exceptions

class InvalidScoreError(Exception):
    pass

def check(score):
    if score < 0:
        raise InvalidScoreError("negative score")

Best exam answer: custom exceptions usually inherit from Exception, not directly from BaseException.

File processing

open() modes

ModeMeaningExisting file behavior
"r"Read textError if missing
"w"Write textTruncates or creates
"a"Append textCreates if missing
"x"Exclusive createError if exists
"b"Binary modifierUse with other modes, e.g. "rb"
"t"Text modifierDefault
"+"Read/write modifierCombines reading and writing
with open("data.txt", "r", encoding="utf-8") as f:
    content = f.read()

File method reference

MethodMeaning
read()Read entire remaining file
read(n)Read up to n characters/bytes
readline()Read one line
readlines()Read all lines into list
write(s)Write string; returns count written
writelines(iterable)Write strings without adding separators
close()Close file
seek(pos)Move file position
tell()Current file position

with statement

Use context managers to guarantee cleanup.

with open("out.txt", "w", encoding="utf-8") as f:
    f.write("hello\n")

Exam trap: writelines(["a", "b"]) writes ab, not a\nb\n.

Object-oriented programming

Class and instance basics

class Dog:
    species = "canine"          # class attribute

    def __init__(self, name):
        self.name = name        # instance attribute

    def speak(self):
        return self.name + " says woof"

d = Dog("Rex")
print(d.name)
print(d.speak())
ElementMeaning
class Dog:Defines a class object
__init__Initializer called after object creation
selfConventional name for current instance
Instance attributeStored per object, usually self.x
Class attributeStored on class, shared lookup by instances
MethodFunction defined in class, bound to instance when called

Instance vs class attributes

class C:
    x = 1

a = C()
b = C()

a.x = 2
print(a.x)    # 2
print(b.x)    # 1
print(C.x)    # 1
AccessLookup behavior
obj.attrInstance first, then class, then base classes
Class.attrClass, then base classes
obj.attr = valueCreates/replaces instance attribute
Class.attr = valueCreates/replaces class attribute

Mutable class attribute trap:

class Bag:
    items = []

a = Bag()
b = Bag()
a.items.append("x")
print(b.items)       # ['x']

Methods

Method typeFirst parameterCalled asUse
Instance methodselfobj.method()Work with instance state
Class methodclsClass.method() or obj.method()Work with class state/constructors
Static methodNone automaticClass.method() or obj.method()Utility grouped in class
class Example:
    count = 0

    def inst(self):
        return self

    @classmethod
    def cls_method(cls):
        return cls.count

    @staticmethod
    def util(x):
        return x * 2

Encapsulation and name mangling

Name formMeaning
namePublic by convention
_nameNon-public by convention
__nameName-mangled to reduce accidental override
__name__Special “dunder” method/attribute
class A:
    def __init__(self):
        self.__x = 1

a = A()
## a.__x        # AttributeError
print(a._A__x) # 1, name-mangled form

PCAP-style trap: double underscores do not make true private attributes; they trigger name mangling.

Inheritance and overriding

class Animal:
    def speak(self):
        return "sound"

class Dog(Animal):
    def speak(self):
        return "woof"

print(Dog().speak())       # woof
ConceptMeaning
InheritanceChild class reuses/extends parent class
OverrideChild defines same method name
PolymorphismSame interface, different class behavior
super()Access parent behavior through method resolution order
isinstance(obj, Class)Object is instance of class or subclass
issubclass(Sub, Base)Class inheritance test
class Parent:
    def __init__(self, x):
        self.x = x

class Child(Parent):
    def __init__(self, x, y):
        super().__init__(x)
        self.y = y

Multiple inheritance and MRO

class A:
    def f(self): return "A"

class B(A):
    def f(self): return "B"

class C(A):
    def f(self): return "C"

class D(B, C):
    pass

print(D().f())      # B
print(D.__mro__)

Method Resolution Order searches classes in a deterministic order. For class D(B, C), B is searched before C.

Special methods

MethodUsed byExample
__init__Initializationobj = C()
__str__User-friendly stringstr(obj), print(obj)
__repr__Developer-oriented representationrepr(obj)
__len__Length/truthiness fallbacklen(obj)
__eq__Equalityobj1 == obj2
__lt__Less-than comparisonobj1 < obj2
__add__Addition operatorobj1 + obj2
__iter__Iterationfor x in obj
__next__Iterator next itemnext(obj)
class Point:
    def __init__(self, x):
        self.x = x

    def __str__(self):
        return f"Point({self.x})"

print(Point(3))     # Point(3)

Common built-ins and conversions

Built-inPurposeTrap
len(x)LengthRequires object supporting length
type(x)Exact type objectFor inheritance checks, prefer isinstance
isinstance(x, T)Type/subtype checkWorks with tuple of types
id(x)Object identity integerNot value equality
int(x)Convert to integerCan raise ValueError
float(x)Convert to floatCan raise ValueError
str(x)Convert to stringCalls string conversion
list(x)Convert iterable to listConsumes iterators
tuple(x)Convert iterable to tupleConsumes iterators
set(x)Unique unordered collectionRemoves duplicates
dict(x)Build dictionaryNeeds key/value pairs or keywords
enumerate(x)Index and value pairsReturns iterator
zip(a, b)Pair iterablesStops at shortest
any(x)True if any item truthyShort-circuits
all(x)True if all items truthyTrue for empty iterable
sum(x)Numeric sumStart value optional
min(x) / max(x)Smallest/largestError on empty iterable without default
print(list(enumerate(["a", "b"])))     # [(0, 'a'), (1, 'b')]
print(list(zip([1, 2], ["x"])))        # [(1, 'x')]
print(all([]))                         # True
print(any([]))                         # False

Formatting and f-strings

name = "Ada"
score = 95.5

print(f"{name}: {score}")
print("{}: {}".format(name, score))
FormatMeaning
f"{x}"Interpolate expression
"{} {}".format(a, b)Positional formatting
"{name}".format(name="Ada")Keyword formatting
repr(x)Developer representation
str(x)User-facing string conversion

PCAP-style questions may focus on which expression is evaluated and whether braces are literal or placeholders.

Debug-style output prediction checklist

When solving code-output questions:

  1. Mark every assignment as either rebinding a name or mutating an object.
  2. Track aliases for lists, dicts, sets, and custom objects.
  3. For function calls, bind arguments left to right.
  4. Check default parameter values only once at function definition.
  5. Resolve names using LEGB.
  6. For methods, identify self and class/instance attribute lookup.
  7. For inheritance, follow MRO and overridden methods.
  8. For exceptions, find the first matching handler.
  9. Run finally logic before deciding final output.
  10. Remember that many mutating methods return None.

Compact trap table

Code patternLikely resultWhy
[].append(1) used in expressionNoneMutating methods often return None
a = b = []Same listBoth names reference one object
[[0] * 3] * 2Shared inner listRepetition copies references
(1)intComma creates tuple, not parentheses
{}dictEmpty set is set()
"abc"[3]IndexErrorLast valid index is 2
"abc"[1:99]"bc"Slices tolerate out-of-range bounds
d["x"] missingKeyErrorUse get to avoid
int("3.0")ValueErrorNot valid integer literal
except Exception before except ValueErrorSpecific handler unreachableParent catches subclass first
return inside try with finallyfinally still runsCleanup clause executes
from m import x then m.xNameError unless m importedOnly x was bound
s.strip("ab")Removes any a/b at endsNot substring removal
list.sort() assigned to variableVariable becomes NoneSorts in place

Mini practice snippets

Aliasing

a = [1, 2]
b = [a, a]
b[0].append(3)
print(b)

Answer:

[[1, 2, 3], [1, 2, 3]]

Scope

x = 5

def f():
    print(x)

def g():
    x = 10
    f()

g()

Answer:

5

Reason: f uses global x; caller’s local scope is not searched.

Exception flow

try:
    print("A")
    1 / 0
    print("B")
except ZeroDivisionError:
    print("C")
else:
    print("D")
finally:
    print("E")

Answer:

A
C
E

OOP lookup

class A:
    x = 1

class B(A):
    pass

b = B()
b.x = 2
print(A.x, B.x, b.x)

Answer:

1 1 2

Final review priorities for PCAP-31-03

Prioritize hands-on fluency with:

  • Predicting output from short Python programs.
  • Lists, dictionaries, strings, slicing, and mutability.
  • Function calls, default arguments, scope, lambdas, and iterators.
  • Import syntax, module namespaces, and package concepts.
  • Exception hierarchy, handler order, else, finally, raise, and custom exceptions.
  • File modes and context managers.
  • Classes, self, attributes, inheritance, overriding, super(), MRO, and special methods.

Next step: work through timed PCAP-31-03 practice questions and explain each answer by tracing state, control flow, and object identity before checking the solution.