CertGrid CertGrid

PCEP cheat sheet

The whole of PCEP-30-02 on one page, grouped by its four blocks - fundamentals, control flow, data collections, functions and exceptions. Every output was printed by Python 3.14.4, and every row is one the exam actually asks about.

Block 1: Fundamentals (18%)

  • sys.implementation.name

    Which Python is running. CPython compiles to bytecode and interprets the bytecode - the answer to "compiled or interpreted?" is both.

    Full guide
  • a SyntaxError prints nothing at all

    The whole file is compiled before any of it runs, so a syntax error means no output - not even from correct lines above it.

    Full guide
  • keyword.kwlist

    35 reserved words on Python 3.14. True, False and None are among them; print is not.

    Full guide
  • TabError

    Mixing tabs and spaces has its own exception class - a subclass of IndentationError, itself a subclass of SyntaxError. Practice tests ask for it by name.

    Full guide
  • 0b1010 · 0o17 · 0x1f · bin() oct() hex()

    Three prefixes in, three functions out - and the functions return strings with the prefix included.

    Full guide
  • 017

    Python 2 octal. A leading zero on a multi-digit integer is a SyntaxError in Python 3, not 15 and not 17.

    Full guide
  • True + True

    bool is a subclass of int, so this is 2. `True == 1` is True and `True is 1` is False.

    Full guide
  • / vs // vs %

    `/` always returns a float. `//` floors, so -7 // 2 is -4. `%` takes the sign of the right operand.

    The single most asked arithmetic question in either exam.

    Full guide
  • 2 ** 3 ** 2 · -2 ** 2

    `**` is right-associative and binds tighter than unary minus: 512, and -4.

    Full guide
  • and / or return an operand

    Not a boolean. `0 or "x"` is the string, and `0 and 1/0` never divides - short-circuiting is observable.

    Full guide
  • ~5 · << >>

    `~n` is `-n - 1`, so ~5 is -6. Shifts multiply and floor-divide by powers of 2.

    Full guide
  • round() vs int()

    round() is nearest-with-ties-to-even, so round(2.5) is 2. int() truncates. round(2.675, 2) is 2.67 for a different reason entirely.

    Full guide
  • bool() on everything

    Zero, empty and None are false. `'0'`, `' '` and `[0]` are all true.

    Full guide
  • int("3.5")

    ValueError. int() parses sign and digits only - int(float("3.5")) is the two-step fix.

    Full guide
  • print(*values, sep=" ", end="\n")

    One space between arguments by default. `sep` goes between, `end` goes after.

    Full guide
  • input() returns str

    So `input() + input()` concatenates. Convert at the read: `int(input())`.

    The most reliably examined question in objective 1.5.

    Full guide

Block 2: Control flow (29%)

  • elif order

    Tested top to bottom, first true one wins. A broad condition above a narrow one makes the narrow one dead code, with no warning.

    Full guide
  • A if cond else B

    The conditional expression. Result first, then the condition - and the else is mandatory.

    Full guide
  • range(stop) · range(start, stop) · range(start, stop, step)

    Stop is excluded. A negative step counts down. An impossible range is empty, not an error. And a range prints as `range(0, 5)`, not a list.

    Full guide
  • range(1.5)

    TypeError - range takes integers only. A zero step is a ValueError instead.

    Full guide
  • the loop variable after the loop

    A `for` leaves it at the last value; a loop that never ran leaves it unbound and a NameError. A `while` counter overshoots by one.

    Full guide
  • for ... else

    The else runs **unless** a break happened. Read it as `nobreak:`.

    Full guide
  • else after zero iterations

    Still runs. No break happened, because there was no opportunity for one.

    Full guide
  • break in nested loops

    Leaves the inner loop only. There is no labelled break and no `break 2`.

    Full guide

Block 3: Data collections (25%)

  • xs[start:stop:step]

    Start included, stop excluded. `xs[:]` copies, `xs[::-1]` reverses, `xs[::2]` takes every second.

    Full guide
  • a slice never raises

    Out-of-range slices clamp to what exists. Only single-element indexing raises IndexError.

    Full guide
  • xs.sort() vs sorted(xs)

    The method sorts in place and returns None; the function returns a new list. `xs = xs.sort()` destroys the list.

    If you remember one row on this sheet, this one.

    Full guide
  • b = a vs c = a[:]

    Assignment binds a second name to one list. Slicing copies. Check with `a is b`.

    Full guide
  • [[0] * 2] * 3

    Three names for one inner list. Use a comprehension: `[[0] * 2 for _ in range(3)]`.

    Full guide
  • (1) vs (1,)

    The comma makes the tuple, not the brackets. `(1)` is an int. `()` is the one exception.

    Full guide
  • tuple refusals

    AttributeError for `append` (the method does not exist), TypeError for item assignment and deletion.

    Full guide
  • in tests keys, not values

    `99 in d` is False even when 99 is a value. Use `99 in d.values()`.

    Full guide
  • insertion order · duplicate keys

    Order is guaranteed since 3.7. And `{1: "int", 1.0: "float", True: "bool"}` is ONE entry, keyed 1, valued "bool".

    Full guide
  • d["missing"]

    KeyError. `d.get("missing")` returns None instead, and takes a default.

    Full guide
  • split() vs split(" ")

    No argument collapses runs of whitespace; an explicit separator does not. Same input, three items against four.

    Full guide
  • s += "d" on a string

    Builds a new string and rebinds the name. Any other name still sees the old value - the opposite of a list.

    Full guide

Block 4: Functions and exceptions (28%)

  • a function with no return

    Returns None. `print(f())` where f only prints produces two lines.

    Full guide
  • def f(x, target=[])

    The default is created once, when the def runs. Every call without an argument shares it. `__defaults__` holds the accumulating object.

    Asked on both exams, in at least three disguises.

    Full guide
  • def f(a, b=1, c)

    SyntaxError - compile time, so the program prints nothing at all.

    Full guide
  • rebind vs mutate

    A function cannot rebind the caller's name and can mutate the caller's object. That single distinction answers most argument questions.

    Full guide
  • UnboundLocalError

    An assignment anywhere in a function makes the name local everywhere in it - including the line above that reads it.

    Full guide
  • LEGB

    Local, Enclosing, Global, Built-in. First match wins and the search stops.

    Full guide
  • no base case

    RecursionError - a subclass of RuntimeError - at a default depth of 1000. Not StackOverflowError, which is another language.

    Full guide
  • the exception hierarchy

    Printed from __bases__. The three nobody guesses: TabError under IndentationError under SyntaxError, UnboundLocalError under NameError, RecursionError under RuntimeError.

    Full guide
  • BaseException.__subclasses__()

    KeyboardInterrupt and SystemExit sit outside Exception, which is why `except Exception:` does not catch Ctrl-C.

    Full guide
  • except clause order

    Specific before general. A base class above its subclass makes the subclass clause unreachable, silently.

    Full guide
  • except (A, B) · else · finally

    A tuple of types in one clause. `else` runs only on success; `finally` runs always, including after zero iterations of anything.

    Full guide

The one-liners worth knowing cold

  • -7 // 2 · -7 % 2 · 2 ** 3 ** 2 · -2 ** 2

    -4, 1, 512, -4. Four separate questions in one line.

    Full guide
  • "abcdef"[::-2] · [4:1] · len("a\tb")

    fdb, an empty string, 3. An escape is one character.

    Full guide
  • bool("0") · bool([0]) · int(-3.9) · round(2.5)

    True, True, -3, 2.

    Full guide