PCPP1 Probeprüfung: 45 Fragen im Prüfungsstil

Track Python · PCPP1 Block 1 bis 5 · ca. 65 Min. Prüfungszeit plus ca. 30 bis 40 Min. Auswertung

Worum es geht

Laut Quelle gibt es keinen offiziellen PCPP1-Übungstest. Diese Probeprüfung ersetzt ihn nicht, sie baut dir aber die Prüfungssituation nach: 45 Fragen, verteilt wie in der echten Prüfung auf die fünf Blöcke, ausschließlich aus dem Stoff der Lektionen 11 bis 18. Jede Frage ist eine Übung: Du trägst den Buchstaben (bei Mehrfachauswahl beide Buchstaben) als String ein und klickst auf den Check. Der Check erklärt zu jeder Option, warum sie stimmt oder nicht.

Wo Code im Spiel ist, führt der Check den Code aus und leitet die richtige Antwort daraus ab. Bei reinen Wissensfragen (tkinter, Sockets, HTTP, Werkzeuge) stehen Quellenangabe und Begründung im Feedback und im Code des Checks. Für tkinter benutzt der Check eine Attrappe, die nur die Rückgabewerte nachbildet, für Sockets gibt es keine echten Verbindungen.

Die Prüfung laut Glossar

Die Zahlen stammen aus quellen/python-glossar-pcap-pcpp1.md (Teil 2, Stand dort: 1. Oktober 2026). Vor dem Buchen bitte auf der offiziellen Seite prüfen.

Punkt Angabe laut Glossar
Prüfung PCPP1 (Exam PCPP-32-101)
Fragen 45
Dauer 65 Minuten, dazu 10 Minuten Tutorial (etwa 1,4 Minuten pro Frage)
Bestehen 70 %
Formate Einfachauswahl, Mehrfachauswahl, Codeaufgaben, Szenarien, interaktive Aufgaben
Kosten laut offizieller Seite ab 325 USD, nur Einzelvoucher ohne Wiederholungsoption
Version PCPP-32-101 ist aktiv. Eine Nachfolgeversion PCPP-32-102 war als “in Entwicklung” gelistet (bitte prüfen)

Die Blöcke und die Fragenzahl in dieser Probeprüfung:

Block Thema Fragen Gewicht
1 Fortgeschrittene OOP 15 35 %
2 Coding-Konventionen, Best Practices, Standardisierung 7 12 %
3 GUI-Programmierung 8 20 %
4 Netzwerkprogrammierung 8 18 %
5 Dateiverarbeitung und Umgebung 7 15 %

70 % von 45 Fragen sind 31,5, also brauchst du in dieser Probeprüfung mindestens 32 richtige Antworten (eigene Rechnung). Ob die echte Prüfung nach Blöcken gewichtet rechnet oder Teilpunkte bei Mehrfachauswahl vergibt, steht für die PCPP1 nicht in der Quelle (bei der PCAP spricht sie vom Durchschnitt über alle Blöcke, bitte prüfen). Hier gilt: Eine Frage zählt nur, wenn sie vollständig richtig ist.

So gehst du vor

  1. Zeit stoppen: 65 Minuten für alle 45 Fragen. Bei etwa 1,4 Minuten pro Frage bleibt für Codefragen nicht viel Zeit. Lies bei Code zuerst, was am Ende ausgegeben wird, dann von oben nach unten. Bleibst du bei einer Frage länger als zwei Minuten hängen, rate und markiere sie.
  2. Nichts nachschlagen, keinen Code ausprobieren. Für eine ehrliche Simulation öffne die Hinweise (Hints) nicht. Wer einen Hinweis braucht, zählt die Frage als falsch und notiert sie für die Wiederholung.
  3. Zwei Durchgänge: Erst beantwortest du alle 45 Fragen mit Stoppuhr, die Antworten notierst du auf Papier. Die Stoppuhr läuft nicht, während du Antworten einträgst und prüfst. Danach trägst du die Antworten Frage für Frage ein und liest das Feedback (etwa 30 bis 40 Minuten, weil du zu jeder Option die Erklärung liest). Wer lieber sofort Feedback will, prüft nach jeder Frage, übt dann aber nicht mehr die Zeitnot.
  4. Die Lösungen sind auf dieser Seite ausgeblendet. Das Feedback des Checks zeigt dir die Erklärung zu jeder Option, auch zu den falschen.
  5. Am Ende trägst du die Punkte pro Block in die Auswertungshilfe ein.
  6. Plane zwei Sitzungen (zum Beispiel Block 1 und 2 am einen Tag, Block 3 bis 5 am anderen), wenn du nicht 65 Minuten am Stück hast. Die Zeit stoppst du dann pro Block (Fragenzahl mal 1,4 Minuten).

Ein Hinweis zur Form: Die echte Prüfung enthält laut Quelle auch Szenarien, Codeaufgaben und interaktive Aufgaben (die Quelle beschreibt sie nicht genauer). Diese Probeprüfung besteht nur aus Einfach- und Mehrfachauswahl, so lassen sich alle 45 Fragen automatisch und ehrlich prüfen.

Block 1: Fortgeschrittene OOP (35 %, 15 Fragen)

Stoff: Lektionen 11, 12 und 13. Fragen 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15.

Frage 1

Mehrfachauswahl, wähle zwei Antworten

Gegeben ist der Code unten. Welche zwei Ausdrücke ergeben True?

class Tier:
    pass

class Hund(Tier):
    pass

h = Hund()
  • A: isinstance(h, (int, Tier))

  • B: issubclass(Hund, (str, Tier))

  • C: type(h) == Tier

  • D: issubclass(Tier, Hund)

Trage die beiden Buchstaben als String ein, alphabetisch, z. B. "AC".

Prüfe bei jedem Ausdruck zwei Dinge: Stehen die Argumente in der richtigen Reihenfolge? Und ist eine exakte Typprüfung gemeint oder eine, die Vererbung berücksichtigt?

Frage 2

Einfachauswahl

Was gibt der Code aus? Die drei Zeilen der Ausgabe sind in den Antworten mit / getrennt.

class Meter:
    def __init__(self, v):
        self.v = v

    def __add__(self, other):
        if isinstance(other, Meter):
            return Meter(self.v + other.v)
        return NotImplemented

    def __radd__(self, other):
        return Meter(self.v + other)

    def __repr__(self):
        return f"Meter({self.v})"

print(Meter(1) + Meter(2))
print(5 + Meter(3))
try:
    print(Meter(1) + 2)
except TypeError:
    print("TypeError")
  • A: Meter(3) / TypeError / TypeError

  • B: Meter(3) / Meter(8) / Meter(3)

  • C: Meter(3) / Meter(8) / TypeError

  • D: Meter(3) / 8 / TypeError

Trage den Buchstaben als String ein, z. B. "B".

NotImplemented ist ein Rückgabewert, kein Fehler. Überlege, wessen Methode Python danach probiert, und welcher Operand bei 5 + Meter(3) links steht.

Frage 3

Einfachauswahl

Was gibt der Code aus? Die Zeilen der Ausgabe sind in den Antworten mit / getrennt.

class P:
    def __init__(self, x):
        self.x = x

    def __eq__(self, other):
        return self.x == other.x

a, b = P(1), P(1)
print(a == b)
try:
    print(len({a, b}))
except TypeError:
    print("TypeError")
  • A: True / 2

  • B: True / TypeError

  • C: True / 1

  • D: False / TypeError

Trage den Buchstaben als String ein, z. B. "B".

Was macht Python mit __hash__, sobald eine Klasse __eq__ selbst definiert? Und was braucht ein Set, um ein Objekt aufzunehmen?

Frage 4

Einfachauswahl

Was gibt der Code aus? Die Zeilen der Ausgabe sind in den Antworten mit / getrennt.

class G:
    x = 1

    def __getattr__(self, name):
        print("getattr", name)
        return 0

class H:
    x = 1

    def __getattribute__(self, name):
        print("getattribute", name)
        return super().__getattribute__(name)

g, h = G(), H()
g.x
g.y
h.x
  • A: getattr x / getattr y / getattribute x

  • B: getattr y

  • C: getattr x / getattr y

  • D: getattr y / getattribute x

Trage den Buchstaben als String ein, z. B. "B".

Eine der beiden Methoden greift nur als Notnagel, wenn der normale Weg nichts findet. Die andere ist ein Türsteher für jeden einzelnen Zugriff.

Frage 5

Einfachauswahl

Was gibt der Code aus? Die beiden Zeilen der Ausgabe sind in den Antworten mit / getrennt.

reihenfolge = []

class A:
    def __init__(self):
        reihenfolge.append("A")
        super().__init__()

class B(A):
    def __init__(self):
        reihenfolge.append("B")
        super().__init__()

class C(A):
    def __init__(self):
        reihenfolge.append("C")
        super().__init__()

class D(B, C):
    def __init__(self):
        reihenfolge.append("D")
        super().__init__()

D()
print(reihenfolge)
print([k.__name__ for k in D.__mro__])
  • A: ['D', 'B', 'A'] / ['D', 'B', 'A', 'object']

  • B: ['D', 'B', 'A', 'C'] / ['D', 'B', 'A', 'C', 'object']

  • C: ['D', 'B', 'C', 'A'] / ['D', 'B', 'C', 'A', 'object']

  • D: ['D', 'C', 'B', 'A'] / ['D', 'C', 'B', 'A', 'object']

Trage den Buchstaben als String ein, z. B. "B".

super() bedeutet nicht die Elternklasse, sondern die nächste Klasse in der MRO des aktuellen Objekts. Schreibe dir die MRO von D auf und gehe sie Schritt für Schritt ab.

Frage 6

Einfachauswahl

Was gibt der Code aus? Die Zeilen der Ausgabe sind in den Antworten mit / getrennt.

def a(f):
    print("dek a")
    def w():
        print("run a")
        return f()
    return w

def b(f):
    print("dek b")
    def w():
        print("run b")
        return f()
    return w

@a
@b
def f():
    print("run f")

f()
  • A: dek a / dek b / run a / run b / run f

  • B: dek b / dek a / run a / run b / run f

  • C: dek b / dek a / run b / run a / run f

  • D: dek a / dek b / run b / run a / run f

Trage den Buchstaben als String ein, z. B. "B".

Es gibt zwei Phasen: das Dekorieren beim Definieren (einmal) und das Ausführen beim Aufruf. Beide laufen in einer jeweils eigenen Reihenfolge. Übersetze @a @b def f in f = ....

Frage 7

Mehrfachauswahl, wähle zwei Antworten

Gegeben ist der Code unten. Welche zwei Aussagen sind richtig?

import functools

def wiederhole(n):
    def deko(fn):
        @functools.wraps(fn)
        def wrapper(*args, **kwargs):
            r = None
            for _ in range(n):
                r = fn(*args, **kwargs)
            return r
        return wrapper
    return deko

@wiederhole(2)
def gruss(name):
    """Sag hallo."""
    return "hi " + name
  • A: gruss.__name__ ist "wrapper", weil der Dekorator die Funktion ersetzt.

  • B: @wiederhole(2) entspricht gruss = wiederhole(gruss)(2).

  • C: gruss.__name__ ist "gruss".

  • D: gruss.__doc__ ist "Sag hallo.".

Trage die beiden Buchstaben als String ein, alphabetisch, z. B. "AC".

Frage dich, welche Funktion nach dem Dekorieren unter dem Namen gruss liegt, und was functools.wraps an dieser Stelle kopiert. Und: in welcher Reihenfolge werden die Klammern bei @wiederhole(2) ausgewertet?

Frage 8

Einfachauswahl

Was gibt der Code aus?

class Basis:
    @classmethod
    def erzeuge(cls):
        return cls()

    @staticmethod
    def hallo():
        return "hallo"

class Kind(Basis):
    pass

k = Kind.erzeuge()
print(type(k).__name__, Basis.erzeuge().__class__.__name__, k.hallo())
  • A: Kind Basis hallo

  • B: Basis Basis hallo

  • C: Kind Kind hallo

  • D: Kind Basis TypeError

Trage den Buchstaben als String ein, z. B. "B".

Welches Objekt bekommt cls, wenn du die Klassenmethode über Kind aufrufst, obwohl sie in Basis steht? Und darf man eine statische Methode über eine Instanz aufrufen?

Frage 9

Einfachauswahl

Was gibt der Code aus? Die Zeilen der Ausgabe sind in den Antworten mit / getrennt.

from abc import ABC, abstractmethod

class Form(ABC):
    @abstractmethod
    def flaeche(self): ...

    @abstractmethod
    def name(self): ...

class Quadrat(Form):
    def flaeche(self):
        return 4

class Ohne:
    @abstractmethod
    def x(self): ...

for k in (Quadrat, Ohne):
    try:
        k()
        print(k.__name__, "ok")
    except TypeError:
        print(k.__name__, "TypeError")
  • A: Quadrat TypeError / Ohne ok

  • B: Quadrat ok / Ohne ok

  • C: Quadrat TypeError / Ohne TypeError

  • D: Quadrat ok / Ohne TypeError

Trage den Buchstaben als String ein, z. B. "B".

Zwei Dinge entscheiden: Hat Quadrat wirklich alle abstrakten Methoden überschrieben? Und wer sorgt in Python überhaupt dafür, dass @abstractmethod etwas bewirkt?

Frage 10

Einfachauswahl

Was gibt der Code aus? Die Zeilen der Ausgabe sind in den Antworten mit / getrennt.

class Konto:
    def __init__(self, stand):
        self._stand = stand

    @property
    def stand(self):
        return self._stand

    @stand.setter
    def stand(self, v):
        if v < 0:
            raise ValueError("negativ")
        self._stand = v

k = Konto(-5)
try:
    k.stand = -1
except ValueError:
    print("Fehler")
print(k.stand)
  • A: Programmabbruch mit ValueError bei Konto(-5)

  • B: Fehler / -5

  • C: Fehler / -1

  • D: Fehler / None

Trage den Buchstaben als String ein, z. B. "B".

Welche Zeile im __init__ ruft den Setter auf, und welche umgeht ihn? Und wann wird in einem Setter der Wert tatsächlich gespeichert?

Frage 11

Einfachauswahl

Was gibt der Code aus? Die Zeilen der Ausgabe sind in den Antworten mit / getrennt.

class Spur(list):
    def append(self, x):
        print("append", x)
        super().append(x)

s = Spur()
s.append(1)
s.extend([2, 3])
s += [4]
print(s)
  • A: append 1 / [1, 2, 3, 4]

  • B: append 1 / append 2 / append 3 / append 4 / [1, 2, 3, 4]

  • C: append 1 / append 2 / append 3 / [1, 2, 3, 4]

  • D: append 1 / [1]

Trage den Buchstaben als String ein, z. B. "B".

Überlege, ob die eingebauten Methoden extend und += intern deine überschriebene Methode benutzen oder ihre eigene Implementierung.

Frage 12

Mehrfachauswahl, wähle zwei Antworten

Gegeben ist der Code unten. Welche zwei Aussagen sind richtig? (Das Dict fehler enthält nach der Schleife die gefangenen Exceptions.)

def lade():
    try:
        {}["port"]
    except KeyError as e:
        raise RuntimeError("Konfig") from e

def lade2():
    try:
        1 / 0
    except ZeroDivisionError:
        raise ValueError("neu")

def lade3():
    try:
        1 / 0
    except ZeroDivisionError:
        raise ValueError("neu") from None

fehler = {}
for f in (lade, lade2, lade3):
    try:
        f()
    except Exception as ex:
        fehler[f.__name__] = ex
  • A: In lade ist __cause__ die ursprüngliche KeyError.

  • B: In lade3 ist __context__ None, weil from None den Kontext löscht.

  • C: In lade2 steht die ZeroDivisionError in __context__, und __cause__ ist None.

  • D: In lade2 ist __cause__ die ZeroDivisionError.

Trage die beiden Buchstaben als String ein, alphabetisch, z. B. "AC".

raise ... from e setzt ausdrücklich __cause__. Es gibt zwei Attribute, die eine Verkettung festhalten, und sie werden auf unterschiedlichen Wegen gesetzt. Prüfe bei jeder Aussage, welches Attribut gemeint ist und was from None damit tatsächlich macht.

Frage 13

Einfachauswahl

Was gibt der Code aus? Die beiden Zeilen der Ausgabe sind in den Antworten mit / getrennt.

import copy

a = [[1, 2], [3]]
b = copy.copy(a)
c = copy.deepcopy(a)
a[0].append(99)
a.append([4])
print(b)
print(c)
  • A: [[1, 2, 99], [3], [4]] / [[1, 2], [3]]

  • B: [[1, 2], [3]] / [[1, 2], [3]]

  • C: [[1, 2], [3]] / [[1, 2, 99], [3]]

  • D: [[1, 2, 99], [3]] / [[1, 2], [3]]

Trage den Buchstaben als String ein, z. B. "B".

Eine flache Kopie legt einen neuen äußeren Container an. Was teilen sich a und b danach noch, und was nicht? Beachte beide Änderungen an a.

Frage 14

Mehrfachauswahl, wähle zwei Antworten

Gegeben ist der Code unten. Welche zwei Aussagen sind richtig?

import pickle

daten = {"a": [1, 2, 3], "t": (1, 2)}
blob = pickle.dumps(daten)
zurueck = pickle.loads(blob)
  • A: blob ist ein str, damit man ihn bequem als Text speichern kann.

  • B: zurueck == daten, und das Tupel bleibt ein Tupel.

  • C: pickle.loads ist ungefährlich, solange die Bytes ein gültiges Pickle sind, auch aus fremden Quellen.

  • D: Ein Lambda lässt sich nicht pickeln: pickle.dumps(lambda: 1) scheitert.

Trage die beiden Buchstaben als String ein, alphabetisch, z. B. "AC".

Denke an den Datentyp von blob, an das, was mit dem Tupel beim Rückweg passiert (anders als bei JSON), und an Dinge, die sich nicht in Bytes verwandeln lassen.

Frage 15

Einfachauswahl

Was gibt der Code aus?

class Meta(type):
    def __new__(mcs, name, bases, ns):
        ns["erzeugt_von"] = "Meta"
        return super().__new__(mcs, name, bases, ns)

class A(metaclass=Meta):
    pass

class B(A):
    pass

Dog = type("Dog", (), {"laut": "Wuff"})
print(A.erzeugt_von, type(B) is Meta, type(Meta).__name__, Dog().laut, A.__class__.__name__)
  • A: Meta True type Wuff Meta

  • B: Meta False type Wuff type

  • C: Meta True Meta Wuff Meta

  • D: Meta True type Wuff type

Trage den Buchstaben als String ein, z. B. "B".

Eine Metaklasse ist die Klasse einer Klasse. Überlege, was type(B) ist, wenn B von einer Klasse erbt, die eine Metaklasse hat, und was type selbst als Klasse ist.

Block 2: Coding-Konventionen, Best Practices, Standardisierung (12 %, 7 Fragen)

Stoff: Lektion 14. Fragen 16, 17, 18, 19, 20, 21, 22.

Frage 16

Einfachauswahl

Welche Aussage zu PEP 20 stimmt?

  • A: PEP 20 ist “The Zen of Python” mit 20 ausgeschriebenen Leitsätzen, abrufbar mit import this.

  • B: PEP 20 ist der “Style Guide for Python Code” und regelt Einrückung und Zeilenlänge.

  • C: PEP 20 beschreibt die Konventionen für Docstrings und heißt “Docstring Conventions”.

  • D: PEP 20 ist “The Zen of Python” mit 19 ausgeschriebenen Leitsätzen, abrufbar mit import this.

Trage den Buchstaben als String ein, z. B. "B".

PEP 20 ist keiner der PEPs für Stil oder Docstrings. Er hat einen eigenen Namen und lässt sich mit einem Import anzeigen. Die Zahl der ausgeschriebenen Leitsätze ist eine Falle: Lies die Zahlen in den Optionen genau.

Frage 17

Mehrfachauswahl, wähle zwei Antworten

Welche zwei Zeilen folgen den Namenskonventionen von PEP 8?

  • A: class ShoppingCart: ...

  • B: def ComputeTotal(self): ...

  • C: class config_error(Exception): ...

  • D: MAX_SIZE = 100

Trage die beiden Buchstaben als String ein, alphabetisch, z. B. "AC".

Klassen, Funktionen und Konstanten haben je ein eigenes Schema. Vergleiche, wie jeder Name geschrieben ist: CapWords, Kleinbuchstaben mit Unterstrichen oder Großbuchstaben mit Unterstrichen.

Frage 18

Mehrfachauswahl, wähle zwei Antworten

Welche zwei Zeilen entsprechen PEP 8?

  • A: def f(a: int=1): ...

  • B: def f(a: int = 1): ...

  • C: x = f(a=1)

  • D: x = f( a = 1 )

Trage die beiden Buchstaben als String ein, alphabetisch, z. B. "AC".

PEP 8 unterscheidet bei = in der Klammer, ob eine Annotation (Typangabe) dabei ist oder nicht. Außerdem steht nichts direkt hinter der öffnenden und vor der schließenden Klammer.

Frage 19

Einfachauswahl

Gegeben ist der Code unten. Welche Aussage stimmt?

class Immer:
    def __eq__(self, other):
        return True

x = Immer()
  • A: x is None ist True, weil __eq__ immer True liefert.

  • B: is lässt sich wie == überschreiben, nämlich über eine Methode __is__.

  • C: x == None ist True, x is None ist False. Darum verlangt PEP 8 is None.

  • D: PEP 8 bevorzugt == None, weil es auch bei eigenen Klassen funktioniert.

Trage den Buchstaben als String ein, z. B. "B".

== ruft __eq__ auf, und das darf die Klasse selbst festlegen. Kann eine Klasse das Verhalten von is auch selbst festlegen? Probiere beide Ausdrücke im Kopf mit dem Immer-Objekt durch.

Frage 20

Einfachauswahl

Was gibt der Code aus?

def f():
    x = 1
    """Return x."""
    return x

def g():
    """Return 2."""
    return 2

print(f.__doc__, g.__doc__)
  • A: None Return 2.

  • B: Return x. Return 2.

  • C: None None

  • D: Return x. None

Trage den Buchstaben als String ein, z. B. "B".

Ein Docstring ist nicht jedes Zeichenkettenliteral in einer Funktion. Lies die Definition: wo genau muss er stehen?

Frage 21

Einfachauswahl

Was gibt der Code aus?

def verdopple(x: int) -> int:
    return x * 2

print(verdopple("ab"), verdopple.__annotations__)
  • A: Abbruch: TypeError

  • B: abab {}

  • C: abab {'x': <class 'int'>, 'return': <class 'int'>}

  • D: abab {'x': 'int', 'return': 'int'}

Trage den Buchstaben als String ein, z. B. "B".

Wer prüft in Python die Annotationen: der Interpreter beim Aufruf, oder Werkzeuge wie mypy? Und was liegt in __annotations__: Klassen oder Strings?

Frage 22

Mehrfachauswahl, wähle zwei Antworten

Welche zwei Aussagen zu Werkzeugen aus dem PCPP1-Umfeld stimmen?

  • A: mypy prüft Typannotationen nach PEP 484, ohne das Programm auszuführen.

  • B: isort sortiert die Imports einer Datei automatisch.

  • C: flake8 formatiert den Code automatisch um, bis er PEP 8 entspricht.

  • D: pycodestyle prüft Typannotationen und ersetzt damit mypy.

Trage die beiden Buchstaben als String ein, alphabetisch, z. B. "AC".

Unterscheide drei Rollen: ein Prüfer meldet Verstöße, ein Formatierer ändert den Code selbst, ein Typprüfer liest die Annotationen. Ordne jedes Werkzeug seiner Rolle zu.

Block 3: GUI-Programmierung (tkinter) (20 %, 8 Fragen)

Stoff: Lektion 15. Fragen 23, 24, 25, 26, 27, 28, 29, 30.

Frage 23

Einfachauswahl

Was passiert beim Ausführen dieses Programms? (Die Ausgabe ist die Meldung der Exception beziehungsweise ok.)

import tkinter as tk

root = tk.Tk()
b = tk.Button(root, text="OK").pack()
try:
    b.config(text="Neu")
    print("ok")
except AttributeError as e:
    print(e)
  • A: ok

  • B: 'Button' object has no attribute 'config'

  • C: 'NoneType' object has no attribute 'config'

  • D: 'tuple' object has no attribute 'config'

Trage den Buchstaben als String ein, z. B. "B".

Was liefert der Aufruf .pack() zurück? Und was steht deshalb nach der Zuweisung in b?

Frage 24

Einfachauswahl

Was gibt das Programm aus, wenn der Button über b.invoke() ausgelöst wird (so, als hätte jemand geklickt)? Die beiden Zeilen sind in den Antworten mit / getrennt.

import tkinter as tk

aufrufe = []

def speichern():
    aufrufe.append(1)

root = tk.Tk()
b = tk.Button(root, text="Speichern", command=speichern())
print(len(aufrufe))
b.invoke()
print(len(aufrufe))
  • A: 0 / 1

  • B: 1 / 1

  • C: 1 / 2

  • D: 0 / 0

Trage den Buchstaben als String ein, z. B. "B".

Achte auf die Klammern hinter speichern in der Zeile mit dem Button. Wann wird die Funktion dadurch aufgerufen, und was bekommt der Button als command?

Frage 25

Einfachauswahl

root = tk.Tk() ist in jeder Variante vorhanden. In welcher Variante löst das Programm einen TclError aus? (Der Check analysiert die Varianten mit dem Modul ast, ohne tkinter auszuführen.)

  • A:

    tk.Label(root, text="Name").pack()
    tk.Entry(root).pack()
    tk.Button(root, text="OK").grid(row=0, column=0)
  • B:

    tk.Label(root, text="Name").grid(row=0, column=0)
    tk.Entry(root).grid(row=0, column=1)
    tk.Button(root, text="OK").grid(row=1, column=0, columnspan=2)
  • C:

    rahmen = tk.Frame(root)
    rahmen.pack()
    tk.Label(rahmen, text="Name").grid(row=0, column=0)
    tk.Entry(rahmen).grid(row=0, column=1)
  • D:

    e = tk.Entry(root)
    e.pack()
    b = tk.Button(root, text="OK")
    b.pack()

Trage den Buchstaben als String ein, z. B. "B".

Die Regel gilt pro Container: Schau bei jedem Widget nach, in welchem Elternteil es liegt (erstes Argument oder die Zuweisung davor) und welcher Manager für dieses Elternteil benutzt wird.

Frage 26

Einfachauswahl

Welche Aussage zu den Variablenklassen von tkinter (StringVar, IntVar, …) stimmt?

  • A: Beobachter meldest du mit var.bind("<<Change>>", callback) an.

  • B: var.trace_add("write", callback) ruft callback bei jeder Änderung auf. Die ältere Form trace("w", ...) ist veraltet.

  • C: Ein Widget zeigt Änderungen der Variablen erst an, nachdem root.update() aufgerufen wurde.

  • D: trace_add gibt es nur bei StringVar, nicht bei IntVar oder BooleanVar.

Trage den Buchstaben als String ein, z. B. "B".

Denke an das Beobachter-Muster (Observer): Es gibt eine Methode, die bei jeder Änderung einen Callback aufruft. Ihr Name enthält den Hinweis, dass sie das Schreiben beobachtet.

Frage 27

Einfachauswahl

Wann wird danach im folgenden Programm ausgegeben?

import tkinter as tk

root = tk.Tk()
tk.Button(root, text="Ende", command=root.destroy).pack()
root.mainloop()
print("danach")
  • A: Sofort beim Start, weil mainloop() im Hintergrund läuft.

  • B: Erst nachdem das Fenster geschlossen wurde, hier durch den Klick auf den Button.

  • C: Nie, weil destroy() das Python-Programm hart beendet.

  • D: Nur wenn statt destroy die Methode quit benutzt wird.

Trage den Buchstaben als String ein, z. B. "B".

Was macht mainloop(), während das Fenster offen ist? Und was bewirkt destroy() mit der Event-Loop?

Frage 28

Einfachauswahl

In einer tkinter-Anwendung soll ein Label jede Sekunde die Uhrzeit aktualisieren, ohne dass die Oberfläche einfriert. Welche Lösung passt?

  • A: Eine Schleife while True: mit time.sleep(1) in einem Button-Handler.

  • B: Ein zweiter Aufruf von root.mainloop() innerhalb von tick.

  • C: root.bind("<Timer>", tick) registriert einen Sekundentakt.

  • D: Eine Funktion tick, die das Label setzt und sich mit root.after(1000, tick) selbst erneut einplant.

Trage den Buchstaben als String ein, z. B. "B".

Was passiert mit der Oberfläche, wenn ein Event-Handler lange läuft oder wartet? Welche Methode plant einen Aufruf, ohne die Event-Loop zu blockieren?

Frage 29

Einfachauswahl

Was gibt das Programm aus?

import tkinter as tk

root = tk.Tk()
a = tk.Entry(root)
b = tk.Entry(root)
a.insert(0, "2")
b.insert(0, "3")
print(a.get() + b.get())
  • A: 5

  • B: 23

  • C: TypeError

  • D: None

Trage den Buchstaben als String ein, z. B. "B".

Welchen Datentyp liefert get(), auch wenn im Feld Ziffern stehen? Was macht + mit diesem Typ?

Frage 30

Mehrfachauswahl, wähle zwei Antworten

Welche zwei Aussagen zu tkinter stimmen?

  • A: Für mehrere Fenster erzeugt man mehrere Tk()-Instanzen, eine pro Fenster.

  • B: pack und grid dürfen im selben Container gemischt werden, solange grid zuerst benutzt wird.

  • C: Ein PhotoImage braucht eine dauerhafte Referenz, sonst räumt der Garbage Collector das Bild weg.

  • D: Radiobuttons einer Gruppe teilen sich eine Variable, jeder Button hat einen eigenen value.

Trage die beiden Buchstaben als String ein, alphabetisch, z. B. "AC".

Gehe jede Aussage durch und frage dich: Was passiert mit einem Objekt, auf das keine Variable mehr zeigt? Wie unterscheiden sich Auswahlgruppen von Einzelwerten? Wie viele Hauptfenster darf es geben?

Block 4: Netzwerkprogrammierung (18 %, 8 Fragen)

Stoff: Lektion 16. Fragen 31, 32, 33, 34, 35, 36, 37, 38.

Frage 31

Einfachauswahl

Ein Client schickt nachricht.encode("utf-8") per sendall. Was gibt der folgende Code aus (er simuliert nur die Umwandlung, ohne Netzwerk)?

nachricht = "Ärger"
daten = nachricht.encode("utf-8")
print(len(nachricht), len(daten), daten.decode("utf-8") == nachricht)
  • A: 5 6 True

  • B: 5 5 True

  • C: 6 6 True

  • D: 5 6 False

Trage den Buchstaben als String ein, z. B. "B".

Zähle getrennt: Zeichen im String und Bytes in der UTF-8-Kodierung. Nicht jedes Zeichen braucht in UTF-8 genau ein Byte.

Frage 32

Einfachauswahl

Im folgenden Client-Code liefert s.recv(4096) irgendwann b"" (leere Bytes). Was bedeutet das?

data = b""
while True:
    chunk = s.recv(4096)
    if not chunk:
        break
    data += chunk
  • A: Im Moment sind keine Daten da. Die Schleife sollte es später noch einmal versuchen.

  • B: Das Zeitlimit von settimeout ist abgelaufen.

  • C: Es wurden genau 4096 Bytes gelesen, der Puffer ist daher leer.

  • D: Die Gegenseite hat die Verbindung geschlossen.

Trage den Buchstaben als String ein, z. B. "B".

Überlege, welche Signale ein TCP-Socket hat: Daten, einen Fehler wie ein Zeitlimit, und das Ende der Verbindung. Welches davon wird als leere Bytes gemeldet?

Frage 33

Einfachauswahl

Ein Messwert-Sender soll einzelne Datenpakete ohne Verbindungsaufbau und ohne Zustellgarantie verschicken. Welche Variante passt?

  • A: socket.socket(socket.AF_INET, socket.SOCK_STREAM) und danach sendto(daten, adresse)

  • B: socket.socket(socket.AF_INET, socket.SOCK_DGRAM) und danach connect(...), accept()

  • C: socket.socket(socket.AF_INET, socket.SOCK_STREAM) und danach sendall(daten)

  • D: socket.socket(socket.AF_INET, socket.SOCK_DGRAM) und danach sendto(daten, adresse)

Trage den Buchstaben als String ein, z. B. "B".

Ordne zuerst zu, welcher Socket-Typ verbindungsorientiert ist und welcher nicht. Dann: Welche Sendemethode braucht eine Zieladresse bei jedem Paket?

Frage 34

Mehrfachauswahl, wähle zwei Antworten

Welche zwei Zuordnungen von Statuscode und Bedeutung stimmen?

  • A: 204 heißt “No Content”: Erfolg ohne Antwortinhalt.

  • B: 401 heißt “verboten” (Forbidden).

  • C: 503 heißt “Dienst nicht verfügbar” und ist ein Serverfehler.

  • D: 301 und 302 sind Clientfehler (4xx).

Trage die beiden Buchstaben als String ein, alphabetisch, z. B. "AC".

Die erste Ziffer gibt die Klasse an: 2xx Erfolg, 3xx Umleitung, 4xx Fehler des Clients, 5xx Fehler des Servers. Dann unterscheiden sich 401 und 403 in einem Detail.

Frage 35

Einfachauswahl

Was gibt der Code aus?

import json

daten = {"name": "Ada", 1: None, "tags": ("a", "b"), "ok": True}
print(json.loads(json.dumps(daten)))
  • A: {'name': 'Ada', 1: None, 'tags': ['a', 'b'], 'ok': True}

  • B: {'name': 'Ada', '1': None, 'tags': ('a', 'b'), 'ok': True}

  • C: {'name': 'Ada', '1': None, 'tags': ['a', 'b'], 'ok': True}

  • D: {'name': 'Ada', '1': 'null', 'tags': ['a', 'b'], 'ok': 'true'}

Trage den Buchstaben als String ein, z. B. "B".

Betrachte jeden Eintrag einzeln: Was wird aus einem int-Schlüssel, aus einem Tupel, aus None und aus True, wenn der Text durch JSON gegangen ist?

Frage 36

Einfachauswahl

Was gibt der Code aus? Die beiden Zeilen der Ausgabe sind in den Antworten mit / getrennt.

import json

try:
    json.loads("{'a': 1}")
except TypeError:
    print("T1")
except ValueError:
    print("V1")

try:
    json.dumps({1, 2})
except ValueError:
    print("V2")
except TypeError:
    print("T2")
  • A: T1 / T2

  • B: V1 / V2

  • C: V1 / T2

  • D: T1 / V2

Trage den Buchstaben als String ein, z. B. "B".

Bei jedem Teil gibt es einen anderen Auslöser: einen Text, der kein gültiges JSON ist, und ein Objekt, das sich nicht serialisieren lässt. Welche Klasse gehört zu welchem?

Frage 37

Einfachauswahl

Was gibt der Code aus?

import xml.etree.ElementTree as ET

dokumente = [
    "<a><b/></a>",
    "<a><b></a></b>",
    "<a x=1/>",
    "<a/><b/>",
]
ergebnis = []
for d in dokumente:
    try:
        ET.fromstring(d)
        ergebnis.append("ok")
    except ET.ParseError:
        ergebnis.append("Fehler")
print(ergebnis)
  • A: ['ok', 'Fehler', 'Fehler', 'Fehler']

  • B: ['ok', 'Fehler', 'ok', 'Fehler']

  • C: ['ok', 'Fehler', 'Fehler', 'ok']

  • D: ['ok', 'ok', 'Fehler', 'Fehler']

Trage den Buchstaben als String ein, z. B. "B".

Wohlgeformt (well-formed) heißt: genau ein Wurzelelement, korrekt verschachtelte und geschlossene Tags, Attributwerte in Anführungszeichen. Prüfe jedes Dokument gegen diese Liste.

Frage 38

Mehrfachauswahl, wähle zwei Antworten

Welche zwei Aussagen zum Drittpaket requests stimmen?

  • A: Ein Statuscode 404 löst automatisch eine requests.exceptions.HTTPError aus.

  • B: requests.post(url, json=daten) serialisiert daten als JSON und setzt den Content-Type.

  • C: Ohne timeout bricht requests eine Anfrage nach 5 Sekunden ab.

  • D: r.raise_for_status() löst bei den Codes 4xx und 5xx einen HTTPError aus.

Trage die beiden Buchstaben als String ein, alphabetisch, z. B. "AC".

Unterscheide, was requests selbst entscheidet (Serialisierung, Zeitlimit) und was erst passiert, wenn du es verlangst (Fehler bei 4xx und 5xx).

Block 5: Dateiverarbeitung und Umgebung (15 %, 7 Fragen)

Stoff: Lektionen 17 und 18. Fragen 39, 40, 41, 42, 43, 44, 45.

Frage 39

Einfachauswahl

Was gibt der Code aus? Die drei Zeilen der Ausgabe sind in den Antworten mit / getrennt.

import sqlite3

conn = sqlite3.connect(":memory:")
conn.execute("CREATE TABLE t (x INTEGER NOT NULL)")
try:
    with conn:
        conn.execute("INSERT INTO t VALUES (1)")
        conn.execute("INSERT INTO t VALUES (NULL)")
except sqlite3.IntegrityError:
    print("Fehler")
print(conn.execute("SELECT COUNT(*) FROM t").fetchone())
print(conn.execute("SELECT 1").fetchone())
  • A: Fehler / (1,) / (1,)

  • B: Fehler / (0,) / (1,)

  • C: Fehler / (0,) / ProgrammingError

  • D: Fehler / 0 / 1

Trage den Buchstaben als String ein, z. B. "B".

Was macht with conn: bei einer Exception im Block: bestätigen oder zurückrollen? Und schließt es die Verbindung? fetchone() liefert übrigens eine Zeile, und eine Zeile ist ein Tupel.

Frage 40

Einfachauswahl

Die Variable name enthält die Benutzereingabe x' OR '1'='1. Welcher Aufruf läuft fehlerfrei und liefert nur passende Zeilen (hier: keine), ist also nicht per Injection angreifbar? (Der Check führt jede Variante gegen eine Testtabelle mit Ada und Bob aus.)

  • A: cur.execute(f"SELECT name FROM users WHERE name = '{name}'")

  • B: cur.execute("SELECT name FROM users WHERE name = ?", name)

  • C: cur.execute("SELECT name FROM users WHERE name = %s", (name,))

  • D: cur.execute("SELECT name FROM users WHERE name = ?", (name,))

Trage den Buchstaben als String ein, z. B. "B".

Die Platzhalter-Schreibweise von sqlite3 ist ein Fragezeichen. Und was genau übergibst du als zweites Argument von execute: den Wert selbst oder eine Folge von Werten? Prüfe, wie Python ("a") liest.

Frage 41

Einfachauswahl

Was gibt der Code aus?

import csv
import io

buf = io.StringIO()
w = csv.writer(buf)
w.writerow(["name", "age"])
w.writerow(["Ada", 36])
buf.seek(0)
print(list(csv.DictReader(buf)))
  • A: [{'name': 'Ada', 'age': 36}]

  • B: [['name', 'age'], ['Ada', '36']]

  • C: [('Ada', '36')]

  • D: [{'name': 'Ada', 'age': '36'}]

Trage den Buchstaben als String ein, z. B. "B".

Was weiß eine Textdatei über Zahlen? Überlege, welchen Typ age nach dem Zurücklesen hat, und wie DictReader die erste Zeile verwendet.

Frage 42

Einfachauswahl

Was gibt der Code aus?

import xml.etree.ElementTree as ET

root = ET.fromstring("<lib><book id='1'><title>Python</title></book></lib>")
buch = root.find("book")
print(root.find("title"), root.find(".//title").text, buch.get("id"), type(buch.get("id")).__name__)
  • A: <Element 'title' at 0x7f> Python 1 str

  • B: None Python 1 int

  • C: None Python 1 str

  • D: AttributeError

Trage den Buchstaben als String ein, z. B. "B".

find mit einem einfachen Namen sucht nur direkte Kinder. Für tiefer verschachtelte Elemente braucht der Pfad eine andere Schreibweise. Und was ist der Typ eines Attributwerts?

Frage 43

Einfachauswahl

Was gibt der Code aus?

import io
import logging

buf = io.StringIO()
handler = logging.StreamHandler(buf)
handler.setLevel(logging.ERROR)
logger = logging.getLogger("probe.zwei")
logger.setLevel(logging.DEBUG)
logger.propagate = False
logger.addHandler(handler)

logger.debug("d")
logger.warning("w")
logger.error("e")
logger.removeHandler(handler)
print(buf.getvalue().split())
  • A: ['d', 'w', 'e']

  • B: ['w', 'e']

  • C: ['e']

  • D: []

Trage den Buchstaben als String ein, z. B. "B".

Eine Meldung muss zwei Prüfungen bestehen, nacheinander. Welche beiden Level sind hier gesetzt, und welche Meldung besteht beide?

Frage 44

Einfachauswahl

Was gibt der Code aus?

import configparser

cfg = configparser.ConfigParser()
cfg.read_string("[DEFAULT]\ntimeout = 30\n[app]\ndebug = yes\nname = demo\n")
print(cfg.getint("app", "timeout"), cfg.getboolean("app", "debug"),
      repr(cfg["app"]["timeout"]), cfg.read("gibt_es_nicht.ini"))
  • A: 30 True '30' []

  • B: 30 True 30 []

  • C: 30 True '30' FileNotFoundError

  • D: KeyError

Trage den Buchstaben als String ein, z. B. "B".

Vier Teile: Woher kommt timeout für den Abschnitt app? Was versteht getboolean unter yes? Welchen Typ hat der Zugriff mit eckigen Klammern? Und wie reagiert read auf eine fehlende Datei?

Frage 45

Einfachauswahl

Was gibt der Code aus?

import sqlite3

conn = sqlite3.connect(":memory:")
cur = conn.cursor()
cur.execute("CREATE TABLE t (x INTEGER)")
cur.executemany("INSERT INTO t VALUES (?)", [(1,), (2,), (3,)])
cur.execute("SELECT x FROM t ORDER BY x")
print(cur.fetchone(), cur.fetchall(), cur.fetchone())
  • A: (1,) [(1,), (2,), (3,)] None

  • B: (1,) [(2,), (3,)] None

  • C: 1 [2, 3] None

  • D: (1,) [(2,), (3,)] (1,)

Trage den Buchstaben als String ein, z. B. "B".

Ein Cursor merkt sich, wie weit er gelesen hat. Was bleibt nach fetchone() für fetchall() übrig, und was für den nächsten fetchone()? Wie sieht eine einzelne Zeile aus?

Auswertungshilfe

Trage nach jedem Block ein, wie viele Fragen du vollständig richtig hattest. Rechne danach den Prozentwert aus (Richtige geteilt durch Fragen mal 100).

Block Fragen Gewicht Meine Richtigen Prozent
1 Fortgeschrittene OOP 15 35 % ____ ____
2 Konventionen (PEPs) 7 12 % ____ ____
3 GUI (tkinter) 8 20 % ____ ____
4 Netzwerk 8 18 % ____ ____
5 Dateien und Umgebung 7 15 % ____ ____
Gesamt 45 100 % ____ ____

Bestanden wäre die Probeprüfung ab 32 richtigen Antworten (70 %). Für die PCAP nennt das Glossar als Buchungsrichtwert “konstant über 85 % in Probetests”. Für die PCPP1 steht keine eigene Zahl in der Quelle, übertrage den Richtwert nur als eigene Annahme (bitte prüfen). 85 % von 45 Fragen wären 38,25, also 39 richtige.

Beispiel: Block 1 mit 9 von 15 richtig sind 9 geteilt durch 15 mal 100, also 60 %. Das liegt unter 70 %, Block 1 steht auf deiner Wiederholungsliste.

So liest du das Ergebnis (eigene Faustregel, keine Vorgabe der Quelle):

Ergebnis Was es bedeutet Nächster Schritt
unter 32 richtig Du würdest die Probe nicht bestehen Schwache Blöcke wiederholen (Tabelle unten), danach nach einer Woche eine neue Probe mit eigenen Fragen
32 bis 38 richtig Bestanden, aber knapp Fehlerliste durchgehen, vor allem Blöcke unter 70 %
39 oder mehr richtig Über dem übertragenen 85-%-Richtwert Buchung planen, vorher noch einmal die Fehlerliste wiederholen

Zwei Dinge relativieren das Ergebnis: Du hast die Fragen jetzt einmal gesehen, ein zweiter Durchlauf sagt wenig. Und die Fragen sind selbst geschrieben, sie ersetzen keinen offiziellen Test. Zähle auch, bei wie vielen Fragen du zuerst falsch lagst, weil du die Anzahl der Antworten übersehen hast. Das ist ein Lesefehler, kein Wissensfehler.

Was du bei schwachen Blöcken wiederholst

Block Wiederhole Typische Schwachstelle
1 Lektion 11a, Lektion 11b, Lektion 12a, Lektion 12b, Lektion 13a, Lektion 13b Magic Methods (__hash__, __radd__, __getattr__), MRO und super(), Reihenfolge gestapelter Dekoratoren, Setter im __init__, Exception-Verkettung, flache und tiefe Kopien
2 Lektion 14 PEP-Nummern, Namensschemata, Leerzeichen bei =, Docstring als erste Anweisung, Hints sind keine Laufzeitprüfung
3 Lektion 15a, Lektion 15b pack() liefert None, command=f(), pack und grid pro Container, mainloop() blockiert, after statt sleep
4 Lektion 16a, Lektion 16b Bytes statt Strings, leere Bytes bei recv, TCP und UDP, Statuscodes, JSON-Typabbildung, wohlgeformt statt gültig, requests
5 Lektion 17, Lektion 18a, Lektion 18b with conn, Platzhalter ?, Cursor, CSV-Werte als Strings, find und None, zwei Level-Prüfungen bei logging, configparser

Für jede falsch beantwortete Frage: Eintrag in die Fehlerliste (ein Satz, warum), nach einer Woche wiederholen. Zur Frage gehört jeweils die Lektion in dieser Übersicht:

Frage Thema Lektion
1 Reflexion: isinstance, issubclass 11a
2 __add__, __radd__ und NotImplemented 11a
3 __eq__ ohne __hash__ 11a
4 __getattr__ und __getattribute__ 11b
5 MRO und kooperatives super() 11b
6 Gestapelte Dekoratoren 12a
7 Dekorator mit Argumenten, functools.wraps 12a
8 classmethod und staticmethod bei Vererbung 12a
9 Abstrakte Klassen, ABC 12b
10 Properties: Setter im __init__ 12b
11 Eingebaute Klassen beerben (list) 12b
12 Exception-Verkettung: __cause__ und __context__ 13a
13 Flache und tiefe Kopien 13a
14 pickle: Serialisierung und Grenzen 13b
15 Metaklassen 13b
16 PEP 20 (Zen of Python) 14
17 PEP 8: Namenskonventionen 14
18 PEP 8: Leerzeichen bei Defaults und Schlüsselwortargumenten 14
19 PEP 8: is None statt == None 14
20 PEP 257: Docstring als erste Anweisung 14
21 PEP 484: Type Hints zur Laufzeit 14
22 Werkzeuge: Linter, Formatierer, Typprüfer 14
23 pack() liefert None 15
24 command=funktion() statt command=funktion 15
25 pack und grid im selben Container 15
26 Beobachtbare Variablen 15
27 mainloop() blockiert, destroy() beendet 15
28 Timer mit after() 15
29 Entry.get() liefert immer einen String 15
30 PhotoImage, Radiobutton, Tk und Toplevel, pack und grid 15a, 15b
31 Sockets übertragen Bytes (encode/decode) 16
32 recv liefert leere Bytes 16
33 TCP und UDP 16
34 HTTP-Statuscodes 16
35 JSON: Typabbildung Dict und Tupel 16
36 JSON: Fehlerklassen 16
37 XML: wohlgeformt 16
38 requests: json=, raise_for_status, timeout 16
39 sqlite3: with conn bei Fehler 17
40 sqlite3: Platzhalter und SQL-Injection 17
41 csv: DictReader liefert Strings 17
42 ElementTree: find, Pfade und Attribute 17
43 logging: Logger-Level und Handler-Level 18
44 configparser: Strings, DEFAULT, fehlende Datei 18
45 sqlite3: fetchone, fetchall und der Cursor 17

Die Karteikarten zu den schwierigsten Fragen liegen in karteikarten/python-20-pcpp1-probepruefung.md.


Quelle: quellen/python-glossar-pcap-pcpp1.md, Abschnitt “Teil 2: PCPP1 Überblick” (Prüfungsdaten, Blöcke, Fragenzahl und Gewichte, Stand 1. Oktober 2026) sowie die Abschnitte “PCPP1 Block 1” bis “PCPP1 Block 5”. Alle Fragen sind durch den Stoff der Lektionen 11 bis 18 und die genannten Glossarabschnitte gedeckt. Prüfungsdaten (Kosten, Version, Gewichtung, ob gewichtet gewertet wird) bitte vor der Buchung auf der offiziellen Seite prüfen.