Das Erlernen von Python durch isolierte Übungen ist nützlich, aber es erfasst nicht ganz, wie es sich anfühlt, etwas Reales zu bauen. In den Übungen lernen Sie die Syntax für Wörterbücher, Schleifen und Funktionen isoliert kennen. Ein Projekt zeigt Ihnen, wie diese Teile zusammenwirken, um eine Anwendung zu erstellen, die tatsächlich etwas tut.

In diesem Tutorial erstellen wir eine App zum Bestellen von Lebensmitteln von Grund auf. Stellen Sie sich vor, Sie betreiben ein lokales Restaurant und möchten Ihren Kunden die Möglichkeit geben, Ihre Speisekarte zu durchsuchen, Artikel in den Warenkorb zu legen, Mengen anzupassen und eine Bestellung aufzugeben. Wir erstellen das alles unter Verwendung der grundlegenden Python-Grundlagen, ohne dass externe Bibliotheken erforderlich sind.

Am Ende verfügen Sie über eine vollständige, funktionierende Python-Anwendung und ein klareres Gefühl dafür, wie Funktionen, Wörterbücher und Schleifen in eine echte Programmarchitektur passen.

Was Sie lernen werden

Am Ende dieses Tutorials wissen Sie, wie Sie:

  • Verwenden Sie verschachtelte Wörterbücher, um strukturierte Menüdaten zu speichern
  • Schreiben Sie modulare Funktionen, die jeweils eine Verantwortung übernehmen
  • Benutzen Sie die enter() Funktion zum Erstellen interaktiver Benutzererlebnisse
  • Die Kette funktioniert zusammen, sodass jeder Baustein in den nächsten einfließt
  • Steuern Sie den Anwendungsfluss mit a whereas Schleife und boolesches Flag
  • Testen und debuggen Sie beim Erstellen inkrementell

Bevor Sie beginnen

Sie benötigen Python 3.8+ und Jupyter Pocket book. Es sind keine externen Bibliotheken erforderlich. Wenn Sie zunächst die Grundlagen auffrischen möchten, ist die Python-Grundlagen für die Datenanalyse Der Pfad deckt die Wörterbuch-, Schleifen- und Funktionskenntnisse ab, die diesem Projekt zugrunde liegen.

Greifen Sie auf das vollständige Projekt zu Dataquest-App und das Lösungsnotizbuch auf GitHub.

Die Projektarchitektur

Bevor Sie Code schreiben, ist es hilfreich, darüber nachzudenken, was die Anwendung benötigt. Eine Essensbestell-App besteht ungefähr aus drei Ebenen:

Daten: Was steht auf der Speisekarte? Was ist im Warenkorb? Welche Aktionen kann ein Benutzer durchführen?

Logik: Funktionen, die jede Aktion verarbeiten – Anzeigen des Menüs, Hinzufügen von Artikeln, Entfernen von Artikeln, Anzeigen und Ändern des Warenkorbs und Auschecken.

Fließen: Eine Hauptschleife, die alles miteinander verbindet, Benutzereingaben entgegennimmt und die richtige Funktion aufruft.

Wir werden diese Schichten der Reihe nach aufbauen.

Teil 1: Globale Variablen

Globale Variablen sind Werte, die konstant bleiben oder in der gesamten Anwendung zugänglich sein müssen. Wir werden sie alle im Voraus definieren.

RESTAURANT_NAME = "Hungry Hare"

Konventionsgemäß werden globale Konstanten in ALL_CAPS geschrieben. Dies ändert nichts daran, wie Python damit umgeht, aber es signalisiert jedem, der Ihren Code liest, dass dieser Wert stabil sein soll.

Unser Menü verwendet eine verschachtelte Wörterbuchstruktur:

menu = {
    "sku1": {"identify": "Hamburger", "worth": 6.51},
    "sku2": {"identify": "Cheeseburger", "worth": 7.75},
    "sku3": {"identify": "Milkshake", "worth": 5.99},
    "sku4": {"identify": "Fries", "worth": 2.39},
    "sku5": {"identify": "Sub", "worth": 5.87},
    "sku6": {"identify": "Ice Cream", "worth": 1.55},
    "sku7": {"identify": "Fountain Drink", "worth": 3.45},
    "sku8": {"identify": "Cookie", "worth": 3.15},
    "sku9": {"identify": "Brownie", "worth": 2.46},
    "sku10": {"identify": "Sauce", "worth": 0.75}
}

Jeder Menüpunkt wird durch eine SKU (Inventory Retaining Unit) und nicht durch seinen Namen identifiziert. Dies ist wichtig für die Wartbarkeit: Wenn sich der Preis eines Hamburgers ändert, aktualisieren Sie einen Wörterbuchwert. Wenn das Ingredient umbenannt wird, aktualisieren Sie den Namen, ohne etwas anderes in der Codebasis zu berühren. Das Referenzieren von Dingen anhand einer stabilen ID ist ein Muster, das Sie in realen Systemen sehen werden.

Das App-Aktionswörterbuch ordnet Zahlen Beschreibungen zu. Dies sind die Auswahlmöglichkeiten, die Ihrem Benutzer bei jedem Schritt angezeigt werden:

app_actions = {
    "1": "Add a brand new menu merchandise to cart",
    "2": "Take away an merchandise from the cart",
    "3": "Modify a cart merchandise's amount",
    "4": "View cart",
    "5": "Checkout",
    "6": "Exit"
}

Zum Schluss noch der Umsatzsteuersatz und ein leerer Warenkorb:

SALES_TAX_RATE = 0.07
cart = {}

Der Warenkorb beginnt leer und wird mit den Bestellungen des Benutzers gefüllt. Es werden SKU-Schlüssel mit ganzzahligen Mengen als Werte gespeichert: {"sku1": 2, "sku4": 1} würde zwei Hamburger und eine Portion Pommes bedeuten.

Lerneinblick: Die Trennung Ihrer Daten von Ihrer Logik ist eine der wertvollsten Gewohnheiten beim Programmieren. Wenn sich Ihr Menü in einem Wörterbuch und Ihr Warenkorb in einem anderen befindet, können Sie eines davon aktualisieren, ohne Ihren Funktionscode durchsuchen zu müssen, um herauszufinden, wo Preise oder Mengen gespeichert sind.

Teil 2: Anzeigen des Menüs

def display_menu():
    """Shows all menu merchandise SKUs, names, and costs."""
    print("n****Menu****n")
    for sku in menu:
        parsed_sku = sku(3:)
        merchandise = menu(sku)('identify')
        worth = menu(sku)('worth')
        print("(" + parsed_sku + ") " + merchandise + ": $" + str(worth))
    print("n")

sku(3:) schneidet das Präfix „sku“ ab, sodass der Benutzer „(1) Hamburger: $6.51“ anstelle von „(sku1) Hamburger: $6.51“ sieht. Der Preis muss mit in eine Zeichenfolge konvertiert werden str() vor der Verkettung, da Sie es nicht verwenden können + um einen String und einen Float direkt zu kombinieren.

Testen Sie es gleich:

display_menu()
****Menu****

(1) Hamburger: $6.51
(2) Cheeseburger: $7.75
(3) Milkshake: $5.99
(4) Fries: $2.39
...

Lerneinblick: Testen Sie jede Funktion, sobald Sie mit dem Schreiben fertig sind. Es ist viel einfacher, einen Fehler in einer 10-Zeilen-Funktion zu erkennen, als ihn zu erkennen, nachdem Sie 100 weitere Zeilen geschrieben haben, die davon abhängen. Jede Funktion in diesem Projekt erhält direkt nach ihrer Definition einen Testaufruf.

Teil 3: Artikel zum Warenkorb hinzufügen

def add_to_cart(sku, amount=1):
    """
    Add an merchandise and its amount to the cart.

    :param string sku: The enter SKU quantity being ordered.
    :param int amount: The enter amount being ordered.
    """
    if sku in menu:
        if sku in cart:
            cart(sku) += amount
        else:
            cart(sku) = amount
        print("Added", amount, "of", menu(sku)('identify'), "to the cart.")
    else:
        print("I am sorry. The menu quantity", sku, "that you simply entered shouldn't be on the menu.")

Zwei wichtige Designentscheidungen hier. Erste, amount=1 ist ein Standardparameterwert. Wenn ein Kunde einen Artikel hinzufügt, ohne die Anzahl anzugeben, geht die Funktion von einem Artikel aus. Wenn sie mehr angeben, wird die Standardeinstellung außer Kraft gesetzt. Dies ist eine gute UX, da dadurch die Anzahl der für den allgemeinen Fall erforderlichen Eingaben reduziert wird.

Zweitens prüft die Funktion, ob die SKU bereits im Warenkorb vorhanden ist. Wenn dies der Fall ist, wird die Anzahl erhöht. Ist dies nicht der Fall, wird ein neuer Eintrag erstellt. Dadurch wird verhindert, dass eine zweite Hamburgerbestellung die erste überschreibt.

Testen Sie es:

add_to_cart("sku1")       # Provides 1 hamburger
add_to_cart("sku1", 10)   # Provides 10 extra hamburgers
print(cart)
Added 1 of Hamburger to the cart.
Added 10 of Hamburger to the cart.
{'sku1': 11}

Teil 4: Artikel aus dem Warenkorb entfernen

def remove_from_cart(sku):
    """
    Take away an merchandise from the cart.

    :param string sku: The enter SKU quantity to take away from the cart.
    """
    if sku in cart:
        removed_val = cart.pop(sku)
        print("Eliminated", removed_val, "of", menu(sku)('identify'), "from the cart.")
    else:
        print(f"I am sorry. The merchandise with SKU {sku} shouldn't be presently within the cart.")

dict.pop(key) Beide entfernen den Schlüssel und geben seinen Wert in einem Vorgang zurück. Wir verwenden den zurückgegebenen Wert, um dem Benutzer mitzuteilen, was entfernt wurde. Beachten Sie die else department behandelt den Fall, dass der Benutzer versucht, etwas zu entfernen, das sich nicht im Warenkorb befindet – die Funktion gibt eine hilfreiche Meldung aus, anstatt abzustürzen.

Die F-Saite in der else Zweig (f"I am sorry. The merchandise with SKU {sku}...") ist eine sauberere Different zur Zeichenfolgenverkettung für Fälle, in denen Sie eine Variable einbetten müssen. Alles drin {} wird ausgewertet und in den String eingefügt.

Teil 5: Warenkorbmengen ändern

def modify_cart(sku, amount):
    """
    Modify an merchandise's amount within the cart.

    :param string sku: The enter SKU quantity being modified.
    :param int amount: The enter new amount to make use of for the SKU.
    """
    if sku in cart:
        if amount > 0:
            cart(sku) = amount
            print("Modified", menu(sku)('identify'), "amount to", amount, "within the cart.")
        else:
            remove_from_cart(sku)
    else:
        print(f"I am sorry.", menu(sku)('identify'), "shouldn't be presently within the cart.")

Diese Funktion demonstriert den Aufruf einer Funktion aus einer anderen heraus. Wenn der Benutzer eine Menge auf Null oder darunter festlegt, gibt es keinen Grund, den Artikel im Warenkorb zu belassen – additionally modify_cart Anrufe remove_from_cart anstatt diese Logik zu duplizieren. Dies ist in der Praxis das Prinzip „Wiederholen Sie sich nicht“: Wenn zwei Funktionen dasselbe tun müssen, ruft eine die andere auf.

Teil 6: Warenkorbinhalt anzeigen

def view_cart():
    """Show the menu merchandise names and portions contained in the cart."""
    print("n****Cart Contents****n")
    subtotal = 0
    for sku in cart:
        if sku in menu:
            amount = cart(sku)
            subtotal += menu(sku)("worth") * amount
            print(amount, " x ", menu(sku)("identify"))
    tax = subtotal * SALES_TAX_RATE
    complete = subtotal + tax
    print("Complete: $", spherical(complete, 2))
    print("n")

Die Funktion durchläuft den Warenkorb, sucht im Menüwörterbuch nach dem Preis jedes Artikels und berechnet eine Zwischensumme. Steuern und Gesamtsumme werden außerhalb der Schleife berechnet, da sie nur einmal berechnet werden müssen, nachdem alle Posten erfasst wurden. Durch das Runden der Summe auf zwei Dezimalstellen wird sichergestellt, dass der Dollarbetrag korrekt angezeigt wird.

Teil 7: Kasse

def checkout():
    """Show the subtotal data for the person to checkout."""
    print("n****Checkout****n")
    view_cart()
    print("Thanks to your order! Goodbye!")
    print("n")

Der Checkout ist bewusst einfach gestaltet, da die eigentliche Arbeit bereits erledigt ist view_cart(). Das ist Wiederverwendung in ihrer reinsten Type – eine Funktion ruft eine andere auf, die bereits weiß, wie sie genau das tut, was benötigt wird.

Teil 8: Benutzereingaben einholen

Dies ist die am meisten involvierte Funktion im Projekt. Es übernimmt die Erfassung der SKU- und Mengeneingaben des Benutzers mit integrierter Validierung.

def get_sku_and_quantity(sku_prompt, quantity_prompt=None):
    """
    Get enter from the person.

    :param string sku_prompt: Immediate displayed earlier than SKU entry.
    :param string quantity_prompt: Immediate displayed earlier than amount entry.
        Defaults to None when amount enter shouldn't be wanted.

    :returns: The complete sku# worth and optionally the amount.
    """
    item_sku = enter(sku_prompt)
    item_sku = "sku" + item_sku

    if quantity_prompt:
        amount = enter(quantity_prompt)
        if not amount.isdigit():
            amount = 1
        amount = int(amount)
        return item_sku, amount
    else:
        return item_sku

Ein paar Dinge, die es wert sind, hier verstanden zu werden. Der enter() Die Funktion gibt immer einen String zurück. Wenn ein Benutzer „4“ eingibt, speichert Python diese als Zeichenfolge "4"nicht die ganze Zahl 4. Deshalb rufen wir an int(amount) bevor Sie es zurückschicken.

Der item_sku = "sku" + item_sku Zeile stellt „sku“ allen Eingaben des Benutzers voran. Das bedeutet, dass der Benutzer nur „4“ eingeben muss, um auf Fries zu verweisen, und die Funktion den vollständigen Schlüssel zusammenstellt "sku4" das passt zu unserem Wörterbuch.

quantity_prompt=None als Standardparameter macht die Funktion flexibel. Für einige Aktionen (z. B. das Entfernen eines Artikels) ist nur die SKU erforderlich. Andere (z. B. Hinzufügen oder Ändern) benötigen sowohl die SKU als auch eine Menge. Die gleiche Funktion behandelt beide Fälle, indem sie prüft, ob quantity_prompt bereitgestellt wurde.

Der return item_sku, amount Die Zeile gibt zwei Werte als Tupel zurück. Beim Aufruf dieser Funktion kann der Aufrufer beide Werte in einer Zeile entpacken: ordered_sku, amount = get_sku_and_quantity(...).

Teil 9: Die Hauptauftragsschleife

Wenn alle Bausteine ​​vorhanden sind, werden sie durch die Bestellschleife miteinander verbunden.

def order_loop():
    """Loop ordering actions till checkout or exit."""
    print("Welcome to the " + RESTAURANT_NAME + "!")
    ordering = True

    whereas ordering:
        print("n****Ordering Actions****n")
        for quantity in app_actions:
            description = app_actions(quantity)
            print("(" + quantity + ")", description)

        response = enter("Please enter the variety of the motion you need to take: ")

        if response == "1":
            display_menu()
            sku_prompt = "Please enter the SKU quantity for the menu merchandise you need to order: "
            quantity_prompt = "Please enter the amount you need to order (default is 1): "
            ordered_sku, amount = get_sku_and_quantity(sku_prompt, quantity_prompt)
            add_to_cart(ordered_sku, amount)

        elif response == "2":
            display_menu()
            sku_prompt = "Please enter the SKU quantity for the menu merchandise you need to take away: "
            item_sku = get_sku_and_quantity(sku_prompt)
            remove_from_cart(item_sku)

        elif response == "3":
            display_menu()
            sku_prompt = "Please enter the SKU quantity for the menu merchandise you need to modify: "
            quantity_prompt = "Please enter the amount you need to change to (default is 1): "
            item_sku, amount = get_sku_and_quantity(sku_prompt, quantity_prompt)
            modify_cart(item_sku, amount)

        elif response == "4":
            view_cart()

        elif response == "5":
            checkout()
            ordering = False

        elif response == "6":
            print("Goodbye!")
            ordering = False

        else:
            print("You've entered an invalid motion quantity. Please attempt once more.")

Der ordering = True Flagge steuert die whereas Schleife. Solange es ist Trueläuft die Schleife weiter und zeigt das Aktionsmenü an. Wenn der Benutzer auscheckt (Antwort "5") oder beendet (response "6"), ordering eingestellt ist False und die Schleife endet.

Jeder Aktionszweig ruft eine Funktion auf, die wir bereits geschrieben haben. Die Schleife selbst besteht quick ausschließlich aus Funktionsaufrufen – und genau darum geht es. Die einzelnen Funktionen kümmern sich um die Particulars; Die Schleife verwaltet den Fluss.

Führen Sie die App aus mit:

order_loop()
Welcome to the Hungry Hare!

****Ordering Actions****

(1) Add a brand new menu merchandise to cart
(2) Take away an merchandise from the cart
(3) Modify a cart merchandise's amount
(4) View cart
(5) Checkout
(6) Exit

Please enter the variety of the motion you need to take:

Lerneinblick: Der whereas Eine Schleife mit einem booleschen Flag ist ein gängiges Muster für interaktive Anwendungen. Das Erlebnis läuft so lange, bis der Benutzer ausdrücklich signalisiert, dass er fertig ist. Ohne die ordering = False Zeilen würde die Schleife ewig laufen. Sicherzustellen, dass jede Schleife eine klare Beendigungsbedingung hat, ist eine der ersten Gewohnheiten, die man sich als Programmierer aneignen sollte.

Was wir gebaut haben

Ausgehend von einem leeren Notizbuch haben wir eine vollständige interaktive App zum Bestellen von Lebensmitteln erstellt, die ausschließlich auf Python-Grundlagen basiert. Die vollständige Architektur sieht folgendermaßen aus:

Globale Datenschicht: menu, cart, app_actions, RESTAURANT_NAME, SALES_TAX_RATE

Funktionsschicht: display_menu(), add_to_cart(), remove_from_cart(), modify_cart(), view_cart(), checkout(), get_sku_and_quantity()

Anwendungsschleife: order_loop() – der Einstiegspunkt, der alle Funktionen miteinander verbindet

Jede Funktion behandelt eine Sache. Jede Ebene hängt von der darunter liegenden ab. Durch diese Struktur ist die App einfach zu testen, leicht zu erweitern und leicht zu erklären.

Nächste Schritte

Fügen Sie einen Inventarbefehl hinzu. Im Second gibt es keine Möglichkeit, Ihren Warenkorb anzuzeigen, ohne über das Aktionsmenü zu gehen. Ein kurzer view_cart() Der als Aktion „7“ hinzugefügte Anruf wäre eine einfache Ergänzung.

Vervollständigen Sie die modify_cart Logik. Im Lösungsnotizbuch ist ein Platzhalter für diese Funktion enthalten, was eine gute Gelegenheit zum selbstständigen Üben bietet. Die Logik ist sehr ähnlich add_to_cart Und remove_from_cartVersuchen Sie additionally, es umzusetzen, indem Sie sich an dem orientieren, was Sie bereits geschrieben haben.

Fügen Sie eine klare Warenkorboption hinzu. Eine Funktion, die zurückgesetzt wird cart = {} und eine Bestätigungsnachricht ausgibt, ist eine kleine, aber zufriedenstellende Ergänzung.

Reduzieren Sie Wiederholungen. Beachten Sie das display_menu() wird am Anfang jeder Bestellaktion in der Hauptschleife aufgerufen. Dieser wiederholte Anruf könnte herausgerechnet werden, um Doppelarbeit zu vermeiden.

Erstellen Sie ein Frontend. Diese Anwendung ist das Backend – die Logik, die das Erlebnis antreibt. Wenn Sie ihm eine visuelle Oberfläche geben möchten, Streamlit oder Gradio sind einsteigerfreundliche Optionen, mit denen Sie Python-Apps in eine einfache Net-Benutzeroberfläche einbinden können, ohne HTML- oder JavaScript-Kenntnisse zu benötigen.

Ressourcen

Teilen Sie Ihre Model in der Neighborhood und taggen Sie @Anna_strahl. Wenn Sie die App um neue Funktionen erweitert, ein Frontend hinzugefügt oder sie mit einer Datenbank verbunden haben, sind diese Erweiterungen genau die Artwork von Ergänzungen, die ein Projekt portfoliowürdig machen.

Von admin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert