Keksdose
Aufgabe
Quelle: Sesame Street
Stellen Sie sich vor, Sie möchten eine Keksdose implementieren, in der Kekse aufbewahrt werden. Erstellen Sie dazu eine Datei namens jar.py
in einem Ordner namens jar
und implementieren Sie darin eine Klasse Jar
mit den folgenden Methoden:
__init__
- Initialisiert die Keksdose mit einer maximalen Kapazität (
capacity
). - Die Kapazität legt fest, wie viele Kekse maximal hineinpassen.
- Wenn die angegebene
capacity
kein positiverint
ist, soll einValueError
ausgelöst werden.
- Initialisiert die Keksdose mit einer maximalen Kapazität (
__str__
- Gibt einen String zurück, der die Kekse in der Dose darstellt.
- Beispiel: Wenn
3
Kekse in der Keksdose sein, soll die Methode"🍪🍪🍪"
zurückgeben.
deposit
- Legt zusätzliche
n
Kekse in die Keksdose. - Wenn dadurch die Kapazität der Keksdose überschritten wird, soll ein
ValueError
ausgelöst werden.
- Legt zusätzliche
withdraw
- Nimmt
n
Kekse aus der Keksdose. Nom nom nom. - Wenn weniger Kekse in der Dose sind, als entfernt werden sollen, soll ein
ValueError
ausgelöst werden.
- Nimmt
capacity
- Gibt die maximale Kapazität der Keksdose zurück.
size
- Gibt die aktuelle Anzahl der Kekse in der Keksdose zurück (zu Beginn
0
).
- Gibt die aktuelle Anzahl der Kekse in der Keksdose zurück (zu Beginn
Strukturieren Sie Ihre Klasse wie unten beschrieben. Sie dürfen die Parameter dieser Methoden nicht ändern, aber Sie können Ihre eigenen Methoden hinzufügen.
class Jar:
def __init__(self, capacity=12):
...
def __str__(self):
...
def deposit(self, n):
...
def withdraw(self, n):
...
@property
def capacity(self):
...
@property
def size(self):
...
Entweder vor oder nach der Implementierung von jar.py
implementieren Sie zusätzlich in einer Datei namens test_jar.py
vier oder mehr Funktionen, die Ihre Jar-Implementierung gemeinsam gründlich testen. Deren Name sollte jeweils mit test_
beginnen, damit Sie Ihre Tests mit folgendem ausführen können:
pytest test_jar.py
Das Testen von Instanzmethoden ist oft komplexer als das Testen von eigenständigen Funktionen, da Instanzmethoden den “Zustand” der Instanz (also die Instanzvariablen) verändern können. Um eine Methode wie withdraw
zu testen, müssen Sie möglicherweise zuerst eine andere Methode wie deposit
aufrufen, um den notwendigen Zustand herzustellen. Wenn jedoch die zuerst aufgerufene Methode fehlerhaft ist, kann dies den Test der zweiten Methode verfälschen.
Aus diesem Grund nutzen Programmierer beim Testen von Methoden Mocking (mock
) (eine Simulation des Zustands). Mit Tools wie Pythons Mock-Objektbibliothek können sie den Zustand einer Instanz direkt ändern, ohne eine andere Methode aufrufen zu müssen. So lassen sich Methoden isoliert testen.
Für Ihre Tests ist dies jedoch nicht notwendig. Sie können die Methoden wie gewohnt testen, ohne den Status zu simulieren!
Eine genauere Beschreibung, wie Sie beim schreiben von Tests vorgehen können, finden Sie weiter unten in der Sektion Testen.
Tipps
from jar import Jar
def test_init():
...
def test_str():
jar = Jar()
assert str(jar) == ""
jar.deposit(1)
assert str(jar) == "🍪"
jar.deposit(11)
assert str(jar) == "🍪🍪🍪🍪🍪🍪🍪🍪🍪🍪🍪🍪"
def test_deposit():
...
def test_withdraw():
...
Demo
Sie können gerne eine Hauptfunktion implementieren, dies ist jedoch nicht erforderlich. Das ist also alles, was wir vorführen können:
Quelle: Sesame Street
Bevor Sie beginnen
Öffnen Sie VS Code entsprechend Ihrem Setup, klicken Sie auf Ihr Terminalfenster und führen Sie cd
aus. Die Eingabeaufforderung Ihres Terminalfensters sollte ungefähr wie folgt aussehen:
$
Führen Sie nun folgenden Befehl aus
mkdir jar
um in Ihrem Codespace einen Ordner mit dem Namen jar
zu erstellen.
Führen Sie anschließend folgenden Befehl aus
cd jar
Nun können Sie
code jar.py
ausführen, um eine Datei namens jar.py
zu erstellen. In diese Datei schreiben Sie nun Ihren Python Code.
Sie können auch
code test_jar.py
ausführen, um die Datei test_jar.py
zu erstellen. Darin schreiben Sie die Testes für Ihr Programm.
Testen
Nun soll der Code mit pytest
getestet werden:
-
Testen der Initialisierung (
test_init
) Öffnen Sie die Dateitest_jar.py
und importieren Sie Ihre KlasseJar
mitfrom jar import Jar
. Erstellen Sie eine Funktion namenstest_init
. In dieser Funktion erzeugen Sie eine neue Instanz Ihrer Klasse mitjar = Jar()
und überprüfen die Kapazität. Führen Sie anschließend Ihre Tests mitpytest test_jar.py
aus. -
Testen der String-Repräsentation (
test_str
) Fügen Sie der Dateitest_jar.py
eine neue Funktion namenstest_str
hinzu. Erstellen Sie in dieser Funktion eine neue Instanz der KlasseJar
und legen Sie einige Kekse hinein. Überprüfen Sie, ob die Methodestr(jar)
die korrekte Anzahl an Keksen ausgibt, die sich in der Keksdose befinden. Führen Sie danach die Tests mitpytest test_jar.py
aus. -
Testen der Einlage von Keksen (
test_depos
) Fügen Sie der Dateitest_jar.py
eine Funktion namenstest_deposit
hinzu. In dieser Funktion erstellen Sie eine neue Instanz der KlasseJar
und legen einige Kekse hinein. Überprüfen Sie, ob die Größe der Keksdose (size
) der Anzahl der hinterlegten Kekse entspricht. Testen Sie außerdem, ob einValueError
ausgelöst wird, wenn Sie versuchen, mehr Kekse hineinzulegen, als die Kapazität der Keksdose (capacity
) erlaubt. Führen Sie anschließend die Tests mitpytest test_jar.py
aus. -
Testen des Entnehmens von Keksen (
test_withdraw
) Fügen Sie der Dateitest_jar.py
eine Funktion namenstest_withdraw
hinzu. Erstellen Sie in dieser Funktion eine neue Instanz der KlasseJar
und legen Sie zunächst einige Kekse hinein. Überprüfen Sie, ob beim Entnehmen von Keksen die verbleibende Anzahl korrekt in der Keksdose gespeichert ist. Testen Sie auch, ob einValueError
ausgelöst wird, wenn Sie versuchen, mehr Kekse zu entnehmen, als tatsächlich in der Keksdose vorhanden sind (size
). Führen Sie schließlich Ihre Tests mitpytest test_jar.py
aus.
Korrektheit
Führen Sie in Ihrem Terminal den folgenden Befehl aus, um die Korrektheit Ihrer Arbeit zu überprüfen. Testen Sie Ihr Programm aber zuerst manuell.
check50 -l cs50/problems/2022/python/jar
Style
Führen Sie den folgenden Befehl aus, um den Stil Ihres Codes mit style50
zu analysieren:
style50 jar.py