Python for Profit

Building a Complete Inventory System

04

Managing Collections of Data with Lists

The Big Idea

This chapter introduces Python's most fundamental collection type, the list, to store multiple inventory items, and the for loop to process each item in the collection, finally solving our program's "goldfish memory" problem.

Roadmap

  • Beyond a Single Item: We'll discuss why tracking inventory requires handling collections of data, not just individual variables.

  • Introducing Lists: Learn to create a list, a powerful, ordered container for storing multiple pieces of data.

  • The Problem of Related Data: We'll see how storing related data (like product names and prices) in separate lists is clumsy and error-prone.

  • A Better Way: Lists of Lists: Organize our inventory data into a nested structure where each inner list represents a single, complete product.

  • Processing Collections with for Loops: Master the for loop, the essential tool for iterating over every item in a list and performing an action.

  • Accessing Nested Data: Learn how to use multiple index positions ([ ]) to access specific data points within our list of lists.

  • Evolving main.py: We'll upgrade our script to use a list to store a pre-defined inventory and a for loop to generate a complete stock report.

Full Chapter Content

The Need for a Shopping Cart

Imagine a real inventory. It doesn't have just one product; it has dozens, hundreds, or even thousands. Our current program can only handle one item at a time. As soon as it finishes, the data is gone. We need a way to hold a collection of items in memory all at once.

Think of it like shopping. You don't carry each item you want to buy in your hands separately. You put them all into a shopping cart. In Python, one of the most common "shopping carts" for data is called a list.

Your First List

A list is an ordered, changeable collection of items. You create a list using square brackets [], with individual items separated by commas.

Let's create a list of product names.

product_names = ["Laptop", "Mouse", "Keyboard", "Monitor"]

We now have a single variable, product_names, that holds four separate string values. You can access any item in the list using its index—its position in the list. Crucially, indexing in Python starts at 0.

  • product_names[0] would give you "Laptop".

  • product_names[1] would give you "Mouse".

  • And so on.

You can add new items to the end of a list using the .append() method:

product_names.append("Webcam")
# The list is now ["Laptop", "Mouse", "Keyboard", "Monitor", "Webcam"]

The Challenge of Keeping Data Together

We could create separate lists for names, quantities, and prices:

product_names = ["Laptop", "Mouse", "Keyboard"]
quantities = [10, 50, 25]
prices = [1200.00, 25.00, 75.50]

To get the details for the keyboard, we'd have to access product_names[2], quantities[2], and prices[2]. This is clumsy and dangerous. What if we add a new product but forget to add its price to the prices list? All of our data would become misaligned, and our program would produce incorrect results. This is a common source of bugs for beginners.

A Professional Solution: Lists of Lists

A much better, more professional approach is to group all the data for a single product together. We can create a list where each item is another list containing the details for one product.

# Each inner list represents a product: [Name, Quantity, Price]
inventory = [
    ["Laptop", 10, 1200.00],
    ["Mouse", 50, 25.00],
    ["Keyboard", 25, 75.50]
]

This structure is robust. All the information for a single product is bundled together. To access the data for the "Mouse," we first access the second item in the main inventory list (inventory[1]), which gives us the list ["Mouse", 50, 25.00]. From there, we can get the price by accessing the third item of that list ([2]). We can chain the indexes together: inventory[1][2] gives us 25.00.

Doing Work with for Loops

Now that we have our collection, how do we process every item in it without writing the same code over and over? We use a loop. The most common type of loop is the for loop, which is designed to iterate over a sequence (like a list).

The syntax is clean and readable:

# For each 'product' in the 'inventory' list...
for product in inventory:
    # ...do something with that 'product'.
    print(product)

In the code above, product is a temporary variable. In the first pass of the loop, product will be ["Laptop", 10, 1200.00]. In the second pass, it will be ["Mouse", 50, 25.00], and so on, until every item in the inventory list has been processed.

Evolving main.py for Batch Reporting

Let's replace our interactive script with one that uses a pre-defined list of inventory data and a for loop to generate a complete stock report. This is a foundational step towards our CLI tool, which will eventually read this data from a file.

Open main.py and replace the code with this:

# --- PyInventory: A Step-by-Step Journey to Profit ---
# Chapter 4: Managing Collections with Lists

# --- Configuration ---
currency = "MAD"

# --- Data Store ---
# Using a list of lists to store our inventory.
# Each inner list represents a single product: [Name, Quantity, Price]
inventory = [
    ["High-Performance Laptop", 15, 1499.99],
    ["Wireless Ergonomic Mouse", 75, 49.50],
    ["Mechanical Gaming Keyboard", 40, 129.95],
    ["4K Ultra-Wide Monitor", 20, 799.00]
]

# --- Main Application Logic ---
print("--- Current Inventory Report ---")
print("-" * 30) # A separator line for cleaner output

total_inventory_value = 0.0

# The 'for' loop iterates through each product list in our main inventory list.
for product in inventory:
    # Access items from the inner list using their index
    product_name = product[0]
    product_quantity = product[1]
    product_price = product[2]

    # Calculate the value for the current product
    item_total_value = product_quantity * product_price

    # Add the current item's value to the grand total
    total_inventory_value += item_total_value

    # Display the details for the current product
    print(f"Product: {product_name}")
    print(f"Quantity: {product_quantity}")
    print(f"Price: {currency}{product_price}")
    print(f"Stock Value: {currency}{item_total_value:.2f}") # Format to 2 decimal places
    print("-" * 30)

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

In the code above, we've introduced two new things. First, total_inventory_value += item_total_value is a convenient shorthand for total_inventory_value = total_inventory_value + item_total_value. Second, the :.2f inside the f-String is special formatting that tells Python to display the number as a float with exactly two decimal places, which is perfect for currency.

Save and run python main.py. You'll now see a complete, professional-looking report for all the items in your inventory.

Chapter 4: Summary & What's Next

You've fundamentally upgraded our application's capabilities.

  • You learned how to store collections of data using Python lists.

  • You organized your data professionally into a list of lists to keep related information together.

  • You mastered the for loop to process every item in a collection automatically.

Our data is still hard-coded, but now it's in a structure that's ready to be loaded from an external source. In the next chapter, we'll learn how to organize our code into reusable blocks called functions, a crucial step in building larger, more complex applications without creating a mess.