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 first | Common trap |
|---|
| “What is printed?” | Current values, aliases, mutation, exception flow | Assuming methods return modified objects |
| List/dict/set behavior | Whether object is mutated in place | Confusing shallow copy with deep copy |
| Function output | Argument binding, scope, default values | Mutable default argument reused |
| Class behavior | Instance vs class attributes, method resolution | Reading self.x as always instance-only |
| Exception flow | First matching except, else, finally | finally can run even after return |
| String methods | Strings are immutable | Methods return new strings |
| Import questions | Namespace created by each import form | import module vs from module import name |
| Generator questions | Lazy execution and StopIteration | Thinking generator body runs at creation |
Core syntax and runtime rules
Truthiness and boolean logic
| Value/type | False when | Notes |
|---|
None | Always false | Singleton; compare with is None |
bool | False | bool is a subclass of int |
| Numbers | Zero | 0, 0.0, 0j are false |
| Strings | Empty string "" | Non-empty strings are true, even "False" |
| Lists, tuples, sets, dicts | Empty | Non-empty containers are true |
| Custom objects | Usually true | Can define __bool__() or __len__() |
print(bool("0")) # True
print(bool([])) # False
print(True + True) # 2
Operators most likely to matter
| Operator | Meaning | Exam notes |
|---|
+, -, * | Arithmetic; also sequence operations | "a" * 3 == "aaa" |
/ | True division | Always returns float |
// | Floor division | Floors toward negative infinity |
% | Remainder | Sign follows divisor in Python |
** | Exponentiation | Right-associative |
and | Boolean AND | Returns an operand, not forced bool |
or | Boolean OR | Returns an operand |
not | Boolean negation | Always returns bool |
is | Identity | Same object, not same value |
== | Equality | Value comparison |
in | Membership | Works 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 lower | Examples |
|---|
| Parentheses, indexing, calls | f(x), a[i] |
| Exponentiation | ** |
| Unary | +x, -x, not x has lower precedence than comparisons |
| Multiplicative | *, /, //, % |
| Additive | +, - |
| Comparisons | <, <=, >, >=, ==, !=, is, in |
| Boolean | not, 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
| Construct | Runs when | Trap |
|---|
if | Condition truthy | Assignment is not expression syntax in classic if usage |
elif | Previous conditions false, this one true | Only one branch runs |
else after if | No condition matched | Not related to exceptions |
while | Repeats while condition truthy | May never run |
for | Iterates over iterable | Does not require numeric index |
Loop else | Loop ended normally | Skipped if break occurred |
break | Exits nearest loop | Skips loop else |
continue | Next iteration | Does not exit loop |
for x in [1, 2, 3]:
if x == 4:
break
else:
print("not found") # prints
range() behavior
| Expression | Values |
|---|
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
| Type | Mutable? | Ordered/indexed? | Allows duplicates? | Literal |
|---|
str | No | Yes | Yes | "abc" |
list | Yes | Yes | Yes | [1, 2] |
tuple | No | Yes | Yes | (1, 2) |
dict | Yes | By key | Keys unique | {"a": 1} |
set | Yes | No | No | {1, 2} |
frozenset | No | No | No | frozenset({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]
| Operation | Result |
|---|
b = a | New 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
| Operation | Meaning | Mutates? | Return value |
|---|
lst.append(x) | Add one item at end | Yes | None |
lst.extend(iterable) | Add many items | Yes | None |
lst.insert(i, x) | Insert before index | Yes | None |
lst.remove(x) | Remove first matching value | Yes | None |
lst.pop() | Remove and return last item | Yes | Removed item |
lst.pop(i) | Remove and return item at index | Yes | Removed item |
lst.clear() | Remove all items | Yes | None |
lst.sort() | Sort in place | Yes | None |
sorted(lst) | Return sorted list | No | New list |
lst.reverse() | Reverse in place | Yes | None |
reversed(lst) | Return reverse iterator | No | Iterator |
nums = [3, 1, 2]
print(nums.sort()) # None
print(nums) # [1, 2, 3]
Slicing reference
| Expression | Meaning |
|---|
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
| Expression | Result |
|---|
(1, 2, 3) | Tuple |
1, 2, 3 | Tuple 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
| Operation | Meaning |
|---|
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] = v | Add or replace |
del d[k] | Delete key; raises KeyError if missing |
k in d | Tests 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
| Trap | Correct understanding |
|---|
| Keys can be lists | False; keys must be hashable |
in checks values | False; checks keys |
d.get(k) raises if missing | False; returns default |
dict.keys() is a list | False; it is a view object |
| Duplicate literal keys remain duplicated | False; later value wins |
d = {"x": 1, "x": 2}
print(d) # {'x': 2}
Sets
| Operation | Meaning |
|---|
| `a | bora.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
| Feature | Rule |
|---|
| Mutability | Strings are immutable |
| Indexing | Same indexing and slicing rules as sequences |
| Concatenation | + creates a new string |
| Repetition | "ab" * 3 gives "ababab" |
| Membership | "x" in "xyz" |
| Comparison | Lexicographic by Unicode code points |
s = "Python"
print(s[0]) # P
print(s[-1]) # n
print(s[1:4]) # yth
High-yield string methods
| Method | Use | Trap |
|---|
s.lower() / s.upper() | Case conversion | Returns new string |
s.strip() | Remove surrounding whitespace | Not middle whitespace |
s.strip(chars) | Remove any listed chars from ends | chars is a set of characters, not substring |
s.find(sub) | Index or -1 | No exception if missing |
s.index(sub) | Index | Raises ValueError if missing |
s.replace(old, new) | Return replaced copy | Original unchanged |
s.split(sep) | String to list | Default splits on whitespace |
sep.join(iterable) | List of strings to one string | Separator is the caller |
s.startswith(x) | Prefix test | Returns bool |
s.endswith(x) | Suffix test | Returns bool |
s.isalpha() | All alphabetic and non-empty | Empty string returns False |
s.isdigit() | All digits and non-empty | Empty string returns False |
s.isalnum() | Alphabetic or digit and non-empty | Empty string returns False |
s.isspace() | All whitespace and non-empty | Empty 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
| Function | Meaning |
|---|
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
| Concept | Example | Notes |
|---|
| Positional parameter | def f(a, b): | Matched by position |
| Default parameter | def f(a=1): | Evaluated once at definition time |
| Keyword argument | f(a=3) | Name-based binding |
| Variadic positional | def f(*args): | args is a tuple |
| Variadic keyword | def f(**kwargs): | kwargs is a dict |
| Return value | return x | Without 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
| Level | Meaning | Example |
|---|
| Local | Inside current function | Assignment creates local unless declared |
| Enclosing | Outer nested function scope | Used by closures |
| Global | Module-level name | global can rebind |
| Built-in | Python built-ins | len, 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
| Keyword | Rebinds name in | Cannot create |
|---|
global | Module scope | Local-only rebinding |
nonlocal | Nearest enclosing function scope | New 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]
| Construct | Returns | Exam note |
|---|
lambda x: expr | Function object | Expression only, no statements |
map(func, iterable) | Iterator | Convert with list() for display |
filter(func, iterable) | Iterator | Keeps truthy results |
sorted(iterable) | New list | Does not mutate original |
list.sort() | None | Mutates list |
Iterables, iterators, and generators
Iterable vs iterator
| Term | Meaning |
|---|
| Iterable | Object usable in for, provides iter() |
| Iterator | Object 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:
yield vs return
| Statement | In normal function | In generator function |
|---|
return value | Ends function and returns value | Ends generator; value becomes StopIteration detail |
yield value | Syntax invalid outside generator context | Pauses and emits value |
Modules and packages
| Syntax | What name becomes available? | Usage |
|---|
import math | math | math.sqrt(9) |
import math as m | m | m.sqrt(9) |
from math import sqrt | sqrt | sqrt(9) |
from math import sqrt as s | s | s(9) |
from math import * | Many public names | Avoid 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 module | Module 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
| Item | Meaning |
|---|
| Module | Single .py file or built-in/extension module |
| Package | Directory-based module grouping |
sys.path | Search locations for imports |
__init__.py | Package 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
| Module | Typical use |
|---|
math | Deterministic math functions, constants |
random | Pseudorandom choices and numbers |
platform | Runtime/platform information |
sys | Interpreter/system interaction |
os | Operating system interfaces |
datetime | Dates and times |
time | Time-related functions |
Avoid assuming exact platform output in exam questions unless it is explicitly given.
Package management concepts
| Term | Meaning |
|---|
pip | Python package installer |
| PyPI | Public package index |
| Virtual environment | Isolated package environment |
| Dependency | Package 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")
| Clause | Runs when |
|---|
try | Protected code block |
except | Matching exception raised in try |
else | No exception occurred in try |
finally | After try/except/else, even during return or raise |
Exception matching rules
| Rule | Impact |
|---|
First matching except wins | Put specific exceptions before general ones |
| Subclasses match parent handlers | except Exception catches many ordinary errors |
BaseException is broader than Exception | Usually not used for application errors |
Bare except: catches almost everything | Dangerous in real code |
| Multiple exceptions can be grouped | except (ValueError, TypeError): |
try:
int("x")
except Exception:
print("general")
except ValueError:
print("value") # unreachable
Common built-in exceptions
| Exception | Typical cause |
|---|
SyntaxError | Invalid Python syntax |
IndentationError | Invalid indentation |
NameError | Name not defined |
TypeError | Operation on inappropriate type |
ValueError | Correct type, invalid value |
IndexError | Sequence index out of range |
KeyError | Missing dictionary key |
ZeroDivisionError | Division/modulo by zero |
AttributeError | Missing attribute |
ImportError | Import failed |
ModuleNotFoundError | Module cannot be found |
FileNotFoundError | File path not found |
AssertionError | Failed assert |
Raising and re-raising
raise ValueError("bad input")
Inside an except block:
try:
int("x")
except ValueError:
print("logging")
raise
| Form | Meaning |
|---|
raise SomeException() | Raise a new exception |
raise SomeException | Instantiate and raise exception class |
raise | Re-raise current exception inside handler |
assert
assert x > 0, "x must be positive"
| Feature | Meaning |
|---|
| Raises | AssertionError if condition is false |
| Purpose | Debugging/sanity checks |
| Trap | Do 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
| Mode | Meaning | Existing file behavior |
|---|
"r" | Read text | Error if missing |
"w" | Write text | Truncates or creates |
"a" | Append text | Creates if missing |
"x" | Exclusive create | Error if exists |
"b" | Binary modifier | Use with other modes, e.g. "rb" |
"t" | Text modifier | Default |
"+" | Read/write modifier | Combines reading and writing |
with open("data.txt", "r", encoding="utf-8") as f:
content = f.read()
File method reference
| Method | Meaning |
|---|
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())
| Element | Meaning |
|---|
class Dog: | Defines a class object |
__init__ | Initializer called after object creation |
self | Conventional name for current instance |
| Instance attribute | Stored per object, usually self.x |
| Class attribute | Stored on class, shared lookup by instances |
| Method | Function 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
| Access | Lookup behavior |
|---|
obj.attr | Instance first, then class, then base classes |
Class.attr | Class, then base classes |
obj.attr = value | Creates/replaces instance attribute |
Class.attr = value | Creates/replaces class attribute |
Mutable class attribute trap:
class Bag:
items = []
a = Bag()
b = Bag()
a.items.append("x")
print(b.items) # ['x']
Methods
| Method type | First parameter | Called as | Use |
|---|
| Instance method | self | obj.method() | Work with instance state |
| Class method | cls | Class.method() or obj.method() | Work with class state/constructors |
| Static method | None automatic | Class.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 form | Meaning |
|---|
name | Public by convention |
_name | Non-public by convention |
__name | Name-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
| Concept | Meaning |
|---|
| Inheritance | Child class reuses/extends parent class |
| Override | Child defines same method name |
| Polymorphism | Same 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
| Method | Used by | Example |
|---|
__init__ | Initialization | obj = C() |
__str__ | User-friendly string | str(obj), print(obj) |
__repr__ | Developer-oriented representation | repr(obj) |
__len__ | Length/truthiness fallback | len(obj) |
__eq__ | Equality | obj1 == obj2 |
__lt__ | Less-than comparison | obj1 < obj2 |
__add__ | Addition operator | obj1 + obj2 |
__iter__ | Iteration | for x in obj |
__next__ | Iterator next item | next(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-in | Purpose | Trap |
|---|
len(x) | Length | Requires object supporting length |
type(x) | Exact type object | For inheritance checks, prefer isinstance |
isinstance(x, T) | Type/subtype check | Works with tuple of types |
id(x) | Object identity integer | Not value equality |
int(x) | Convert to integer | Can raise ValueError |
float(x) | Convert to float | Can raise ValueError |
str(x) | Convert to string | Calls string conversion |
list(x) | Convert iterable to list | Consumes iterators |
tuple(x) | Convert iterable to tuple | Consumes iterators |
set(x) | Unique unordered collection | Removes duplicates |
dict(x) | Build dictionary | Needs key/value pairs or keywords |
enumerate(x) | Index and value pairs | Returns iterator |
zip(a, b) | Pair iterables | Stops at shortest |
any(x) | True if any item truthy | Short-circuits |
all(x) | True if all items truthy | True for empty iterable |
sum(x) | Numeric sum | Start value optional |
min(x) / max(x) | Smallest/largest | Error 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
name = "Ada"
score = 95.5
print(f"{name}: {score}")
print("{}: {}".format(name, score))
| Format | Meaning |
|---|
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:
- Mark every assignment as either rebinding a name or mutating an object.
- Track aliases for lists, dicts, sets, and custom objects.
- For function calls, bind arguments left to right.
- Check default parameter values only once at function definition.
- Resolve names using LEGB.
- For methods, identify
self and class/instance attribute lookup. - For inheritance, follow MRO and overridden methods.
- For exceptions, find the first matching handler.
- Run
finally logic before deciding final output. - Remember that many mutating methods return
None.
Compact trap table
| Code pattern | Likely result | Why |
|---|
[].append(1) used in expression | None | Mutating methods often return None |
a = b = [] | Same list | Both names reference one object |
[[0] * 3] * 2 | Shared inner list | Repetition copies references |
(1) | int | Comma creates tuple, not parentheses |
{} | dict | Empty set is set() |
"abc"[3] | IndexError | Last valid index is 2 |
"abc"[1:99] | "bc" | Slices tolerate out-of-range bounds |
d["x"] missing | KeyError | Use get to avoid |
int("3.0") | ValueError | Not valid integer literal |
except Exception before except ValueError | Specific handler unreachable | Parent catches subclass first |
return inside try with finally | finally still runs | Cleanup clause executes |
from m import x then m.x | NameError unless m imported | Only x was bound |
s.strip("ab") | Removes any a/b at ends | Not substring removal |
list.sort() assigned to variable | Variable becomes None | Sorts in place |
Mini practice snippets
Aliasing
a = [1, 2]
b = [a, a]
b[0].append(3)
print(b)
Answer:
Scope
x = 5
def f():
print(x)
def g():
x = 10
f()
g()
Answer:
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:
OOP lookup
class A:
x = 1
class B(A):
pass
b = B()
b.x = 2
print(A.x, B.x, b.x)
Answer:
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.