This page presents a complete, production-quality Python program for a Philippine wine shop ordering system called VINO PH. Whether you are a beginner programmer in the Philippines, a student learning Python fundamentals, or a developer revisiting the foundations, this walkthrough is designed to guide you — line by line — through one of the most practical introductory Python programs you can build.
VINO PH demonstrates several core Python concepts: how to model real-world data using nested dictionaries, how to display formatted menus with f-strings and format specifiers, how to handle unpredictable user input using while True loops with try/except exception handling, and how to compute and display a formatted receipt. Each concept is introduced in the context of a real, working program — not just isolated code snippets — so you can see why each design decision was made, not just what the code does.
By the end of this walkthrough, you will understand not just the code, but the thinking behind the code — the kind of logical reasoning that separates a beginner who writes code from a developer who engineers solutions.
A complete logical breakdown of the Python script — every line explained, step by step.
# ── VINO PH — Wine Shop (Philippines) ── # Python 3 · by Glenn Pansensoy · Valleys & Bytes wines = { 1: {"name": "Yellow Tail Cabernet Sauvignon (Australia)", "price": 799}, 2: {"name": "Jacob's Creek Shiraz (Australia)", "price": 899}, 3: {"name": "Concha y Toro Frontera Cabernet Sauvignon (Chile)", "price": 599}, 4: {"name": "Beringer Founders' Estate Merlot (USA)", "price": 1299}, 5: {"name": "Robert Mondavi Private Selection Chardonnay (USA)", "price": 1499}, 6: {"name": "Gallo Family Vineyards Merlot (USA)", "price": 649}, 7: {"name": "Sutter Home Cabernet Sauvignon (USA)", "price": 699}, 8: {"name": "Lindemans Bin 65 Chardonnay (Australia)", "price": 899}, 9: {"name": "Penfolds Koonunga Hill Shiraz Cabernet (Australia)", "price": 1199}, 10: {"name": "Wolf Blass Yellow Label Cabernet Sauvignon", "price": 1099}, 11: {"name": "Hardys Stamp Shiraz Cabernet (Australia)", "price": 799}, 12: {"name": "Oxford Landing Cabernet Sauvignon (Australia)", "price": 749}, 13: {"name": "Woodbridge by Robert Mondavi Cabernet (USA)", "price": 999}, 14: {"name": "Kim Crawford Sauvignon Blanc (New Zealand)", "price": 1699}, 15: {"name": "Oyster Bay Sauvignon Blanc (New Zealand)", "price": 1499}, } # ── Welcome banner ── print("==================================================") print(" WELCOME TO VINO PH - Wine Shop (Philippines)") print(" Available Wines (Prices in PHP per bottle)") print("==================================================") # ── Display the menu via for loop ── for num, wine in wines.items(): print(f"{num:2d}. {wine['name']:50} ₱{wine['price']:,.0f}") # ── First input loop: wine selection ── while True: try: choice = int(input("\nEnter the number of the wine you want to buy (1-15): ")) if choice in wines: selected_wine = wines[choice] print(f"\nYou selected: {selected_wine['name']}") print(f"Price per bottle: ₱{selected_wine['price']:,}") break else: print("Invalid number! Please choose between 1 and 15.") except ValueError: print("Please enter a valid number!") # ── Second input loop: quantity ── while True: try: quantity = int(input("\nEnter quantity (bottles): ")) if quantity > 0: break else: print("Quantity must be at least 1!") except ValueError: print("Please enter a valid number!") # ── Computation ── total_cost = selected_wine['price'] * quantity # ── Print receipt ── print(f"Wine : {selected_wine['name']}") print(f"Price per bottle: ₱{selected_wine['price']:,}") print(f"Quantity : {quantity}") print(f"Total Cost : ₱{total_cost:,}") print("Thank you for shopping at VINO PH! 🍷")
wines = { 1: {"name": "Yellow Tail Cabernet Sauvignon", "price": 799}, 2: {"name": "Jacob's Creek Shiraz", "price": 899}, ... (15 items total) }
dict) is the ideal Python data structure when you need to look up values by a key. Here, each wine number (1–15) is a key, and each value is another dictionary containing the wine's name and price. This creates a nested dictionary — a dictionary inside a dictionary.5), the program uses it as a key: wines[5] instantly returns {"name": "Robert Mondavi...", "price": 1499}. No looping required — dictionary lookup is O(1) — instant access regardless of how many wines exist.print("==================================================") print(" WELCOME TO VINO PH - Wine Shop (Philippines)") print(" Available Wines (Prices in PHP per bottle)") print("==================================================")
print() is Python's built-in function for displaying text output to the terminal. Multiple calls construct a visual banner that greets the user, establishes the shop's identity, and sets context before showing products.= signs create a visual border — a classic terminal UI technique mimicking a real shop menu or POS system.print() statements sequentially from top to bottom. Each call outputs one line followed by a newline character. The strings are string literals displayed exactly as written.for num, wine in wines.items(): print(f"{num:2d}. {wine['name']:50} ₱{wine['price']:,.0f}")
for loop with .items() efficiently iterates over every wine in the dictionary without repeating code. Writing 15 individual print() calls would be tedious. The loop handles all 15 wines with just 2 lines.{} braces. The format specifiers control column widths and number display:{num:2d} — integer, at least 2 characters wide{wine['name']:50} — string padded to 50 characters{wine['price']:,.0f} — float with commas, 0 decimal places
wines.items() returns each key-value pair as a tuple. The for num, wine in syntax unpacks each tuple — num gets the integer key and wine gets the nested dictionary. This is called tuple unpacking.while True: try: choice = int(input("\nEnter the number of the wine (1-15): ")) if choice in wines: selected_wine = wines[choice] break else: print("Invalid number! Please choose between 1 and 15.") except ValueError: print("Please enter a valid number!")
while True creates an infinite loop that runs until explicitly stopped with break. This pattern guarantees the program never proceeds with invalid input — it keeps asking until the user provides a valid response.input() always returns a string. Wrapping it in int() converts it to an integer — but if the user types "abc", int() raises a ValueError. The try/except block catches that crash and prints a friendly message instead.in operator checks if the value exists as a key in the wines dictionary. Returns True only for 1–15 — this is a range and existence check combined into one clean operation.while True: try: quantity = int(input("\nEnter quantity (bottles): ")) if quantity > 0: break else: print("Quantity must be at least 1!") except ValueError: print("Please enter a valid number!")
> form reads more naturally as "Must be a positive number." It also explicitly rejects zero, negative numbers, and text — all invalid purchase quantities.break immediately exits the innermost while loop. Without it, the loop would run forever even after getting valid input. Think of break as the exit door of the loop.total_cost = selected_wine['price'] * quantity
selected_wine is a reference to the inner dictionary (e.g. {"name": "Kim Crawford...", "price": 1699}). Using ['price'] accesses the integer stored at that key — the result is then multiplied by quantity.print(f"Wine : {selected_wine['name']}") print(f"Price per bottle: ₱{selected_wine['price']:,}") print(f"Quantity : {quantity}") print(f"Total Cost : ₱{total_cost:,}") print("Thank you for shopping at VINO PH! 🍷")
:, format spec adds thousands separators (e.g. 1699 → 1,699) for currency readability.:, format specifier instructs Python to insert commas every 3 digits. So 16990 becomes ₱16,990 automatically — no manual string manipulation required. The ₱ symbol is a Unicode character typed directly into the string.Understanding VINO PH means understanding the building blocks it is composed of. Below is a deeper exploration of the most important Python concepts in this program — written for learners who want to go beyond surface-level understanding and truly internalize why Python works the way it does.
Nested Dictionaries as Mini-Databases. In professional software, data is usually stored in a database. In a small Python program, a nested dictionary serves exactly the same purpose. The outer dictionary's keys (integers 1–15) act like row IDs. The inner dictionaries act like rows in a table, each containing a name column and a price column. This is the same mental model used in SQL, MongoDB, and most modern data systems.
The Defensive Input Pattern. The combination of while True + try/except + break is one of the most important patterns in Python programming. It is called defensive programming — you assume the user will make mistakes and design your code to handle them gracefully without crashing. This same pattern is used in production-level command-line tools, system scripts, and automation code all over the world.
f-strings vs Older String Formatting. Python has had three string formatting methods: the old % operator, the .format() method, and modern f-strings (introduced in Python 3.6). f-strings are now the preferred method because they are readable, concise, and support format specifiers directly inside the curly braces. VINO PH uses advanced format specs like :2d, :50, and :,.0f — knowing how to read these is an important skill for any Python developer.
Try extending this program: add a discount system (if quantity >= 5: discount = 0.10), a cart system that allows multiple purchases, or export the receipt to a .txt file using open("receipt.txt", "w"). These extensions will solidify every concept you learned here.
VINO PH is not just a working program — it is a demonstration of clean, professional coding habits. Here are the specific best practices it models that you should carry into every program you write:
wines dict). If a price changes, you update it in exactly one location.selected_wine, total_cost, and quantity tell you exactly what they store at a glance.# comments explain the intent of each section without over-explaining obvious lines.After mastering this program, your next steps in Python should be: functions and modules → file I/O → object-oriented programming (classes) → working with APIs → databases with SQLite or PostgreSQL. Each step builds directly on what you learned here.
| Concept | Python Syntax | Purpose in This Program |
|---|---|---|
| Nested Dictionary | wines = {1: {"name":..., "price":...}} | Stores all 15 wines and their prices as a structured database |
| print() | print("text") | Displays banner, menu, confirmations, and receipt to the user |
| for loop + .items() | for num, wine in wines.items(): | Iterates and prints all 15 wines without repeating code |
| f-string formatting | f"{num:2d}. {name:50} ₱{price:,.0f}" | Formats menu and receipt output with aligned columns and commas |
| Infinite loop | while True: | Keeps asking for input until the user enters a valid response |
| Exception handling | try: ... except ValueError: | Prevents crashes when user types non-numeric input |
| Type conversion | int(input(...)) | Converts the string returned by input() into a usable integer |
| Membership test | if choice in wines: | Validates that the user's number matches an actual wine key (1–15) |
| break statement | break | Exits the while loop once valid input is confirmed |
| Arithmetic | total_cost = price * quantity | Computes the final purchase total after both inputs are gathered |
Stay connected for more Python tutorials, code walkthroughs, and tech content from Valleys & Bytes.
Get notified when new Python tutorials, code walkthroughs, and tech articles are published. No spam — ever.
🔒 Your email is safe. Unsubscribe anytime. No spam, ever.
Congratulations on completing this walkthrough. You have now seen not just a working Python program, but the thinking process behind every design choice — from the nested dictionary as a mini-database, to the defensive input pattern, to the receipt formatting that mirrors a real Philippine POS system.
This is what separates a programmer who copies code from a developer who understands it. You now understand it. Every concept in VINO PH — dictionaries, loops, exception handling, f-strings, arithmetic — appears in real-world Python projects every single day, from simple scripts to enterprise applications.
Keep building. Keep breaking things. Keep reading. The best programmers never stop being curious — and you are already on the right path.
🐍 Review the Code AgainCopyright Notice: All original content on this page — including explanations, walkthroughs, commentary, and structure — is © 2026 Glenn Pansensoy / Valleys & Bytes. All rights reserved. The Python source code (VINO PH) is provided for educational purposes.
Educational Use: The code and explanations on this page are provided for learning and non-commercial educational use. You may adapt the code for personal or academic projects with attribution to the original author.
Advertising Disclosure: This page contains Google AdSense advertisements. These are served automatically by Google and do not constitute endorsements by the author. See Privacy Policy for details on data collected by advertising partners.
Affiliate / Sponsorship: This page has no affiliate links or sponsored content. All wine names and prices mentioned are fictional examples for educational purposes only.
Accuracy: While every effort is made to ensure the technical accuracy of the content, programming languages evolve. Always consult the official Python documentation for the most current specifications.
For full legal details, see: Privacy Policy · Terms of Service · Cookie Policy
💬 Comments
Have a question, correction, or insight? Leave a comment below — all feedback is welcome!