PCAP-31-03 — Python Institute PCAP - Certified Associate Python Programmer Cheat Sheet

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

Use the tables for a quick pre-exam check. Expand a topic’s notes for explanations, examples, and additional distinctions.

Scope and study context

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.

  1. Scan the tables first. They summarize the rules most likely to cause mistakes.
  2. Mark weak areas. Do not reread everything equally; target the rules you cannot explain quickly.
  3. Practice output prediction. Many Python exam questions reward exact reasoning about values, types, scope, mutation, and control flow.
  4. Use original practice questions immediately after review. The fastest improvement usually comes from topic drills with detailed explanations, not passive reading.
  5. Revisit mistakes by category. Track whether you missed syntax, object behavior, mutability, inheritance, exceptions, or standard-library behavior.

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__()
Notes and examples
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)

Arithmetic and comparison rules

OperatorMeaningTrap
+Addition or concatenationWorks differently by type; 1 + "1" is invalid.
-Subtraction or unary negativeUnary operators interact with exponentiation.
*Multiplication or sequence repetition"ha" * 3 gives repeated string content.
/True divisionResult is a float.
//Floor divisionFloors toward negative infinity, not toward zero.
%ModuloSign behavior follows Python’s floor-division relationship.
**ExponentiationRight-associative: 2 ** 3 ** 2 means 2 ** (3 ** 2).
==, !=Equality comparisonDo not confuse with identity checks.
<, <=, >, >=Ordering comparisonsChained comparisons are evaluated mathematically.

Boolean logic and truthiness

ValueTruth value
False, NoneFalse
0, 0.0False
"", [], (), {}, set()False
Most other objectsTrue

Important rules:

  • and and or short-circuit.
  • and returns the first falsy operand or the last operand.
  • or returns the first truthy operand or the last operand.
  • not returns a Boolean value.
  • Chained comparisons such as a < b < c are valid and do not mean (a < b) < c.

Operator precedence review

High-level order to remember:

  1. Parentheses and indexing/calls
  2. Exponentiation
  3. Unary +, -, not where applicable
  4. Multiplication, division, floor division, modulo
  5. Addition and subtraction
  6. Comparisons and membership/identity tests
  7. Boolean and
  8. Boolean or

When in doubt, add parentheses mentally and test with small values in practice questions.

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
Notes and examples
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.

if, elif, and else

PatternReview 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 ifIndentation 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 featureMeaning
while condition:Repeats while condition is truthy.
for item in iterable:Iterates over items produced by iterable.
breakExits the nearest loop immediately.
continueSkips to the next iteration of the nearest loop.
Loop elseRuns if the loop was not terminated by break.

Loop else decision rule

Use this rule:

  • If the loop finishes normally, the else block runs.
  • If the loop exits by break, the else block does not run.
  • continue does not prevent the loop else from running.

This is frequently misunderstood because loop else does not mean “the loop condition was false in the same way as an if statement.”

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})
Notes and examples

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
Notes and examples
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))

Lists

Lists are ordered, mutable sequences.

OperationResult
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

SliceMeaning
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

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)
Notes and examples

Tuples

Tuples are ordered and immutable, but they can contain mutable objects.

PatternMeaning
(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

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
Notes and examples
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}

Dictionaries

Dictionaries store key-value pairs and preserve insertion order in modern Python versions.

OperationReview 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] = valueAdds or updates an entry
del d[key]Deletes key or raises KeyError
key in dTests 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.
  • in checks keys by default.
  • Updating an existing key does not create a duplicate key.

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().

Notes and examples

Sets

Sets are unordered collections of unique hashable elements.

OperationMeaning
set(iterable)Creates a set from unique items
`ab`
a & bIntersection
a - bDifference
a ^ bSymmetric difference
x in sMembership 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

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
Notes and examples
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

Strings

Strings are immutable sequences of characters.

FeatureReview point
Indexings[0], s[-1] work like sequence indexing.
SlicingReturns a new string.
ImmutabilityYou cannot assign to s[0].
MethodsMost return new strings or other values.
Membership"py" in "python" tests substring presence.

String method review

MethodUse
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

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
Notes and examples
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

Default argument trap

Default argument expressions are evaluated once when the function is defined, not each time it is called.

PatternRisk
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.

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
Notes and examples

Iteration, iterators, and generators

ConceptReview point
IterableObject that can produce an iterator
IteratorObject with __next__() behavior
iter(obj)Gets an iterator
next(iterator)Gets next value or raises StopIteration
Generator functionFunction using yield
Generator objectLazy 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.
  • return inside a generator ends iteration.
  • yield pauses function state between values.

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
Notes and examples
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.

Import forms

Import statementName available afterward
import mathmath
import math as mm
from math import sqrtsqrt
from math import sqrt as ss
from math import *Many public names; avoid in production-style reasoning

Import traps

TrapCorrect understanding
import module vs from module import nameThe first imports the module name; the second imports a specific object name.
AliasingAfter import math as m, use m.sqrt(...), not math.sqrt(...) unless math was also imported.
Namespace pollutionfrom module import * can overwrite existing names and reduce clarity.
Module executionTop-level module code executes when imported.
Repeated importsModules are cached after import in normal execution.

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.

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")
Notes and examples
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.

Common built-in exceptions

ExceptionTypical cause
ValueErrorCorrect type, invalid value
TypeErrorOperation or function used with inappropriate type
IndexErrorSequence index out of range
KeyErrorMissing dictionary key
ZeroDivisionErrorDivision or modulo by zero
FileNotFoundErrorFile path cannot be found
AttributeErrorAttribute does not exist
NameErrorName is not defined
UnboundLocalErrorLocal variable referenced before assignment
ImportError / ModuleNotFoundErrorImport problem
AssertionErrorFailed assertion

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
Notes and examples
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())
Notes and examples
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)

Methods and binding

Method patternReview point
Instance methodFirst 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 selfCommon cause of argument-count errors.

Inheritance and overriding

ConceptReview point
InheritanceA subclass can reuse and extend superclass behavior.
OverrideSubclass 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:

  1. Which class is used to create the object?
  2. Does the instance have the attribute directly?
  3. If not, does the class have it?
  4. If not, is it inherited from a superclass?
  5. If a method is called, which override is found first?
  6. Does the method call super() and continue the chain?

Special methods

MethodPurpose
__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.

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
Notes and examples
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.
Notes and examples

Mini review: output-prediction checklist

Before choosing an answer, walk through the code in this order:

  1. Parse the structure. Check indentation, blocks, and function/class definitions.
  2. Identify object creation. Lists, dictionaries, objects, iterators, and generators may carry state.
  3. Track name binding. Assignment changes what a name refers to.
  4. Track mutation. In-place operations affect all references to the same mutable object.
  5. Resolve scope. Apply LEGB for every non-obvious name.
  6. Follow control flow. Include break, continue, return, exceptions, and finally.
  7. Check return values. Many methods return None even though they changed an object.
  8. Confirm final type. A correct-looking value with the wrong type may still be wrong.

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()
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")
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)
1 1 2
Notes and examples

Exception flow

ConstructMeaning
tryCode that may raise an exception
except SomeErrorHandles a matching exception
exceptBroad catch; should usually come last
elseRuns if no exception occurred in try
finallyRuns regardless of whether an exception occurred
raiseRaises an exception
assert conditionRaises AssertionError if condition is false

Exception-order rule

Put specific exception handlers before general ones.

Better orderWhy
except ValueError: before except Exception:Specific handler gets a chance to run.
Broad handler firstMakes later specific handlers unreachable or ineffective.

try / except / else / finally decision table

Situationexcept runs?else runs?finally runs?
No exception in tryNoYesYes
Exception handled by matching exceptYesNoYes
Exception not handledNo matching handlerNoYes, then exception propagates
return inside tryMaybe notDepends on flowYes before function exits

Important: finally is for cleanup logic. It runs even when control flow is leaving the block.

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.

Notes and examples

Practice priorities before the real exam

After this Cheat Sheet, use a question bank with original practice questions, topic drills, and detailed explanations. Prioritize practice in this order if time is short:

PriorityPractice focusWhy it matters
1Output prediction with lists, dictionaries, functions, and scopeHigh error rate and easy to underestimate
2Exceptions and file handlingTests exact control flow and cleanup behavior
3OOP inheritance and attributesRequires methodical lookup reasoning
4Modules and importsSmall syntax differences change available names
5Strings and slicingMany questions hide off-by-one or immutability traps
6Iterators, generators, comprehensionsLazy evaluation and exhaustion can surprise candidates

High-yield PCAP-31-03 review map

AreaWhat to know coldCommon candidate mistake
Types and operatorsNumeric operators, precedence, truthiness, comparison behaviorConfusing is with ==, or / with //
Control flowif, loops, break, continue, loop else, nestingThinking loop else means “if condition was false”
CollectionsLists, tuples, dictionaries, sets, slicing, mutabilityForgetting list methods often mutate and return None
StringsIndexing, slicing, immutability, methods, formatting basicsExpecting string methods to modify the original string
FunctionsParameters, return values, defaults, scope, *args, **kwargsUsing mutable default arguments unintentionally
Modules and packagesImport forms, namespaces, __name__, module search conceptsNot knowing what name is introduced by each import style
Exceptionstry, except, else, finally, raising exceptions, hierarchyCatching broad exceptions before specific ones
FilesOpen modes, text processing, context managersForgetting to close files or mishandling newline behavior
OOPClasses, instances, attributes, methods, inheritance, overridingConfusing class attributes with instance attributes
Iteration toolsIterables, iterators, comprehensions, generatorsExpecting a generator to restart automatically

Python execution model and object basics

Python questions often test object behavior more than definitions.

ConceptReview rule
Everything is an objectValues have identity, type, and value.
Assignment binds namesx = y makes x refer to the same object as y; it does not copy the object.
Mutability mattersLists, dictionaries, and sets are mutable. Strings, tuples, numbers, and booleans are immutable.
Identity vs equalityis checks object identity; == checks value equality.
NamespacesA name is resolved in a namespace; the same spelling can refer to different objects in different scopes.
Notes and examples

Identity, equality, and mutation traps

Expression or patternCorrect interpretation
a == bDo a and b have equal values?
a is bAre a and b the exact same object?
b = ab 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() makes x become None.

Defining and calling functions

FeatureReview rule
def name(...):Creates a function object and binds it to a name.
return valueExits function and sends value back.
No explicit returnFunction returns None.
Positional argumentsMatched by position.
Keyword argumentsMatched by parameter name.
Default parametersUsed when caller omits that argument.
*argsCollects extra positional arguments as a tuple.
**kwargsCollects extra keyword arguments as a dictionary.

Argument-order rule

A safe ordering model:

  1. Positional parameters
  2. Defaulted parameters
  3. *args
  4. Keyword-only parameters, if used
  5. **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.

Scope and name resolution

Python uses the LEGB rule:

LevelMeaning
LocalNames assigned inside the current function
EnclosingNames in enclosing function scopes
GlobalNames at module level
Built-inPython 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.
  • global tells Python that assignment should target the module-level name.
  • nonlocal targets a name in an enclosing function scope.

Lambda, higher-order functions, and comprehensions

FeatureReview point
lambdaCreates 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 comprehensionBuilds a list from an expression and iterable.
Generator expressionLazy 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(...).

__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.

Selected standard-library areas to recognize

ModuleCommon purpose
mathMathematical functions and constants
randomPseudorandom choices and numbers
datetimeDates and times
osOperating-system interactions
sysInterpreter-related values and functions
platformPlatform information
jsonJSON 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.

File-opening basics

ModeMeaning
"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
Notes and examples

Use context managers when possible: with open(...) as f: ensures the file is closed after the block.

File method review

MethodUse
read()Reads entire file or specified size
readline()Reads one line
readlines()Reads all lines into a list
Iterating over file objectReads 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.

Class and object fundamentals

TermMeaning
ClassBlueprint for objects
Object / instanceA concrete object created from a class
AttributeData associated with an object or class
MethodFunction associated with a class
selfConventional name for the current instance
Constructor initializer__init__ initializes a new instance after creation

Instance vs class attributes

Attribute typeWhere storedShared?
Instance attributeOn each objectNo
Class attributeOn the classYes, 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__.

Encapsulation conventions

Python uses conventions more than strict access controls.

Name styleConvention
namePublic
_nameInternal-use convention
__nameName-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.

Comprehensions

FormProduces
[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 the if, 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

MistakeCorrection
Missing colon after if, for, while, def, class, try, exceptCompound statements need :.
Incorrect indentationBlocks are defined by indentation.
Mixing tabs and spacesAvoid; can produce indentation errors.
Assuming braces define blocksPython uses indentation, not braces.
Notes and examples

Type and conversion mistakes

MistakeCorrection
Adding string and integer directlyConvert explicitly with str() or int() as appropriate.
Expecting input() to return a numberinput() returns a string.
Confusing list("abc") with ["abc"]The first gives individual characters.
Expecting bool("False") to be falseNon-empty strings are truthy.

Mutability mistakes

MistakeCorrection
Thinking assignment copies a listAssignment binds another name to the same list.
Expecting slicing to deep-copy nested listsSlicing creates a shallow copy.
Using mutable default argumentsUse None and create inside function.
Sorting a list and assigning the resultlist.sort() returns None; use sorted() for a new list.

Scope mistakes

MistakeCorrection
Assigning to global name inside function without globalCreates a local name by default.
Reading local before assignmentCan raise UnboundLocalError.
Shadowing built-ins like list or strAvoid using built-in names as variables.

Exception mistakes

MistakeCorrection
Catching Exception before ValueErrorPut specific handlers first.
Assuming finally runs only on errorsIt runs regardless.
Assuming else runs after an exception is handledelse 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…
AssignmentAre two names pointing to the same object?
A list or dictionaryIs it being mutated in place?
A method callDoes this method return a value or mutate and return None?
A functionWhat is returned if no return executes?
DefaultsWas the default object created once at definition time?
ScopeIs the name local, enclosing, global, or built-in?
ImportsWhich exact name is available after the import statement?
ExceptionsWhich handler matches first? Does finally run?
InheritanceWhich method or attribute is found first?
IteratorsHas the iterator already been consumed?
StringsIs a new string returned rather than modifying the original?
DictionariesIs membership checking keys or values?

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, try else, and finally execute.
  • 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.

Put the review into practice