Fruit Retail β
Python Code Explained
Step by Step.
A complete, annotated walkthrough of a real Python program simulating a Philippine fruit retail market. Every design decision β from dictionary lookups to exception handling β is explained in plain language.
This guide assumes you have seen Python syntax before but want a deeper understanding of why professional developers make the choices they do. Each of the 8 steps dissects one key concept β its purpose, its implementation, how it operates, and why it matters in the real world.
Understanding the Fruit Retail Program
π A Real-World Python Learning Experience
Programming becomes meaningful when it solves real problems. The Philippine Fruit Retail Business simulation is a perfect beginner-to-intermediate Python project because it touches nearly every core concept you'll use in production code.
This program uses dictionaries for storing inventory, functions for organizing logic, loops for user interaction, exception handling for crash prevention, and arithmetic for business calculations.
Every code example in this guide is fully interactive β you can copy and run each snippet right in your browser using the Pyodide Python runtime. No setup required.
π― What You'll Learn
- Python dictionaries β O(1) key-value lookups for inventory
- while True + break β user-driven indefinite loops
- try/except β graceful error handling that prevents crashes
- List of tuples β immutable records inside a mutable container
- f-strings β clean string formatting with :.2f for currency
- Functions β reusability and separation of concerns
- __name__ guard β mandatory best practice for modular code
π The Program in Brief
A command-line fruit market simulation. Users browse Philippine fruit prices, add items to a cart, apply discount codes, and receive a formatted receipt β all built with core Python, no external libraries.
π Prerequisites: Basic Python syntax familiarity β variables, print statements, and if/else conditions. No prior knowledge of data structures, error handling, or functions is required.
Complete Implementation
Copy and save as fruit_retail.py β or Run it directly in your browser.
β οΈ Interactive program: this code calls input() several times. When you press Run, your browser will pop up prompt dialogs asking for the fruit, quantity, and discount code. Answer each prompt and the receipt will print once the program finishes.
# Philippine Fruit Retail Business Simulation # Core Python β no external libraries required fruits = { "mangoes": 180.00, "papayas": 75.00, "rambutan": 180.00, "coconuts": 50.00, "lanzones": 120.00, "mangosteen": 135.00, "bananas": 60.00, "pineapples": 75.00, "guavas": 50.00, "guyavanos": 130.00, "avocados": 120.00 } def display_fruits(): print("Available Fruits and Prices (per kg in PHP):") for fruit, price in fruits.items(): print(f"{fruit.capitalize()}: {price:.2f}") def get_discount(): codes = {"SALE10": 10, "FRESH15": 15, "FRUIT20": 20} while True: ans = input("Do you have a discount code? (yes/no): ").lower() if ans == 'yes': code = input("Enter your discount code: ").upper() if code in codes: discount = codes[code] print(f"Discount code accepted! {discount}% off applied.") return discount else: print("Invalid discount code. No discount applied.") return 0.0 elif ans == 'no': return 0.0 else: print("Please enter 'yes' or 'no'.") def calculate_total(): total_cost = 0.0 shopping_cart = [] while True: display_fruits() choice = input("\nEnter the fruit you want to buy (or 'done' to finish): ").lower() if choice == 'done': break if choice not in fruits: print("Invalid fruit selection.") continue try: quantity = float(input(f"Enter quantity in kg for {choice}: ")) if quantity <= 0: raise ValueError except ValueError: print("Invalid quantity. Please enter a positive number.") continue cost = fruits[choice] * quantity shopping_cart.append((choice, quantity, cost)) total_cost += cost print(f"Added {quantity} kg of {choice} for {cost:.2f} PHP.") if shopping_cart: print("\nShopping Cart Summary:") for item in shopping_cart: print(f"{item[0].capitalize()}: {item[1]} kg = {item[2]:.2f} PHP") discount_percent = get_discount() discount_amount = total_cost * (discount_percent / 100) final_total = total_cost - discount_amount print(f"\nSubtotal: {total_cost:.2f} PHP") if discount_percent > 0: print(f"Discount ({discount_percent}%): -{discount_amount:.2f} PHP") print(f"Total Cost: {final_total:.2f} PHP") else: print(f"\nTotal Cost: {total_cost:.2f} PHP") if __name__ == "__main__": print("Welcome to the Philippine Fruit Retail Business!") calculate_total() print("Thank you for shopping with us!")
8 Concepts, Fully Explained
Each section covers: Why Β· Snippet Β· How it operates Β· Significance
πΉ STEP 01 β Dictionary: Storing Fruits & Prices
fruits = {
"mangoes": 180.00,
"papayas": 75.00,
"rambutan": 180.00,
"coconuts": 50.00,
"lanzones": 120.00,
"mangosteen": 135.00,
"bananas": 60.00,
"pineapples": 75.00,
"guavas": 50.00,
"guyavanos": 130.00,
"avocados": 120.00
}- Why a dictionary? A dictionary binds each fruit name to its price as a single key-value pair. Lookup is O(1) constant time β instant regardless of how many fruits exist.
-
How it operates: Python stores this as a hash table internally.
fruits["mangoes"]retrieves180.00in O(1) time β no looping required. - Significance: Speed and simplicity. If we used a list instead, we'd have to loop through every item to find a match β an O(n) operation.
πΉ STEP 02 β display_fruits(): Iteration & Formatting
def display_fruits(): print("Available Fruits and Prices (per kg in PHP):") for fruit, price in fruits.items(): print(f"{fruit.capitalize()}: {price:.2f}")
- Why isolate display logic? The display function can be called at the start of every shopping loop without duplicating code.
-
How it operates:
fruits.items()returns each key-value pair as a tuple. Thefor fruit, price in ...line unpacks that tuple into two named variables.{price:.2f}formats the float to exactly 2 decimal places. - Significance: Reusability and separation of concerns. If the display format ever changes, you change it in one place only.
πΉ STEP 03 β while True: Continuous Shopping Loop
while True: display_fruits() choice = input("\nEnter fruit or 'done' to finish: ").lower() if choice == 'done': break if choice not in fruits: print("Invalid selection.") continue
-
Why
while True? The number of items a customer wants is unknown in advance. The program should keep asking until the user explicitly decides to stop. -
How it operates:
while Truecreates an infinite loop. The only exit isbreakwhen the user types "done".continueskips the rest of the loop and returns to the top. -
Significance: User-driven flow control. The
while True+breakpattern hands control to the user β the program ends only when they say so.
πΉ STEP 04 β try/except: Input Validation
try: quantity = float(input(f"Enter quantity in kg for {choice}: ")) if quantity <= 0: raise ValueError except ValueError: print("Invalid quantity. Please enter a positive number.") continue
-
Why
try/except?input()always returns a string. Converting withfloat()crashes the program if the user types anything non-numeric. -
How it operates: Python attempts
float(...). If that fails, Python raisesValueErrorautomatically. Iffloat()succeeds but the result is β€ 0, we manuallyraise ValueError. Either way, theexceptblock catches it, prints an error, andcontinuerestarts the loop. - Significance: Crash prevention. Without this block, a single bad keystroke would terminate the entire program β losing all cart data.
πΉ STEP 05 β Shopping Cart: List of Tuples
cost = fruits[choice] * quantity shopping_cart.append((choice, quantity, cost)) total_cost += cost for item in shopping_cart: print(f"{item[0].capitalize()}: {item[1]} kg = {item[2]:.2f} PHP")
- Why a tuple? Each purchase is a fixed 3-part record. Tuples are immutable β once created, that record cannot be accidentally changed.
-
Why a list? Lists are ordered and dynamic, allowing unlimited items to be appended.
.append()adds the tuple as a new element at the end. - Significance: Data integrity and clarity. Immutable tuples inside a mutable list give the best of both worlds β you can grow the cart freely, but individual purchase records stay protected.
πΉ STEP 06 β Discount System: Dictionary Lookup
codes = {"SALE10": 10, "FRESH15": 15, "FRUIT20": 20}
code = input("Enter your discount code: ").upper()
if code in codes:
discount = codes[code]
print(f"Discount code accepted! {discount}% off applied.")
return discount
else:
print("Invalid discount code. No discount applied.")
return 0.0-
Why a dictionary for discounts? Code validation requires fast, exact key lookups. Using a dictionary instead of a chain of
if/elifstatements means the logic stays the same whether there are 3 codes or 300. -
How it operates:
if code in codesis a safe O(1) check that will never raise aKeyError..upper()makes codes case-insensitive from the user's perspective. - Significance: Scalability and maintainability. Adding a new discount code only requires one new line in the dictionary β no logic changes needed.
πΉ STEP 07 β Discount Calculation: Arithmetic
discount_percent = get_discount() discount_amount = total_cost * (discount_percent / 100) final_total = total_cost - discount_amount print(f"Subtotal: {total_cost:.2f} PHP") if discount_percent > 0: print(f"Discount ({discount_percent}%): -{discount_amount:.2f} PHP") print(f"Total Cost: {final_total:.2f} PHP")
- Why split the calculation? Breaking it into named variables makes the math readable and easy to debug. A customer can see exactly how much was deducted and why.
-
How it operates:
discount_percent / 100converts e.g.15β0.15. Multiplying bytotal_costgives the peso amount to deduct. Subtracting yields the final price. - Significance: Transparency and auditability. This mirrors how real POS (point-of-sale) receipt systems work β showing subtotal, discount, and grand total as separate line items.
πΉ STEP 08 β if __name__ == "__main__": Entry Guard
if __name__ == "__main__": print("Welcome to the Philippine Fruit Retail Business!") calculate_total() print("Thank you for shopping with us!")
-
Why the guard? Without it, the moment another Python file does
import fruit_retail, the program would immediately launch the interactive session β an unintended side effect. -
How it operates: Python sets
__name__to"__main__"when a file is run directly. When imported, it's set to the module name. The guard means the program only runs in the first case. - Significance: Reusability and testability. This single pattern transforms the script into a proper module. It is considered mandatory in professional Python development.
Quick Cheatsheet
Every Python concept featured in this program β mapped directly to the step where it appears.
| Concept | Step | Key Takeaway |
|---|---|---|
dict | 1 | O(1) key-value lookup; more scalable than parallel lists |
.items() | 2 | Iterates key-value pairs simultaneously via tuple unpacking |
| f-strings | 2 | Embed expressions directly in strings with :.2f for currency |
while True + break | 3 | User-driven loop that exits on explicit sentinel input |
continue | 3 | Skips remainder of loop body and restarts from the top |
try / except | 4 | Catches runtime errors and recovers gracefully |
raise ValueError | 4 | Manually triggers an exception for logically invalid values |
| list of tuples | 5 | Mutable container holding immutable fixed-width records |
.append() | 5 | Adds items to the end of a list in O(1) amortized time |
in operator | 6 | Safe O(1) key membership check that prevents KeyError |
| Arithmetic | 7 | Named intermediate variables improve readability and debuggability |
__name__ guard | 8 | Enables import without triggering execution; mandatory best practice |
Go Further With These Ideas
Persist Your Data
Save the shopping cart to a JSON file with json.dump() so records survive program restarts.
Write Unit Tests
Use pytest to test functions in isolation. The __name__ guard makes this possible.
Build a Web Version
Port the logic to Flask or FastAPI β the functions translate almost 1:1 to REST API endpoints.
Add Sales Analytics
Track which fruits sell most with collections.Counter to optimize inventory decisions.
Avoid These Pitfalls
β Mistake 1 β Using a list instead of a dictionary
Storing fruit names and prices in parallel lists and using list.index() to find a price is O(n) and breaks the moment the lists fall out of sync. A dictionary is always the right choice.
β Mistake 2 β Catching bare except:
Writing except: without specifying an exception type will silently swallow every error β including KeyboardInterrupt and memory errors. Always catch the most specific exception type possible.
β Mistake 3 β Forgetting if __name__ == "__main__"
Omitting the entry guard means any test file or other module that imports your functions will immediately trigger the full interactive program. Even for small scripts, always wrap top-level execution code in this guard.
β Mistake 4 β Using input() without stripping whitespace
A user who types a space before their fruit name β " mangoes" instead of "mangoes" β will get an invalid selection error. Always sanitize user input with .strip().lower().
Python Concepts, Deeper
Explore these concepts beyond the basics β a structured learning roadmap.
Dictionary Internals
Python's dict is a hash table. Understanding hash collisions, load factors, and why insertion order is preserved since Python 3.7 will make you a more confident user of this structure.
Exception Hierarchy
ValueError is just one node in Python's exception tree. Learning when to raise TypeError vs a custom exception is essential for writing maintainable code.
Format Specification Mini-Language
The :.2f in f-strings is part of a powerful format specification mini-language. Mastering it eliminates most manual string manipulation in display code.
Named Tuples
Python's collections.namedtuple or typing.NamedTuple lets you access fields by name β item.fruit instead of item[0] β dramatically improving readability in larger codebases.
Subscribe to Poetic Bytes
Level up your Python knowledge.
In-depth Python tutorials, code breakdowns, and programming insights β delivered straight to your inbox. No spam, ever.
π Join 8,400+ developers. Your email is never shared or sold.
Follow Poetic Bytes
Stay connected across every platform. Get daily Python tips, OOP insights, and the latest programming developments β wherever you spend your time online.
Wrapping Up: Your Python Journey
π What You've Accomplished
You've just completed a deep-dive into a real-world Python program that simulates a Philippine fruit retail business.
You now understand how to use dictionaries for O(1) lookups, while True + break for user-driven loops, try/except for crash prevention, lists of tuples for immutable records, and the __name__ guard for modular, testable code.
Every code example was interactive β you ran Python in your browser, experimented with the code, and saw the results instantly.
Key Takeaways
- Dictionaries = Speed β O(1) hash table lookups make price retrieval instant
- while True + break β the standard Python idiom for user-driven indefinite loops
- try/except = Resilience β graceful error handling is the difference between a demo and real software
- List of Tuples β mutable containers of immutable records for data integrity
- __name__ Guard β mandatory best practice that enables imports, testing, and reuse
Your Next Steps
Now that you've mastered these fundamentals, you're ready to build on this foundation:
β¨ "The best way to solidify these concepts is to write code that breaks them and then figure out why. Every bug you fix teaches you something a tutorial never could. Keep coding, keep learning, and remember: great programmers are made, not born."
β Glenn Junsay Pansensoy, Poetic Bytes