Eingabe mit Wert aus Dictionary vergleichen und zusammen rechnen

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
Robert456
User
Beiträge: 5
Registriert: Sonntag 15. August 2021, 12:09

Hallo Zusammen,
auch ich bin neu und habe eine Menge keine Ahnung.

Mein Ziel ist, Eingaben die gemacht werden, mit einer dictionary zu vergleichen und die Treffer miteinander zu addieren und aus zu geben.
Mit meinem bescheidenen wissen habe ich keine Lösung im Netz gefunden.
---

Code: Alles auswählen

from tkinter import *
"""
Eingabe der Speisen und Getränke
"""
def copy_text():
    (input1_Ergebnis1, input2_Ergebnis2, input3_Ergebnis3 ) =\
        (input1.get(), input2.get(), input3.get())
    (Ergebnis1["text"], Ergebnis2["text"], Ergebnis3["text"]) =\
        (input1_Ergebnis1, input2_Ergebnis2, input3_Ergebnis3)
"""
Speisekarte
"""
Speisekarte = {"Fisch": 15.99, "Schnitzel": 12.99, "Rinderfilet": 25.99, "Bratkartoffel": 6.99,
               "Pommes": 4.99, "Bier": 4.99, "Wein": 6.99, "Wasser": 3.99}
"""
Berechnung der Gesamtkosten

die input1_Ergebnis1 bis 3 sollen zusammengerechnet und ausgegeben werden.
wie vergleiche ich den input1_Ergebnis1 mit der Speisekarte und wie rechne 
ich die dann mit den anderen zusammen
"""
#???
"""
Änderung des Tabellennamens
"""
Nr1 = Tk()
"""
Fenster Namen und Größe
"""
Nr1.title("Rechnung erstellen")
Nr1.geometry("500x500")
"""
Header Überschrift
"""
header = Label(Nr1, text="Kunden berechnen:", font=("Arial", 25))
header.pack()
"""
die drei Eingabe Felder
"""
input1 = Entry(Nr1)
input1.pack()

input2 = Entry(Nr1)
input2.pack()

input3 = Entry(Nr1)
input3.pack()
"""
der Bestätigungs Button
"""
submit = Button(Nr1, text="Bestätigen", font=("Arial", 15), command=copy_text)
submit.pack()
"""
die Gerichte die eingegeben wurden
"""
Ergebnis1 = Label(Nr1, text="Gericht 1:", font=("Arial", 20))
Ergebnis1.pack()

Ergebnis2 = Label(Nr1, text="Gericht 2:", font=("Arial", 20))
Ergebnis2.pack()

Ergebnis3 = Label(Nr1, text="Getränk 1:", font=("Arial", 20))
Ergebnis3.pack()
"""
Überschrift für den Betrag
"""
betrag = Label(Nr1, text="Rechnungsbetrag:", font=("Arial", 10))
betrag.pack()


#print(Rechnungsbetrag)


Nr1.mainloop()
--------
Ich sag schon mal Danke fürs anschauen!
Grüße Robert
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@Robert456,

da du die Zwischensumme für die Berechnung merken willst, wäre es besser, das Ganze in eine Klasse zu packen.

Dir fehlen anscheinend noch einige Grundlagen um so etwas in Python umzusetzen. Daher wäre die Frage: Ist das für dich persönlich zum lernen, ist das ein Schulprojekt, ...?
Was genau ist das Ziel dieser Applikation?
Robert456
User
Beiträge: 5
Registriert: Sonntag 15. August 2021, 12:09

Hallo rogerb,
das ist für mich persönlich. Ich hab einen online Kurs gemacht und versuche eine Aufgabe zu erweitern.
Hast du eine Idee wo und wie ich das Thema vertiefen kann? Beim suchen im Netz ist verliert man sich schnell.
Das Ziel ist, dass ich die Gerichte in die Input-Felder eintrage und wenn ich den Bestätigen Button drücke, dass die Gerichte unten angezeigt werden(was es ja bereits tut) und die Summe der Gerichte als Rechnungsbetrag ausweist.
Danach wollte ich die Gerichte und den Rechnungsbetrag in eine eigene Datei speichern. Aber erstmal muss ich verstehen, wie ich überhaupt zum Rechnungsbetrag komme.
Grüße
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich wuerde immer erstmal im offiziellen Python-Tutorial nachschauen. Da gibt es zB ein Kapitel zum Datentyp dict. https://docs.python.org/3/tutorial/data ... ctionaries
Benutzeravatar
YAPD
User
Beiträge: 120
Registriert: Dienstag 27. Juli 2021, 23:23
Wohnort: Frankfurt am Main

Hi Robert,

da es nur für dich persönlich ist, weiß ich nicht ob es Sinn macht , aber ich würde
es grundsätzlich anders aufbauen. Was ist, wenn der Gast nur 1 Speise und 3
Getränke bestellt ? Das sieht irgendwie sehr unfertig aus.
-----
Yet Another Python Developer
Benutzeravatar
__blackjack__
User
Beiträge: 14056
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Robert456: Anmerkungen zum Quelltext:

Sternchen-Importe sind Böse™. Da holt man sich gerade bei `tkinter` fast 200 Namen ins Modul von denen nur ein kleiner Bruchteil verwendet wird. Auch Namen die gar nicht in `tkinter` definiert werden, sondern ihrerseits von woanders importiert werden. Das macht Programme unnötig unübersichtlicher und fehleranfälliger und es besteht die Gefahr von Namenskollisionen.

Literale Zeichenketten darf man nicht als Kommentare missbrauchen. An bestimmten Stellen im Quelltext haben die für die Sprache selbst eine besondere Bedeutung als DocStrings. Und für einige Dokumentationswerkzeuge auch noch an weiteren Stellen um den Code zu dokumentieren. Wenn man den Code einfach nur kommentieren will, dann verwendet man dafür Kommentare und die fangen mit einem ``#`` an.

Kommentare sollen dem Leser einen Mehrwert über den Code geben. Faustregel: Kommentare beschreiben nicht *was* der Code macht, denn das steht da bereits als Code, sondern warum er das macht. Sofern das nicht offensichtlich ist. Offensichtlich ist in aller Regel auch was in der Dokumentation von Python und den verwendeten Bibliotheken steht.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Funktionen (und Methoden) bekommen alles was sie ausser Konstanten benötigen als Argument(e) übergeben. `copy_text()` braucht also die `Label` und `Entry`-Objekte als Argumente. Hier kann man das noch mit `functools.partial()` lösen, aber jede nicht-triviale GUI braucht objektorientierte Programmierung (OOP), also mindestens eine eigene Klasse.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).

Man nummeriert keine Namen. Entweder will man passendere Namen verwenden, oder gar keine einzelnen Werte sondern eine Datenstruktur verwenden. Oft eine Liste.

`Nr1` ist ein seltsamer Name für ein `Tk`-Objekt. Vor allem auch weil es davon nur ein einziges geben darf. Der traditionelle Name ist `root`. Man könnte es auch `main_window` nennen.

Wenn man einen Wert später gar nicht mehr braucht, muss man auch nicht jedem Zwischenergebnis einen Namen geben.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk
from functools import partial


def copy_text(input_entries, result_labels):
    for entry, label in zip(input_entries, result_labels):
        label["text"] = entry.get()


def main():
    item_to_price = {
        #
        # Gerichte
        #
        "Bratkartoffel": 6.99,
        "Fisch": 15.99,
        "Pommes": 4.99,
        "Rinderfilet": 25.99,
        "Schnitzel": 12.99,
        #
        # Getränke
        #
        "Bier": 4.99,
        "Wasser": 3.99,
        "Wein": 6.99,
    }

    root = tk.Tk()
    root.title("Rechnung erstellen")

    tk.Label(root, text="Kunden berechnen:", font=("Arial", 25)).pack()

    texts = ["Gericht 1", "Gericht 2", "Getränk 1"]
    input_entries = []
    for _ in range(len(texts)):
        entry = tk.Entry(root)
        entry.pack()
        input_entries.append(entry)

    submit_button = tk.Button(root, text="Bestätigen", font=("Arial", 15))
    submit_button.pack()

    result_labels = []
    for text in texts:
        label = tk.Label(root, text=text + ":", font=("Arial", 20))
        label.pack()
        result_labels.append(label)

    total_label = tk.Label(root, text="Rechnungsbetrag:", font=("Arial", 10))
    total_label.pack()

    submit_button["command"] = partial(copy_text, input_entries, result_labels)

    root.mainloop()


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Robert456
User
Beiträge: 5
Registriert: Sonntag 15. August 2021, 12:09

@YAPD natürlich macht das keinen Sinn, soll nur zur Übung gut sein. :-)
wie würdest du den Code schreiben?

@ __blackjack__ Danke für die vielen Tips, versuch ich zu verarbeiten.
die Namen habe ich nur so gewählt, weil ich nicht viel schreiben wollte.
Der Rechnungsbetrag wird trotzdem nicht angezeigt.
Danke für deine Mühen.
Benutzeravatar
YAPD
User
Beiträge: 120
Registriert: Dienstag 27. Juli 2021, 23:23
Wohnort: Frankfurt am Main

Hi Robert,

mir ist schon klar, dass es nur ein Übungsscript und daher nicht vollständig ist.
Trotzdem sollte man alle eventuellen Fälle berücksichtigen, die eintreten können. ;)

Ich habe mal versucht, deine Beschreibung entsprechend umzusetzen, bin allerdings
auch noch relativ neu in der Materie :)

Code: Alles auswählen

class Order:

    availablefood = {"Baked Fries": 5.50}
    availabledrinks = {"Water": 1.75, "Coffee": 2.50}

    def __init__(self):

        self.ordernumber = 1

        self.orderfood = {}
        self.orderdrinks = {}

    def createorder(self, table, persons):

        print("Creating Order For Table  : {}".format(table))
        print("Associated Persons        : {}".format(persons))
        print("Registered Order - Number : {}".format(self.ordernumber))

        self.ordernumber += 1

        return self

    def createorderitem(self, itm ):

        print("Adding '{}' To Order !".format(itm))

        if itm in Order.availablefood:
            
            if itm not in self.orderfood:
                self.orderfood[itm] = 1
            else :
                self.orderfood[itm] += 1
                
        elif itm in Order.availabledrinks:

            if itm not in self.orderdrinks :  
                self.orderdrinks[itm] = 1
            else :
                self.orderdrinks[itm] += 1 
        else:
            print("{} Is Not Available !".format(itm))

        return self


class Billing:
    def __init__(self):
        print()

    def createbill(self):
        print("Bill Of Fare : ", self.orderfood )

        for x in self.orderfood:
            print("{} : {} €".format(x, self.availablefood[x]*self.orderfood[x]))

        for x in self.orderdrinks:
            print("{} : {} €".format(x, self.availabledrinks[x]*self.orderdrinks[x]))


orderclass = Order()

currentorder = orderclass.createorder(1 , 4 )               # Erstelle Bestellung für Tisch 1 mit 4 Personen
order1 = currentorder.createorderitem("Baked Fries")        # Füge 'Baked Fries' zur Bestellung hinzu ( Food )
order2 = currentorder.createorderitem("Water")              # Fügt 'Water' zur Bestellung hinzu ( Drinks ) 

Rechnung = Billing()                                        # Erstelle Rechnungsobjekt
Billing.createbill(orderclass)                              # Erstellung der Rechnung für Tisch 1
Schau mal, ob du damit etwas anfangen kannst.

VG
YAPD
Zuletzt geändert von YAPD am Sonntag 15. August 2021, 20:21, insgesamt 17-mal geändert.
-----
Yet Another Python Developer
Benutzeravatar
YAPD
User
Beiträge: 120
Registriert: Dienstag 27. Juli 2021, 23:23
Wohnort: Frankfurt am Main

Hab gerade gesehen, dass einige Sachen noch nicht passen,
es wird noch nicht hochgezählt, wenn du mehrere Getränke
der gleichen Art bestellst. Muss ich gerade noch korrigieren. :)

EDIT : Der Code in meinem vorherigen Post wurde angepasst.

Natürlich kannst du mit der Billing Klasse noch mehr machen,
also nur die Preise anzuzeigen ;)

Ich würde nur in der Methode 'createorderitem' der Verständlichkeit
halber anstatt 'itm' z.B. 'orderitm' oder so was verwenden, da wie
angemerkt bestimmte Namen reserviert und daher eine schlechte
Wahl als Variablennamen sind. :)

VG
YAPD
-----
Yet Another Python Developer
Benutzeravatar
YAPD
User
Beiträge: 120
Registriert: Dienstag 27. Juli 2021, 23:23
Wohnort: Frankfurt am Main

Kleine Anmerkungen :

Natürlich :

Code: Alles auswählen

print("Bill Of Fare : {}".format(self.orderfood)
anstatt :

Code: Alles auswählen

print("Bill Of Fare : ", self.orderfood )


'x' sollte 'foodcounter' heissen :

Code: Alles auswählen

for foodcounter in self.orderfood:
    print("{} : {} €".format(foodcounter, self.availablefood[foodcounter]*self.orderfood[foodcounter]))
'x' sollte 'drinkcounter' heissen :

Code: Alles auswählen

for drinkcounter in self.orderdrinks:
   print("{} : {} €".format(drinkcounter, self.availabledrinks[drinkcounter]*self.orderdrinks[drinkcounter]))

Der Aufruf der Billing Klasse sollte so aussehen :

ALT :

Code: Alles auswählen

Rechnung = Billing()                      
Billing.createbill(orderclass)
NEU :

Code: Alles auswählen

currentbill = Billing()                      
currentbill.createbill(currentorder)
VG
YAPD
-----
Yet Another Python Developer
Benutzeravatar
__blackjack__
User
Beiträge: 14056
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@YAPD: Anmerkungen zum Quelltext:

Zwischen Worte in Namen gehört ein Unterstrich, damitdasbesserlesbarist.

Konstanten werden KOMPLETT_GROSS geschrieben.

Attributnamen braucht man nicht noch mal alle mit dem Klassennamen anfangen lassen, die Information steck ja bereits dort drin.

`createorder()` ist entweder ein falscher, weil irreführender Name, oder das sollte eine Klassenmethode sein, die tatsächlich ein `Order`-Objekt erstellt. Und da sollte keine Benutzerinteraktion enthalten sein. Die gehören in die gesamte Klasse nicht hinein.

Methoden die das Objekt verändern sollten nicht `self` zurückgeben.

Der Name `orderclass` ist falsch. Das ist keine Klasse. Wenn schon müsste das `orderinstance` heissen. Da aber jedes Objekt ein Exemplar von irgendeinem Typ ist, könnte/müsste man `instance` an *jeden* Namen anhängen. Hat aber null Informationsgehalt, darum macht das keinen Sinn. Das ist einfach `order`. Das ist ja einer der Gründe für die Namenskonvention, dass man immer einen generischen Namen hat wenn Klassen in PascalCase und Exemplare davon in Kleinbuchstaben geschrieben werden.

`currentorder`, `order1`, und `order2` machen keinen Sinn. Du hast da das *selbe* Objekt an vier verschiedene Namen gebunden.

Bei `item` hast Du das `e` vergessen.

`Billing` ist keine sinnvolle Klasse und wird selbst als solche auch noch total falsch verwendet. Denn eigentlich wird nur die `__init__()` richtig verwendet, die einfach nur eine Leerzeile ausgibt. Die andere ”Methode” wird als Funktion aufgerufen, und das auch noch mit einem falschen Datentyp für `self`, nämlich mit einem `Order`-Objekt.

Das formatieren/ausgeben einer Bestellung als Rechnung kann man entweder als eigene Funktion schreiben, oder man implementiert `Order.__str__()` entsprechend und gibt das Objekt dann einfach mit `print()` aus.

Code: Alles auswählen

#!/usr/bin/env python3
import itertools
from collections import defaultdict


class Order:
    AVAILABLE_FOOD = {"Baked Fries": 5.50}
    AVAILABLE_DRINKS = {"Water": 1.75, "Coffee": 2.50}
    _ORDER_NUMBERS = itertools.count(1)

    def __init__(self, table_number, person_count, number=None):
        self.number = next(self._ORDER_NUMBERS) if number is None else number
        self.table_number = table_number
        self.person_count = person_count
        self.food = defaultdict(int)
        self.drinks = defaultdict(int)

    def __str__(self):
        lines = [
            f"Order For Table           : {self.table_number}",
            f"Associated Persons        : {self.person_count}",
            f"Registered Order - Number : {self.number}",
            "",
            "Bill Of Fare:",
        ]
        for prices, items in [
            (self.AVAILABLE_FOOD, self.food),
            (self.AVAILABLE_DRINKS, self.drinks),
        ]:
            lines.extend(
                f"{name} : {prices[name] * count} €"
                for name, count in items.items()
            )
        return "\n".join(lines)

    def add(self, item):
        if item in self.AVAILABLE_FOOD:
            self.food[item] += 1
        elif item in self.AVAILABLE_DRINKS:
            self.drinks[item] += 1
        else:
            raise KeyError(f"{item!r} is not available!")


def main():
    order = Order(1, 4)
    for item in ["Baked Fries", "Water"]:
        print(f"Adding {item!r} to order!")
        try:
            order.add(item)
        except KeyError as error:
            print(error)

    print(order)


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
YAPD
User
Beiträge: 120
Registriert: Dienstag 27. Juli 2021, 23:23
Wohnort: Frankfurt am Main

__blackjack__ hat geschrieben: Sonntag 15. August 2021, 21:03 @YAPD: Anmerkungen zum Quelltext:

Zwischen Worte in Namen gehört ein Unterstrich, damitdasbesserlesbarist.

Konstanten werden KOMPLETT_GROSS geschrieben.

Attributnamen braucht man nicht noch mal alle mit dem Klassennamen anfangen lassen, die Information steck ja bereits dort drin.

`createorder()` ist entweder ein falscher, weil irreführender Name, oder das sollte eine Klassenmethode sein, die tatsächlich ein `Order`-Objekt erstellt. Und da sollte keine Benutzerinteraktion enthalten sein. Die gehören in die gesamte Klasse nicht hinein.

Methoden die das Objekt verändern sollten nicht `self` zurückgeben.

Der Name `orderclass` ist falsch. Das ist keine Klasse. Wenn schon müsste das `orderinstance` heissen. Da aber jedes Objekt ein Exemplar von irgendeinem Typ ist, könnte/müsste man `instance` an *jeden* Namen anhängen. Hat aber null Informationsgehalt, darum macht das keinen Sinn. Das ist einfach `order`. Das ist ja einer der Gründe für die Namenskonvention, dass man immer einen generischen Namen hat wenn Klassen in PascalCase und Exemplare davon in Kleinbuchstaben geschrieben werden.

`currentorder`, `order1`, und `order2` machen keinen Sinn. Du hast da das *selbe* Objekt an vier verschiedene Namen gebunden.

Bei `item` hast Du das `e` vergessen.

`Billing` ist keine sinnvolle Klasse und wird selbst als solche auch noch total falsch verwendet. Denn eigentlich wird nur die `__init__()` richtig verwendet, die einfach nur eine Leerzeile ausgibt. Die andere ”Methode” wird als Funktion aufgerufen, und das auch noch mit einem falschen Datentyp für `self`, nämlich mit einem `Order`-Objekt.

Das formatieren/ausgeben einer Bestellung als Rechnung kann man entweder als eigene Funktion schreiben, oder man implementiert `Order.__str__()` entsprechend und gibt das Objekt dann einfach mit `print()` aus.

Code: Alles auswählen

#!/usr/bin/env python3
import itertools
from collections import defaultdict


class Order:
    AVAILABLE_FOOD = {"Baked Fries": 5.50}
    AVAILABLE_DRINKS = {"Water": 1.75, "Coffee": 2.50}
    _ORDER_NUMBERS = itertools.count(1)

    def __init__(self, table_number, person_count, number=None):
        self.number = next(self._ORDER_NUMBERS) if number is None else number
        self.table_number = table_number
        self.person_count = person_count
        self.food = defaultdict(int)
        self.drinks = defaultdict(int)

    def __str__(self):
        lines = [
            f"Order For Table           : {self.table_number}",
            f"Associated Persons        : {self.person_count}",
            f"Registered Order - Number : {self.number}",
            "",
            "Bill Of Fare:",
        ]
        for prices, items in [
            (self.AVAILABLE_FOOD, self.food),
            (self.AVAILABLE_DRINKS, self.drinks),
        ]:
            lines.extend(
                f"{name} : {prices[name] * count} €"
                for name, count in items.items()
            )
        return "\n".join(lines)

    def add(self, item):
        if item in self.AVAILABLE_FOOD:
            self.food[item] += 1
        elif item in self.AVAILABLE_DRINKS:
            self.drinks[item] += 1
        else:
            raise KeyError(f"{item!r} is not available!")


def main():
    order = Order(1, 4)
    for item in ["Baked Fries", "Water"]:
        print(f"Adding {item!r} to order!")
        try:
            order.add(item)
        except KeyError as error:
            print(error)

    print(order)


if __name__ == "__main__":
    main()
Danke für deine Anmerkungen, bei deinem Code gibt es viel, dass ich mir noch
anschauen muss, z. B. 'itertools' , 'defaultdict' , die Verwendung von '__str__' &
'__main__' usw.

Ich verstehe, dass ich deinen Code so aufrufe :

Code: Alles auswählen

order = Order(3,5)

bill = order.add("Water")
print(bill)
Aber wann geht es denn in main( ) ? Auch wenn ich die add Methode aufrufe,
die Zeile :

Code: Alles auswählen

print(f"Adding {item!r} to order!")
wird nie ausgeführt.

Zu meinem Code :

Die Klasse Billing hat eventuell doch Verwendung, wenn man die beiden Prozesse
trennen und nicht alles in eine Klasse packen will. Aber ich verstehe was du meinst.

Mit den einzelnen Aufrufen :

Code: Alles auswählen

order1 = currentorder.createorderitem("Baked Fries")
order2 = currentorder.createorderitem("Water")
habe ich einfach neue Elemente hinzugefügt. Allerdings macht die Variable davor
wenig Sinn.

VG
YAPD
-----
Yet Another Python Developer
Benutzeravatar
__blackjack__
User
Beiträge: 14056
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

`main()` wird von der Modulebene im ``if __name__ == "__main__":``-Zweig aufgerufen wenn man das Modul als Programm ausführt. Die Funktion wird nicht aufgerufen wenn man das Modul importiert. Das ist der Sinn von dem ``if``. Damit man das Modul in einer Python-Shell oder aus einem anderen Modul heraus importieren kann, ohne das mehr passiert als das Konstanten, Funktionen, und Klassen definiert werden.

Natürlich wird die `print()`-Anweisung in der `main()`-Funktion nicht ausgeführt wenn man ausserhalb dieser Funktion `add()` auf einem `Order`-Objekt aufruft. Wie gesagt gehört Benutzerinteraktion nicht in dieses Objekt. Man trennt Geschäftslogik von Ein- und Ausgaben von/für den Benutzer. Denn nur so kann man die Logik leicht unabhängig von der Kommunikation mit einem Benutzer entwickeln und testen. Und man kann auch einfach die Bedienoberfläche austauschen, also ob nun Kommandozeilenprogramm, GUI, oder Webanwendung. Oder vielleicht sogar mehr als eine Möglichkeit der Interaktion mit der gleichen Geschäftslogik.

Ein Grund warum `__str__()` eventuell nicht so günstig ist. Für die Anzeige in einer GUI bräuchte man anderen Code, oder wenn man die Rechnung als PDF erstellen möchte, oder über einen POS-Drucker ausgeben will, oder was auch immer. Wenn die Anwendung mehrsprachig werden soll, ist eine starre `__str__()`-Methode auch nicht geeignet. Aber für den ersten Entwurf, dass man eine Rechnung einfach per `print()` auf der Konsole ausgeben oder mit `str()` in eine Zeichenkette wandeln kann, ist `__str__()` ganz nützlich.

Ich weiss bei `Billing` nicht so wirklich was das mal werden könnte/sollte. Es ist halt so wie es da steht keine Klasse weil es 0 Zustand gibt. Zustand ohne Methoden geht ja noch, aber eine Klasse ohne Zustand bündelt nur Funktionen. Und das Mittel um Funktionen zu bündeln ist in Python das Modul.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Robert456
User
Beiträge: 5
Registriert: Sonntag 15. August 2021, 12:09

@ Danke auch für dein Bemühen YPAD!
@__blackjack__ was muss noch bei deinem code hin zugefügt werden das der Rechnungsbetrag angezeigt wird?
Benutzeravatar
__blackjack__
User
Beiträge: 14056
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Robert456: Code der alles aufaddiert. Also das `extend()` geht dann so nicht mehr, weil da für die einzelnen Posten mehr passieren muss als nur die Liste mit den Zeilen zu erweitern.

Oder man spendiert `Order`-Objekten noch eine `get_total()`-Methode (oder ein `total`-Property) welches den Gesamtpreis errechnet.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Robert456
User
Beiträge: 5
Registriert: Sonntag 15. August 2021, 12:09

@__blackjack__: das war meine ursprüngliche Frage, wie ich die Beziehung zwischen der Eingabe und der 'Speisekarte' codier(?), um die dann in der GUI dar zu stellen.
Benutzeravatar
__blackjack__
User
Beiträge: 14056
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Robert456: Da wurde doch schon auf die Dokumentation und das Tutorial dort verwiesen. Und sowohl YAPD als auch ich berechnen doch immerhin schon den Preis jedes einzelnen Postens in Abhängigkeit von den hinterlegten Stückpreisen und der Bestellmenge. Das musst Du halt auch machen und dabei dann noch alles aufaddieren für einen Endpreis.

Eventuell würde es vielleicht auch Sinn machen für einzelne Posten eine Klasse einzuführen die Namen, Stückpreis, und Anzahl des jeweiligen Postens enthält. Oder nur die Namen und gar nicht zu einem Posten mit Anzahl zusammenfassen, weil das sonst im Restaurant für den Kellner nervig wird, wenn er die Bestellung dann am Tisch auf mehrere zahlende Gäste aufteilen muss. Das sind Einzelposten zum Zusammenrechnen wahrscheinlich praktischer.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten