Python for Profit

Building a Complete Inventory System

05

Reusable Code Blocks with Functions

The Big Idea

This chapter introduces functions—the most important tool for organizing code—to create reusable blocks for adding and displaying products, and combines them with a while loop to build the main menu of our command-line application, assembling our script step-by-step.

Roadmap

  • The Problem of "Spaghetti Code": We'll discuss why simply writing code from top to bottom becomes unmanageable as programs grow.

  • The DRY Principle: Introduce the "Don't Repeat Yourself" philosophy, a cornerstone of professional software development.

  • Building main.py Step-by-Step: We will construct our application by adding each piece of code progressively.

1.  Start with a clean slate: An empty inventory list.

2.  Define the `display_inventory` function to show the data.

3.  Define the `add_product` function to add new data.

4.  Create the main application menu using a `while` loop to call our functions.

Full Chapter Content

Avoiding "Spaghetti Code"

So far, our script has run from top to bottom. This works for simple tasks, but as we add more features (like deleting items, updating prices, searching), our main.py file would become a long, confusing tangle of code. This is often called "spaghetti code" because the flow of logic is as hard to follow as a noodle in a bowl of spaghetti.

Professionals avoid this by bundling related lines of code into reusable blocks called functions, following the DRY principle: Don't Repeat Yourself.

Functions give us two major advantages:

  1. Reusability: We write the logic for displaying the inventory once, then "call" it whenever we need a report.

  2. Readability: Instead of a hundred-line script, we have a handful of well-named functions, making the program's purpose immediately clear.

Let's build our application properly, one step at a time.

Step 1: Start with a Clean Slate

First, open your main.py file. We will begin with only our configuration and an empty list for our data. This ensures our program starts fresh every time, reinforcing the need for file storage which we will tackle next.

Your main.py should look like this:

# --- PyInventory: A Step-by-Step Journey to Profit ---
# Chapter 5: Reusable Code Blocks with Functions

# --- Configuration ---
CURRENCY = "MAD"

# --- Data Store ---
# We start with an empty list. Our program will add data to it.
inventory = []

Step 2: Define the "Display Inventory" Function

Now, let's add our first reusable code block. A function is defined using the def keyword. This function, display_inventory, will take the inventory list and currency symbol as input (we call these parameters) and handle all the logic for printing the report.

Add the following code to your main.py file, right below the inventory list:

# --- Function Definitions ---

def display_inventory(inventory_list, currency_symbol):
    """
    Displays the current inventory in a formatted table.
    """
    print("\n--- Current Inventory Report ---")
    print("-" * 50)
    total_inventory_value = 0.0

    if not inventory_list:
        print("Inventory is currently empty.")
    else:
        for item in inventory_list:
            item_name, item_quantity, item_price = item
            item_value = item_quantity * item_price
            total_inventory_value += item_value
            print(f"Product: {item_name}, Quantity: {item_quantity}, Price: {currency_symbol}{item_price:.2f}, Stock Value: {currency_symbol}{item_value:.2f}")

    print("-" * 50)
    print(f"GRAND TOTAL INVENTORY VALUE: {currency_symbol}{total_inventory_value:.2f}")
    print("-" * 50)

Notice the line item_name, item_quantity, item_price = item. This is a Python feature called list unpacking. It's a clean way to assign each element of the item list to its own descriptive variable.

Step 3: Define the "Add Product" Function

Next, we need a function to handle adding a new product. This function will contain the interactive code from Chapter 3. It will also take the inventory_list as a parameter and use the .append() method to add the new product directly to it.

Add this second function to main.py right below the display_inventory function:

def add_product(inventory_list, currency_symbol):
    """
    Interactively asks the user for a new product's details
    and adds it to the inventory list.
    """
    print("\n--- Add a New Product ---")
    product_name = input("Enter the new product name: ")
    quantity_str = input(f"Enter the quantity for {product_name}: ")
    price_str = input(f"Enter the price per item (in {currency_symbol}): ")

    new_product = [product_name, int(quantity_str), float(price_str)]

    inventory_list.append(new_product)
    print(f"\nSUCCESS: '{product_name}' has been added to the inventory.")

Step 4: Create the Main Application Loop

We now have our tools (the functions), but we need a way for the user to choose which one to use. We'll create a main menu that runs continuously using a while True: loop. This loop will show the user their options, get their choice, and then call the appropriate function.

Add this final block of code to the very end of your main.py file:

# --- Main Application Loop ---

while True:
    print("\n--- PyInventory Main Menu ---")
    print("1: Display Current Inventory")
    print("2: Add a New Product")
    print("q: Quit")

    choice = input("Please enter your choice (1, 2, or q): ")

    if choice == '1':
        display_inventory(inventory, CURRENCY)
    elif choice == '2':
        add_product(inventory, CURRENCY)
    elif choice.lower() == 'q':
        print("Exiting PyInventory. Goodbye!")
        break # This exits the while loop
    else:
        print("Invalid choice. Please try again.")

This loop is the control center of our application. It directs the flow of the program based on user input, calling our well-organized functions to do the actual work.

Your complete main.py should now look like the assembled code from all the steps above. Save the file and run it: python main.py. You now have a real, interactive command-line application built in a structured, professional way!

Chapter 5: Summary & What's Next

Congratulations, you have now built the skeleton of a real application.

  • You learned how to organize code into reusable functions with def.

  • You made your functions flexible by passing data to them using parameters.

  • You created a persistent menu system using a while loop.

  • You assembled a complete program step-by-step, starting with an empty data store.

Our program is fully functional, but its memory is still temporary. When you quit the application, any new products you added are lost forever. In the next chapter, we will solve this by learning how to save our inventory data to a file on the computer, giving our program a permanent memory.