KeyError: 2 Fehler

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

Hallo,
ich habe ein Programm das in einen Getränkeautomaten simulieren soll. Das Programm ist in 3 Klassen unterteilt. Getränkeautomat, Produkte und Geldbeutel.
Alles funktioniert soweit aber wenn ich den Geldbeutel updaten will nach einem Kauf (Zeile 177) bekomme ich einen Fehler.

Code: Alles auswählen

Traceback (most recent call last):
  File "./GetränkeAutomat.py", line 176, in <module>
    c.UpdateGeldbeutel()
  File "./GetränkeAutomat.py", line 151, in UpdateGeldbeutel
    self.geldbeutel[2] -= self.einwurf[2]
KeyError: 2
Hier mein Code:

Code: Alles auswählen

#!/usr/bin/python3
import sys

class Getraenkeautomat():

    def __init__(self, produkte):
        self.muenzvorrat = {2:2, 1:3, 0.50:5, 0.20:7, 0.10:10}
        self.muenzarten = [2, 1, 0.50, 0.20, 0.10]
        self.einwurf = {}
        self.rückgeld = {}
        self.guthaben = 0.0
        self.ges_einwurf = 0.0
        self.preis = 0.0
        self.produkte = produkte
        self.d = Geldbeutel(self.einwurf)

    def Muenzeinwurf(self):
        """Nimmt den Münzeneinwurf entgegen und berechnet den Gesamtwert des Einwurfs"""
        einwurf_zwei_euro = self.d.geldbeutel[2]+1
        einwurf_ein_euro = self.d.geldbeutel[1]+1
        einwurf_fünfzig_ct = self.d.geldbeutel[0.50]+1
        einwurf_zwanzig_ct = self.d.geldbeutel[0.20]+1
        einwurf_zehn_ct = self.d.geldbeutel[0.10]+1
        print("")

        while einwurf_zwei_euro > self.d.geldbeutel[2]:
            einwurf_zwei_euro = int(input("Wie viele 2€ Münzen wollen sie hineinwerfen: "))
            if einwurf_zwei_euro > self.d.geldbeutel[2]:
                print("Sie haben keine {0} 2€ Münzen. In ihrem Geldbeutel sind {1} 2€ Münzen vorhanden"
                      .format(einwurf_zwei_euro, self.d.geldbeutel[2]))
        while einwurf_ein_euro > self.d.geldbeutel[1]:
            einwurf_ein_euro = int(input("Wie viele 1€ Münzen wollen sie hineinwerfen: "))
            if einwurf_ein_euro > self.d.geldbeutel[1]:
                print("Sie haben keine {0} 1€ Münzen. In ihrem Geldbeutel sind {1} 1€ Münzen vorhanden"
                      .format(einwurf_ein_euro, self.d.geldbeutel[1]))
        while einwurf_fünfzig_ct > self.d.geldbeutel[0.50]:
            einwurf_fünfzig_ct = int(input("Wie viele 0.50€ Münzen wollen sie hineinwerfen: "))
            if einwurf_fünfzig_ct > self.d.geldbeutel[0.50]:
                print("Sie haben keine {0} 0.50€ Münzen. In ihrem Geldbeutel sind {1} 0.50€ Münzen vorhanden"
                      .format(einwurf_fünfzig_ct, self.d.geldbeutel[0.50]))
        while einwurf_zwanzig_ct > self.d.geldbeutel[0.20]:
            einwurf_zwanzig_ct = int(input("Wie viele 0.20€ Münzen wollen sie hineinwerfen: "))
            if einwurf_zwanzig_ct > self.d.geldbeutel[0.20]:
                print("Sie haben keine {0} 0.20€ Münzen. In ihrem Geldbeutel sind {1} 0.20€ Münzen vorhanden"
                      .format(einwurf_zwanzig_ct, self.d.geldbeutel[0.20]))            
        while einwurf_zehn_ct > self.d.geldbeutel[0.10]:
            einwurf_zehn_ct = int(input("Wie viele 0.10€ Münzen wollen sie hineinwerfen: "))
            if einwurf_zehn_ct > self.d.geldbeutel[0.10]:
                print("Sie haben keine {0} 0.10€ Münzen. In ihrem Geldbeutel sind {1} 0.10€ Münzen vorhanden"
                      .format(einwurf_zehn_ct, self.d.geldbeutel[0.10]))   

        self.ges_einwurf = einwurf_zwei_euro * 2 + einwurf_ein_euro * 1 + einwurf_fünfzig_ct / 2 + \
            einwurf_zwanzig_ct / 5 + einwurf_zehn_ct / 10

        round(self.ges_einwurf,2)

        self.guthaben += self.ges_einwurf

        self.einwurf = {2:einwurf_zwei_euro, 1:einwurf_ein_euro, 0.50:einwurf_fünfzig_ct,
                        0.20:einwurf_zwanzig_ct, 0.10:einwurf_zehn_ct}


    def AenderMuenzvorrat(self):
        """Fügt den Münzen des muenzvorrat Dictionarys die Münzen vom Einwurf hinzu"""
        self.muenzvorrat[2] += self.einwurf[2]
        self.muenzvorrat[1] += self.einwurf[1]
        self.muenzvorrat[0.50] += self.einwurf[0.50]
        self.muenzvorrat[0.20] += self.einwurf[0.20]
        self.muenzvorrat[0.10] += self.einwurf[0.10]


    def ZeigeMuenzvorrat(self):
        """Gibt das Dictionary muenzvorrat formatiert aus"""
        print("\nMünzvorrat des Automat's\n"
              "2€: {0} | 1€: {1} | 50ct: {2} | 20ct: {3} | 10ct: {4}\n"
              .format(self.muenzvorrat[2], self.muenzvorrat[1], self.muenzvorrat[0.50],
                      self.muenzvorrat[0.20], self.muenzvorrat[0.10]))


    def KaufeProdukt(self):
        """Fragt nach Produktwunsch und überprüft Verfügbarkeit. Schließt den Kauf ab."""
        auswahl_produkt = input("\nFür welches Produkt haben sie sich entschieden: ")
        try:
            self.preis = self.produkte[auswahl_produkt]["Preis"]
            print("\n{0} kostet {1:2.2f}€".format(auswahl_produkt, self.preis))
            if self.preis > self.guthaben:
                                print("\nIhnen fehlen {0:2.2f}€. Bitte den restlichen Betrag einwerfen!\n"
                                      .format(self.preis-self.guthaben))
            elif self.preis <= self.guthaben:
                if self.produkte[auswahl_produkt]["Vorrat"] > 0:
                    self.guthaben -= self.preis
                    self.produkte[auswahl_produkt]["Vorrat"] -= 1
                    print("\nBitte entnehmen sie Ihr Produkt.\n")
                else:
                    print("\nDieses Getränk ist momentan ausverkauft\n")
        except KeyError:
            print("""\nDas Produkt "{0}" führen wir nicht, verschrieben?\n""".format(auswahl_produkt))            
        return self.produkte
   

    def ZeigeGuthaben(self):
        print("Guthaben: {0:2.2f}€".format(self.guthaben))


    def Rückgabe(self):
        self.rückgeld = {2:0, 1:0, 0.50:0, 0.20:0, 0.10:0}

        while self.guthaben > 2:
            pass


class Produkte():

    def __init__(self):
        self.produkte = {"Coca-Cola": {"Preis": 2.00, "Vorrat": 3},
                         "Fanta": {"Preis": 1.80, "Vorrat": 3},
                         "Spezi": {"Preis": 1.70, "Vorrat": 3},
                         "Wasser": {"Preis": 1.20 , "Vorrat": 3}}


    def ProduktHinzufuegen(self, produktname, preis, vorrat):
        """Fügt ein Produkt in das self.produkt dictionary ein"""
        self.produkte[produktname] = {"Preis": preis, "Vorrat": vorrat}


    def ZeigeProdukte(self):
        """Zeigt alle Produkte des self.produkt dictionarys formatiert an mit Preis und Vorrat"""
        print("")
        for prod in self.produkte:
            print("{0:10} | {1:3.2f}€ | {2}".format(prod, self.produkte[prod]["Preis"], self.produkte[prod]["Vorrat"]))


class Geldbeutel():
    
    def __init__(self, einwurf):
        self.geldbeutel = {2:5, 1:7, 0.50:12, 0.20:20, 0.10:12}
        self.einwurf = einwurf
        self.ges_geld = 0.0

    def ZeigeGeldbeutel(self):
        """Rechnet Gesamtwert des Geldbeutels aus und zeigt diesen, mit der Anzahl aller Münzen formatiert an"""
        self.ges_geld = self.geldbeutel[2]*2 + self.geldbeutel[1]*1 + self.geldbeutel[0.50]/2
        self.ges_geld += self.geldbeutel[0.20]/5 + self.geldbeutel[0.10]/10
        print("\nMein Geldbeutel:\n"
              "2€: {0} | 1€: {1} | 0.50€: {2} | 0.20€: {3} | 0.10€: {4}\nGesamt: {5:2.2f}€\n"
              .format(self.geldbeutel[2], self.geldbeutel[1], self.geldbeutel[0.50], self.geldbeutel[0.20],
                      self.geldbeutel[0.10], self.ges_geld))


    def UpdateGeldbeutel(self):
        try:
            self.geldbeutel[2] -= self.einwurf[2]
            self.geldbeutel[1] -= self.einwurf[1]
            self.geldbeutel[0.50] -= self.einwurf[0.50]
            self.geldbeutel[0.20] -= self.einwurf[0.20]
            self.geldbeutel[0.10] -= self.einwurf[0.10]

            return self.einwurf
        except TypeError:
            print("Nothing to update")


if __name__ == "__main__":
    b = Produkte()
    a = Getraenkeautomat(b.produkte)
    c = Geldbeutel(a.einwurf)
    
    while True:
        print("\nGuthaben: {0:2.2f}€".format(a.guthaben))
        menu_auswahl = int(input("1. Zeige Produkte\n2. Guthaben aufladen\n3. Produkt kaufen\n"
                                 "4. Mein Geldbeutel\nAuswahl: "))
        a.guthaben
        if menu_auswahl == 1:
            b.ZeigeProdukte()
        elif menu_auswahl == 2:
            a.Muenzeinwurf()
            c.UpdateGeldbeutel()
        elif menu_auswahl == 3:
            a.KaufeProdukt()
        elif menu_auswahl == 4:
            c.ZeigeGeldbeutel()
Sonstige Verbesserungsvorschläge sehr gerne erwünscht.
Sirius3
User
Beiträge: 18330
Registriert: Sonntag 21. Oktober 2012, 17:20

@nfehren: seit wann hat ein Getränkeautomat einen Geldbeutel?
Du hast viel zu viele Codewiederholungen. Teile Dein Programm erst mal in sinnvolle Funktionen. Du solltest die Behandlung der einzelnen Münzarten nicht per Copy-Paste, sondern per Variablen und Schleifen lösen.
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

Sirius3 hat geschrieben:@nfehren: seit wann hat ein Getränkeautomat einen Geldbeutel?
Ein Getränkeautomat hat keinen Geldbeutel. Deshalb gibt es auch eine Klasse "Getraenkeautomat" und eine andere Klasse "Geldbeutel".

Könntest du mir ein Beispiel zeigen wie ich die Behandlung anhand einer Schleife löse?


lg, Navid
BlackJack

@nfehren: Doch der Getränkeautomat hat bei Dir einen Geldbeutel. Der wird in der `__init__()` erzeugt und an das Attribut `d` gebunden. Und ein anderer Geldbeutel wird im Hauptprogramm erzeugt und an den Namen `c` gebunden. Häh? Und das sind wirklich schlechte Namen. Das der Geldbeutel ein Attribut mit dem Namen `geldbeutel` hat, finde ich auch verwirrend.

Das der Geldbeutel den Einwurf von einem Automaten beim erstellen übergeben bekommt ist ebenfalls eigenartig. Damit hat selbst ein ausserhalb eines Automaten erstellten Geldbeutel eine ”feste” Verbindung zu genau einem Automaten. Ich würde ja erwarten dass man mit einem Geldbeutel an beliebige Automaten gehen kann.

Die `Muenzeinwurf()`-Methode vom Automaten weiss viel zu viel von Geldbeuteln. Die greift ja direkt bis in die Daten dieser Struktur durch und verändert die.

Ich denke für den Geldbeutel, den Münzvorrat, den Einwurf, und die Rückgabe könnte man *einen* Datentyp schreiben. Nämlich einen Container für Münzen wo man Münzen hinzufügen und wegnehmen kann, den Gesamtwert abfragen kann, und womit man andere Exemplare dieses Typs aktualisieren kann bzw. den Inhalt übertragen.

Ich weiss übrigens nicht ob ich Gleitkommazahlen genug vertrauen würde. Da gibt es Rechenungenauigkeiten. Ich würde wohl das `decimal`-Modul verwenden oder intern alles als ganze Zahlen in Centbeträgen verarbeiten.
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

Code: Alles auswählen

#!/usr/bin/python3
import sys

class Getraenkeautomat():

    def __init__(self):
        self.muenzvorrat = {2:2, 1:3, 0.50:5, 0.20:7, 0.10:10}
        self.muenzarten = [2, 1, 0.50, 0.20, 0.10]
        self.einwurf = {}
        self.rueckgeld = {}
        self.guthaben = 0.0
        self.ges_einwurf = 0.0
        self.preis = 0.0

    def Muenzeinwurf(self, geldbeutel):
        """Nimmt den Münzeneinwurf entgegen und berechnet den Gesamtwert des Einwurfs"""
        einwurf_zwei_euro = geldbeutel[2]+1
        einwurf_ein_euro = geldbeutel[1]+1
        einwurf_fünfzig_ct = geldbeutel[0.50]+1
        einwurf_zwanzig_ct = geldbeutel[0.20]+1
        einwurf_zehn_ct = geldbeutel[0.10]+1
        print("")

        while einwurf_zwei_euro > geldbeutel[2]:
            einwurf_zwei_euro = int(input("Wie viele 2€ Münzen wollen sie hineinwerfen: "))
            if einwurf_zwei_euro > geldbeutel[2]:
                print("Sie haben keine {0} 2€ Münzen. In ihrem Geldbeutel sind {1} 2€ Münzen vorhanden"
                      .format(einwurf_zwei_euro, geldbeutel[2]))
        while einwurf_ein_euro > geldbeutel[1]:
            einwurf_ein_euro = int(input("Wie viele 1€ Münzen wollen sie hineinwerfen: "))
            if einwurf_ein_euro > geldbeutel[1]:
                print("Sie haben keine {0} 1€ Münzen. In ihrem Geldbeutel sind {1} 1€ Münzen vorhanden"
                      .format(einwurf_ein_euro, geldbeutel[1]))
        while einwurf_fünfzig_ct > geldbeutel[0.50]:
            einwurf_fünfzig_ct = int(input("Wie viele 0.50€ Münzen wollen sie hineinwerfen: "))
            if einwurf_fünfzig_ct > geldbeutel[0.50]:
                print("Sie haben keine {0} 0.50€ Münzen. In ihrem Geldbeutel sind {1} 0.50€ Münzen vorhanden"
                      .format(einwurf_fünfzig_ct, geldbeutel[0.50]))
        while einwurf_zwanzig_ct > geldbeutel[0.20]:
            einwurf_zwanzig_ct = int(input("Wie viele 0.20€ Münzen wollen sie hineinwerfen: "))
            if einwurf_zwanzig_ct > geldbeutel[0.20]:
                print("Sie haben keine {0} 0.20€ Münzen. In ihrem Geldbeutel sind {1} 0.20€ Münzen vorhanden"
                      .format(einwurf_zwanzig_ct, geldbeutel[0.20]))            
        while einwurf_zehn_ct > geldbeutel[0.10]:
            einwurf_zehn_ct = int(input("Wie viele 0.10€ Münzen wollen sie hineinwerfen: "))
            if einwurf_zehn_ct > geldbeutel[0.10]:
                print("Sie haben keine {0} 0.10€ Münzen. In ihrem Geldbeutel sind {1} 0.10€ Münzen vorhanden"
                      .format(einwurf_zehn_ct, geldbeutel[0.10]))   

        self.ges_einwurf = einwurf_zwei_euro * 2 + einwurf_ein_euro * 1 + einwurf_fünfzig_ct / 2 + \
            einwurf_zwanzig_ct / 5 + einwurf_zehn_ct / 10

        round(self.ges_einwurf,2)

        self.guthaben += self.ges_einwurf
        self.einwurf[2] = einwurf_zwei_euro
        self.einwurf[1] = einwurf_ein_euro
        self.einwurf[0.50] = einwurf_fünfzig_ct
        self.einwurf[0.20] = einwurf_zwanzig_ct
        self.einwurf[0.10] = einwurf_zehn_ct


    def AenderMuenzvorrat(self):
        """Fügt den Münzen des muenzvorrat Dictionarys die Münzen vom Einwurf hinzu"""
        self.muenzvorrat[2] += self.einwurf[2]
        self.muenzvorrat[1] += self.einwurf[1]
        self.muenzvorrat[0.50] += self.einwurf[0.50]
        self.muenzvorrat[0.20] += self.einwurf[0.20]
        self.muenzvorrat[0.10] += self.einwurf[0.10]


    def ZeigeMuenzvorrat(self):
        """Gibt das Dictionary muenzvorrat formatiert aus"""
        print("\nMünzvorrat des Automat's\n"
              "2€: {0} | 1€: {1} | 50ct: {2} | 20ct: {3} | 10ct: {4}"
              .format(self.muenzvorrat[2], self.muenzvorrat[1], self.muenzvorrat[0.50],
                      self.muenzvorrat[0.20], self.muenzvorrat[0.10]))


    def KaufeProdukt(self, produkte):
        """Fragt nach Produktwunsch und überprüft Verfügbarkeit. Schließt den Kauf ab."""
        auswahl_produkt = input("\nFür welches Produkt haben sie sich entschieden: ")
        try:
            self.preis = produkte[auswahl_produkt]["Preis"]
            print("\n{0} kostet {1:2.2f}€".format(auswahl_produkt, self.preis))
            if self.preis > self.guthaben:
                                print("\nIhnen fehlen {0:2.2f}€. Bitte den restlichen Betrag einwerfen!"
                                      .format(self.preis-self.guthaben))
            elif self.preis <= self.guthaben:
                if produkte[auswahl_produkt]["Vorrat"] > 0:
                    self.guthaben -= self.preis
                    produkte[auswahl_produkt]["Vorrat"] -= 1
                    print("\nBitte entnehmen sie Ihr Produkt.")
                else:
                    print("\nDieses Getränk ist momentan ausverkauft")
        except KeyError:
            print("""\nDas Produkt "{0}" führen wir nicht, verschrieben?""".format(auswahl_produkt))            

   

    def ZeigeGuthaben(self):
        print("Guthaben: {0:2.2f}€".format(self.guthaben))


    def Rueckgabe(self, geldbeutel):
        self.rueckgeld = {2:0, 1:0, 0.50:0, 0.20:0, 0.10:0}

        while self.guthaben >= 2:
            if self.muenzvorrat[2] > 2:
                self.rueckgeld[2] += 1
                geldbeutel[2] += 1
                self.muenzvorrat[2] -= 1
                self.guthaben -= 2
            else:
                break
        while self.guthaben >= 1:
            if self.muenzvorrat[1] > 3:
                self.rueckgeld[1] += 1
                geldbeutel[1] += 1
                self.muenzvorrat[1] -= 1
                self.guthaben -= 1
            else:
                break
        while self.guthaben >= 0.50:
            if self.muenzvorrat[0.50] > 5:
                self.rueckgeld[0.50] += 1
                geldbeutel[0.50] += 1
                self.muenzvorrat[0.50] -= 1  
                self.guthaben -= 0.50
            else:
                break
        while self.guthaben >= 0.20:
            if self.muenzvorrat[0.20] > 7: 
                self.rueckgeld[0.20] += 1
                geldbeutel[0.20] += 1
                self.muenzvorrat[0.20] -= 1 
                self.guthaben -= 0.20
            else:
                break
        while self.guthaben >= 0.10:
            if self.muenzvorrat[0.10] > 10:
                self.rueckgeld[0.10] += 1
                geldbeutel[0.10] += 1
                self.muenzvorrat[0.10] -= 1
                self.guthaben -= 0.10
            else:
                break

class Produkte():

    def __init__(self):
        self.produkte = {"Coca-Cola": {"Preis": 2.00, "Vorrat": 3},
                         "Fanta": {"Preis": 1.80, "Vorrat": 3},
                         "Spezi": {"Preis": 1.70, "Vorrat": 3},
                         "Wasser": {"Preis": 1.20 , "Vorrat": 3}}


    def ProduktHinzufuegen(self, produktname, preis, vorrat):
        """Fügt ein Produkt in das self.produkt dictionary ein"""
        self.produkte[produktname] = {"Preis": preis, "Vorrat": vorrat}


    def ZeigeProdukte(self):
        """Zeigt alle Produkte des self.produkt dictionarys formatiert an mit Preis und Vorrat"""
        print("")
        for prod in self.produkte:
            print("{0:10} | {1:3.2f}€ | {2}".format(prod, self.produkte[prod]["Preis"], self.produkte[prod]["Vorrat"]))


class Geldbeutel():
    
    def __init__(self):
        self.geldbeutel = {2:5, 1:7, 0.50:12, 0.20:20, 0.10:12}
        self.ges_geld = 0.0


    def ZeigeGeldbeutel(self):
        """Rechnet Gesamtwert des Geldbeutels aus und zeigt diesen, mit der Anzahl aller Münzen formatiert an"""
        self.ges_geld = self.geldbeutel[2]*2 + self.geldbeutel[1]*1 + self.geldbeutel[0.50]/2
        self.ges_geld += self.geldbeutel[0.20]/5 + self.geldbeutel[0.10]/10
        print("\nMein Geldbeutel:\n"
              "2€: {0} | 1€: {1} | 0.50€: {2} | 0.20€: {3} | 0.10€: {4}\nGesamt: {5:2.2f}€"
              .format(self.geldbeutel[2], self.geldbeutel[1], self.geldbeutel[0.50], self.geldbeutel[0.20],
                      self.geldbeutel[0.10], self.ges_geld))


    def UpdateGeldbeutel(self, einwurf, rueckgeld):
        try:
            self.geldbeutel[2] -= einwurf[2]
            self.geldbeutel[1] -= einwurf[1]
            self.geldbeutel[0.50] -= einwurf[0.50]
            self.geldbeutel[0.20] -= einwurf[0.20]
            self.geldbeutel[0.10] -= einwurf[0.10]

        except TypeError:
            print("Nothing to update")
            
        if rueckgeld[2] > 0 or rueckgeld[1] > 0 or rueckgeld[0.50] > 0 or rueckgeld[0.20] > 0 or rueckgeld[0.10] > 0:
            self.geldbeutel[2] += rueckgeld[2]
            self.geldbeutel[1] += rueckgeld[1]
            self.geldbeutel[0.50] += rueckgeld[0.50]
            self.geldbeutel[0.20] += rueckgeld[0.20]
            self.geldbeutel[0.10] += rueckgeld[0.10]


if __name__ == "__main__":
    b = Produkte()
    a = Getraenkeautomat()
    c = Geldbeutel()
    
    while True:
        print("\nGuthaben: {0:2.2f}€".format(a.guthaben))
        menu_auswahl = int(input("1. Zeige Produkte\n2. Guthaben aufladen\n3. Produkt kaufen\n"
                                 "4. Mein Geldbeutel\n5. Guthaben auszahlen\n6. Exit\nAuswahl: "))
        a.guthaben
        if menu_auswahl == 1:
            b.ZeigeProdukte()
            a.ZeigeMuenzvorrat()
        elif menu_auswahl == 2:
            a.Muenzeinwurf(c.geldbeutel)
            a.AenderMuenzvorrat()
            c.UpdateGeldbeutel(a.einwurf, a.rueckgeld)
        elif menu_auswahl == 3:
            a.KaufeProdukt(b.produkte)
        elif menu_auswahl == 4:
            c.ZeigeGeldbeutel()
        elif menu_auswahl == 5:
            a.Rueckgabe(c.geldbeutel)
        elif menu_auswahl == 6:
            sys.exit(0)
Das hier ist die neue Version des Programms. Die Idee mit den verschiedenen Automaten und einem Geldbeutel ist gut, werd ich auch probieren einzubauen.

Wie kann ich aber z.B. diesen Codeblock anhand einer Schleife kompakter machen?
Edit:

Code: Alles auswählen

        self.muenzvorrat[2] += self.einwurf[2]
        self.muenzvorrat[1] += self.einwurf[1]
        self.muenzvorrat[0.50] += self.einwurf[0.50]
        self.muenzvorrat[0.20] += self.einwurf[0.20]
        self.muenzvorrat[0.10] += self.einwurf[0.10]
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

nfehren hat geschrieben:Wie kann ich aber z.B. diesen Codeblock anhand einer Schleife kompakter machen?
Du definierst doch die zulässigen Münzarten innerhalb deiner Getraenkeautomat-Klasse. Du brauchst die Werte nur in einer Schleife durchlaufen und als Keys verwenden.

Mal ein Beispiel.

Code: Alles auswählen

AVAILABLE_COINS = [1, 2, 5, 10, 20, 50, 100, 200]


class VendingMachine():
    def __init__(self):
        self.coins = {coin_type: 0 for coin_type in AVAILABLE_COINS}

    def feed(self, coins):
        for coin_type in AVAILABLE_COINS:
            self.coins[coin_type] += coins.get(coin_type, 0)

machine = VendingMachine()
money = {10: 2, 50: 1}
machine.feed(money)
money = {50: 4, 100: 2}
machine.feed(money)
print(machine.coins)
Ergebnis:

Code: Alles auswählen

{1: 0, 2: 0, 20: 0, 5: 0, 200: 0, 100: 2, 10: 2, 50: 5}
Zuletzt geändert von /me am Dienstag 21. Oktober 2014, 10:05, insgesamt 1-mal geändert.
BlackJack

@nfehren: Das ist alles ein bisschen schräg. Die Typen und Funktionen wissen zu viel voneinander. Die Aufgaben sind teilweise komisch/falsch verteilt. Es gibt einige redundante Daten wo die Gefahr besteht das die Werte ”auseinander laufen”. Die Summen vom Münzvorrat, dem Einwurf, dem Geldbeutel, kann man alle berechnen wenn man sie braucht, da sollte man nicht nebenher noch ein Attribut haben welches *hoffentlich* den richtigen Wert hat. Wie schon gesagt, diese ”Sammlung von Münzen” ist ein prima Kandidat für einen eigenen Datentyp wo das *einmal* gelöst werden kann.

In den Zeilen zur letzten Frage unterscheidet sich jede Zeile doch nur durch den Münzwert. Das kann man also in eine Datenstruktur heraus ziehen:

Code: Alles auswählen

        for muenz_wert in [2, 1, 0.50, 0.20, 0.10]:
            self.muenzvorrat[muenz_wert] += self.einwurf[muenz_wert]
Aber selbst das muss man nicht explizit hin schreiben, denn der `einwurf` hat ja bereits alle nötigen Informationen:

Code: Alles auswählen

        for muenz_wert, anzahl in self.einwurf.items():
            self.muenzvorrat[muenz_wert] += anzahl
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

Sehr schön kompakt danke, werd ich gleich umschreiben.
Kann man vielleicht die Methode Muenzeinwurf besser gestalten? Sie soll abfragen wie viel Münzen eingeworfen werden sollen, dabei aber kontrollieren, dass auch genügend Münzen im Geldautomaten vorhanden sind. Weil mir kommt meine Art der Methode ziemlich schlampig vor.

lg, Navid

Edit:
Bin selber drauf gekommen. Hab die Methode nun umgeschrieben:

Code: Alles auswählen

def Muenzeinwurf(self, geldbeutel):
        """Nimmt den Münzeneinwurf entgegen und berechnet den Gesamtwert des Einwurfs"""
        for muenz_wert, anzahl in geldbeutel.items():
            self.einwurf[muenz_wert] = anzahl+1

        print("")
        for muenz_wert, anzahl in sorted(self.einwurf.items(), reverse = True):
            while self.einwurf[muenz_wert] > geldbeutel[muenz_wert]:
                self.einwurf[muenz_wert] = int(input("Wie viele {0:2.2f}€ Münzen wollen sie hineinwerfen: "
                                                     .format(muenz_wert)))
                if self.einwurf[muenz_wert] > geldbeutel[muenz_wert]:
                    print("Sie haben keine {0} {1:2.2f}€ Münzen. In Ihrem Geldbeutel sind {2} {1:2.2f}€ "
                          "Münzen vorhanden".format(self.einwurf[muenz_wert], muenz_wert, geldbeutel[muenz_wert]))
Sirius3
User
Beiträge: 18330
Registriert: Sonntag 21. Oktober 2012, 17:20

@nfehren: diese Initialisierung ist seltsame. Wer das zum ersten mal liest, versteht doch den Sinn dahinter erst beim dritten mal überlegen.
Warum steht in self.einwurf ein Wert, der größer als der erlaubte ist?
Du hast einen Geldbeutel mit Münzen. Warum soll man gefragt werden, wie viele 50 Cent man einwerfen will, wenn man gar keine hat?
Die logische Reihenfolge wäre doch, ich habe einen Geldbeutel, nehme mir eine Anzahl Münzen heraus und werfe diese in den Automaten.
Das führt wieder zu einer Geldmengenklasse, die ein Geldbeutel, Münzen in der Hand oder Speicher im Automaten sein kann.
Suche-Münzen-aus-dem-Geldbeutel ist also eine Methode die auf einer Geldbeutel-Instanz operiert und Werfe-Münzen-in-den-Automaten eine Methode des Automaten, die aber vom Geldbeutel nichts wissen muß.
Antworten