Keksdose

Aufgabe

Sesame Street 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:

  1. __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 positiver int ist, soll ein ValueError ausgelöst werden.
  2. __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.
  3. deposit
    • Legt zusätzliche n Kekse in die Keksdose.
    • Wenn dadurch die Kapazität der Keksdose überschritten wird, soll ein ValueError ausgelöst werden.
  4. 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.
  5. capacity
    • Gibt die maximale Kapazität der Keksdose zurück.
  6. size
    • Gibt die aktuelle Anzahl der Kekse in der Keksdose zurück (zu Beginn 0).

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:

Sesame Street 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:

  1. Testen der Initialisierung (test_init) Öffnen Sie die Datei test_jar.py und importieren Sie Ihre Klasse Jar mit from jar import Jar. Erstellen Sie eine Funktion namens test_init. In dieser Funktion erzeugen Sie eine neue Instanz Ihrer Klasse mit jar = Jar() und überprüfen die Kapazität. Führen Sie anschließend Ihre Tests mit pytest test_jar.py aus.

  2. Testen der String-Repräsentation (test_str) Fügen Sie der Datei test_jar.py eine neue Funktion namens test_str hinzu. Erstellen Sie in dieser Funktion eine neue Instanz der Klasse Jar und legen Sie einige Kekse hinein. Überprüfen Sie, ob die Methode str(jar) die korrekte Anzahl an Keksen ausgibt, die sich in der Keksdose befinden. Führen Sie danach die Tests mit pytest test_jar.py aus.

  3. Testen der Einlage von Keksen (test_depos) Fügen Sie der Datei test_jar.py eine Funktion namens test_deposit hinzu. In dieser Funktion erstellen Sie eine neue Instanz der Klasse Jar 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 ein ValueError ausgelöst wird, wenn Sie versuchen, mehr Kekse hineinzulegen, als die Kapazität der Keksdose (capacity) erlaubt. Führen Sie anschließend die Tests mit pytest test_jar.py aus.

  4. Testen des Entnehmens von Keksen (test_withdraw) Fügen Sie der Datei test_jar.py eine Funktion namens test_withdraw hinzu. Erstellen Sie in dieser Funktion eine neue Instanz der Klasse Jar 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 ein ValueError 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 mit pytest 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