Skip to Content
Course content

138: Practice Exercise: Building a Simple Inventory System with OOP

Click on the "Edit" button in the top corner of the screen to edit your slide content.

By this point in the course, you know how to define a class and instantiate an object. But there is a big difference between knowing the syntax and knowing why you'd actually choose an object-oriented approach over a simpler one. I see a lot of developers stumble here; they either over-engineer everything into classes or they avoid them entirely, sticking to dictionaries and lists because "it's faster to write."

The "Dictionary Soup" Approach

Let's say we're building a simple inventory system for a small electronics shop. If you were tackling this naively, you'd probably start with a dictionary. It feels intuitive. You have a product name as a key, and another dictionary as the value to hold the quantity and price. It looks something like this:

inventory = {
    "Mechanical Keyboard": {"qty": 15, "price": 120.00},
    "Gaming Mouse": {"qty": 30, "price": 60.00},
    "Ultrawide Monitor": {"qty": 5, "price": 450.00}
}

def update_stock(item_name, amount):
    if item_name in inventory:
        inventory[item_name]["qty"] += amount
    else:
        print("Item not found!")

At first glance, this is lean. But here is where it starts to break. Because you're relying on "stringly typed" keys like "qty" and "price", you're one typo away from a KeyError that crashes your program in production. If I accidentally type inventory[item_name]["quantity"] in one function but "qty" in another, Python won't warn me until the code actually runs and fails. Plus, if you want to add logic—say, a method to calculate the total value of a specific item's stock—you have to write a standalone function and pass the dictionary around everywhere. The data and the logic are living in two different neighborhoods.

Encapsulating Logic with Item and Inventory Classes

The better way is to treat an "Item" as a first-class citizen. By creating an Item class, we define a strict blueprint. We aren't just storing data; we're defining what an item is and what it can do.

class Item:
    def __init__(self, name, qty, price):
        self.name = name
        self.qty = qty
        self.price = price

    def total_value(self):
        return self.qty * self.price

class Inventory:
    def __init__(self):
        self.items = {}

    def add_item(self, item):
        self.items[item.name] = item

    def adjust_stock(self, name, amount):
        if name in self.items:
            self.items[name].qty += amount
        else:
            raise ValueError(f"Item {name} not found in inventory.")

Now, look at the trade-off. Yes, I wrote more lines of code. I had to define two classes instead of one dictionary. But I've gained something massive: predictability. I no longer have to remember if I called the key "qty" or "quantity" because my IDE's autocomplete will tell me exactly what Item attributes exist.

More importantly, the total_value logic now lives inside the Item class. If the way we calculate value changes tomorrow (maybe we add a tax rate or a discount), I only have to change it in one place. The Inventory class doesn't need to know how an item calculates its value; it just knows that the item can do it. This is the core of OOP—delegating responsibility. The Inventory manages the collection, and the Item manages its own data.

When the Complexity Pays Off

You might wonder if this is overkill for a few items. Maybe. But imagine if this system grows. What if some items are "Digital" (no shipping cost) and some are "Physical" (require warehouse space)? With the dictionary approach, you'd be adding if "type" == "digital" checks all over your codebase. With OOP, you just create a DigitalItem subclass that inherits from Item and overrides the specific methods it needs. You've built a foundation that can grow without becoming a tangled mess of nested dictionaries.




📋 Practical Task

Exercise: The Warehouse Stock Auditor

You need to expand the inventory system to handle a "low stock" alert system. Your goal is to build a system that can track items and identify which ones need to be reordered.

Requirements:

  • Create an Item class with name, qty, and reorder_level (the minimum quantity allowed before an alert is triggered).
  • Create an Inventory class that stores these items in a dictionary.
  • Implement a method in Inventory called get_reorder_list() that returns a list of names of all items whose qty is less than or equal to their reorder_level.
  • Implement a method sell_item(name, amount) that reduces the quantity. If the sale would result in a negative quantity, it should raise a ValueError.

Test your code with this scenario:
1. Add a "Laptop" with qty 10 and reorder_level 5.
2. Add a "Mouse" with qty 3 and reorder_level 5.
3. Sell 6 Laptops.
4. Call get_reorder_list() and verify that both "Laptop" and "Mouse" are now on the list.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.