Project 1 - Inventory Management Tool
In real systems, inventory management must handle:
- Fast item lookup
- Quantity updates
- Category grouping
- Low-stock detection
- Sales tracking
- Analytics reporting
We will build a scalable system using proper data structures.
System Requirements
Our system must support:
- Add item
- Remove item
- Update stock
- Search item by ID
- Group items by category
- Detect low stock items
- Track sales frequency
- Generate summary report
Data Structure Design
We choose:
dict→ Main inventory store (O(1) lookup)defaultdict(list)→ Category groupingCounter→ Sales frequency trackingset→ Fast ID existence validation
Why?
Because lookup is frequent and must be O(1).
Step 1 - Core Inventory Class
from collections import defaultdict, Counter
class InventorySystem:
def __init__(self):
# Main storage: item_id -> item data
self.inventory = {}
# Category mapping: category -> list of item_ids
self.categories = defaultdict(list)
# Track sales frequency
self.sales_counter = Counter()
# Fast existence check
self.item_ids = set()
def add_item(self, item_id, name, category, quantity):
if item_id in self.item_ids:
raise ValueError("Item ID already exists")
item_data = {
"name": name,
"category": category,
"quantity": quantity
}
self.inventory[item_id] = item_data
self.categories[category].append(item_id)
self.item_ids.add(item_id)
def remove_item(self, item_id):
if item_id not in self.item_ids:
raise ValueError("Item does not exist")
category = self.inventory[item_id]["category"]
del self.inventory[item_id]
self.categories[category].remove(item_id)
self.item_ids.remove(item_id)
def update_stock(self, item_id, quantity):
if item_id not in self.item_ids:
raise ValueError("Item not found")
self.inventory[item_id]["quantity"] = quantity
def sell_item(self, item_id, quantity):
if item_id not in self.item_ids:
raise ValueError("Item not found")
if self.inventory[item_id]["quantity"] < quantity:
raise ValueError("Insufficient stock")
self.inventory[item_id]["quantity"] -= quantity
self.sales_counter[item_id] += quantity
def get_item(self, item_id):
return self.inventory.get(item_id)
def get_items_by_category(self, category):
return [self.inventory[item_id] for item_id in self.categories[category]]
def low_stock_items(self, threshold=5):
return [
item for item in self.inventory.values()
if item["quantity"] <= threshold
]
def top_selling_items(self, n=5):
return self.sales_counter.most_common(n)
Step 2 - Using the System
system = InventorySystem()
system.add_item(1, "Laptop", "Electronics", 10)
system.add_item(2, "Mouse", "Electronics", 50)
system.add_item(3, "Notebook", "Stationery", 100)
system.sell_item(1, 2)
system.sell_item(2, 5)
system.sell_item(1, 1)
print("Item 1:", system.get_item(1))
print("Electronics:", system.get_items_by_category("Electronics"))
print("Low stock:", system.low_stock_items())
print("Top selling:", system.top_selling_items())
Step 3 - Performance Analysis
Critical operations:
| Operation | Complexity |
|---|---|
| Add item | O(1) |
| Remove item | O(1)* |
| Update stock | O(1) |
| Lookup item | O(1) |
| Category grouping | O(k) |
| Low stock scan | O(n) |
* list removal inside category list is O(k)
If categories become large, we may switch to:
defaultdict(set) for faster removal.
Engineering thinking means identifying bottlenecks.
Step 4 - Scaling Simulation
import time
system = InventorySystem()
# Add 1 million items
start = time.time()
for i in range(1_000_000):
system.add_item(i, f"Item{i}", "General", 100)
print("Add time:", time.time() - start)
# Random lookup test
start = time.time()
for i in range(1_000_000):
system.get_item(i)
print("Lookup time:", time.time() - start)
Lookup remains fast due to dictionary usage.
If we had used list → O(n²) disaster.
Step 5 - Engineering Improvement Ideas
- Replace category list with set for faster removal.
- Add persistence layer (file or database).
- Add restock alert system.
- Add batch update feature.
- Add inventory valuation calculation.
- Add multi-warehouse support.
Extension Challenge
Modify system to:
- Track item price
- Compute total inventory value
- Maintain top revenue generating products
- Add undo/rollback mechanism
What You Learned
This project required:
- Dict for O(1) access
- Set for fast membership validation
- Defaultdict for grouping
- Counter for analytics
- Understanding complexity tradeoffs
This is how real systems are designed.
Not by guessing.
But by choosing structures intentionally.
Final Engineering Takeaway
Inventory systems scale with:
- Millions of items
- Thousands of transactions per second
- Continuous updates
Choosing the wrong data structure:
- Slows lookups
- Breaks scalability
- Causes latency spikes
Choosing the right structure:
- Keeps system predictable
- Keeps operations O(1)
- Enables growth
This is data structure engineering in practice.
© 2026 EngineersOfAI. All rights reserved.
