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
- 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.
- 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.
- 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.
- Die Lösungen sind auf dieser Seite ausgeblendet. Das Feedback des Checks zeigt dir die Erklärung zu jeder Option, auch zu den falschen.
- Am Ende trägst du die Punkte pro Block in die Auswertungshilfe ein.
- 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) == TierD:
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 / TypeErrorB:
Meter(3) / Meter(8) / Meter(3)C:
Meter(3) / Meter(8) / TypeErrorD:
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 / 2B:
True / TypeErrorC:
True / 1D:
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.xA:
getattr x / getattr y / getattribute xB:
getattr yC:
getattr x / getattr yD:
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 fB:
dek b / dek a / run a / run b / run fC:
dek b / dek a / run b / run a / run fD:
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 " + nameA:
gruss.__name__ist"wrapper", weil der Dekorator die Funktion ersetzt.B:
@wiederhole(2)entsprichtgruss = 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 halloB:
Basis Basis halloC:
Kind Kind halloD:
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 okB:
Quadrat ok / Ohne okC:
Quadrat TypeError / Ohne TypeErrorD:
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 / -5C:
Fehler / -1D:
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__] = exA: In
ladeist__cause__die ursprünglicheKeyError.B: In
lade3ist__context__None, weilfrom Noneden Kontext löscht.C: In
lade2steht dieZeroDivisionErrorin__context__, und__cause__istNone.D: In
lade2ist__cause__dieZeroDivisionError.
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:
blobist einstr, damit man ihn bequem als Text speichern kann.B:
zurueck == daten, und das Tupel bleibt ein Tupel.C:
pickle.loadsist 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 MetaB:
Meta False type Wuff typeC:
Meta True Meta Wuff MetaD:
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 NoneistTrue, weil__eq__immerTrueliefert.B:
islässt sich wie==überschreiben, nämlich über eine Methode__is__.C:
x == NoneistTrue,x is NoneistFalse. Darum verlangt PEP 8is 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 NoneD:
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: TypeErrorB:
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:
mypyprüft Typannotationen nach PEP 484, ohne das Programm auszuführen.B:
isortsortiert die Imports einer Datei automatisch.C:
flake8formatiert den Code automatisch um, bis er PEP 8 entspricht.D:
pycodestyleprüft Typannotationen und ersetzt damitmypy.
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:
okB:
'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 / 1B:
1 / 1C:
1 / 2D:
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)ruftcallbackbei jeder Änderung auf. Die ältere Formtrace("w", ...)ist veraltet.C: Ein Widget zeigt Änderungen der Variablen erst an, nachdem
root.update()aufgerufen wurde.D:
trace_addgibt es nur beiStringVar, nicht beiIntVaroderBooleanVar.
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
destroydie Methodequitbenutzt 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:mittime.sleep(1)in einem Button-Handler.B: Ein zweiter Aufruf von
root.mainloop()innerhalb vontick.C:
root.bind("<Timer>", tick)registriert einen Sekundentakt.D: Eine Funktion
tick, die das Label setzt und sich mitroot.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:
5B:
23C:
TypeErrorD:
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:
packundgriddürfen im selben Container gemischt werden, solangegridzuerst benutzt wird.C: Ein
PhotoImagebraucht 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 TrueB:
5 5 TrueC:
6 6 TrueD:
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 += chunkA: Im Moment sind keine Daten da. Die Schleife sollte es später noch einmal versuchen.
B: Das Zeitlimit von
settimeoutist 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 danachsendto(daten, adresse)B:
socket.socket(socket.AF_INET, socket.SOCK_DGRAM)und danachconnect(...),accept()C:
socket.socket(socket.AF_INET, socket.SOCK_STREAM)und danachsendall(daten)D:
socket.socket(socket.AF_INET, socket.SOCK_DGRAM)und danachsendto(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:
204heißt “No Content”: Erfolg ohne Antwortinhalt.B:
401heißt “verboten” (Forbidden).C:
503heißt “Dienst nicht verfügbar” und ist ein Serverfehler.D:
301und302sind 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 / T2B:
V1 / V2C:
V1 / T2D:
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
404löst automatisch einerequests.exceptions.HTTPErroraus.B:
requests.post(url, json=daten)serialisiertdatenals JSON und setzt den Content-Type.C: Ohne
timeoutbrichtrequestseine Anfrage nach 5 Sekunden ab.D:
r.raise_for_status()löst bei den Codes 4xx und 5xx einenHTTPErroraus.
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,) / ProgrammingErrorD:
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 strB:
None Python 1 intC:
None Python 1 strD:
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' FileNotFoundErrorD:
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,)] NoneB:
(1,) [(2,), (3,)] NoneC:
1 [2, 3] NoneD:
(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.