Python Menu-Driven Applications

๐Ÿ Python 3.12+ ๐ŸŸข Chapter 19 of 65 ๐Ÿ“‚ Phase 4: Functions & Reusable Code ๐Ÿ“… 2026 Edition
๐Ÿ“Œ Covered in this chapter: CLI Menu Loops ยท Function Dispatch Tables ยท State Management ยท Banking System Project ยท Capstone Architecture
Master building professional menu-driven CLI applications: interactive while loops, dictionary-based function dispatchers, input validation, and building a full student management & banking application.
1Menu-Driven Architecture & The Control Loop

A Menu-Driven Application is an interactive console program that presents the user with a numbered list of choices, processes their input, executes the corresponding modular function, and loops back until the user explicitly chooses to exit.

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ 1. Display Interactive Menu Options โ”‚ โ”‚ 2. Read User Choice & Validate Input โ”‚ โ”‚ 3. Dispatch Associated Worker Function (CRUD Task) โ”‚ โ”‚ 4. Loop back to Menu (until Exit selected) โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
๐Ÿ’ป Example 1: Interactive Menu Loop Blueprint
# Simple Menu Loop Blueprint:
def show_menu():
    print("\n--- ๐Ÿ“ฑ Quick Actions Menu ---")
    print("1. View Profile")
    print("2. Update Settings")
    print("3. Exit")

def app_controller():
    # Simulated choices for demo run:
    simulated_inputs = ["1", "2", "3"]
    
    for choice in simulated_inputs:
        show_menu()
        print("Selected Choice:", choice)
        
        if choice == "1":
            print("๐Ÿ‘‰ Action: Displaying User Profile...")
        elif choice == "2":
            print("๐Ÿ‘‰ Action: Updating User Settings...")
        elif choice == "3":
            print("๐Ÿ‘‹ Exiting program. Goodbye!")
            break

app_controller()
๐Ÿ” Control Flow:

The loop continuously prompts the user until the exit condition breaks the control loop.

2Dictionary Function Dispatch Tables (Replacing if-elif Ladders)

As CLI applications grow, giant if-elif-elif-else ladders become messy and hard to maintain. Professional Python developers use Dictionary Function Dispatch Tables to route commands in fast $O(1)$ constant time:

๐Ÿ’ป Example 2: Dictionary Function Dispatch Tables
# Modular worker functions:
def handle_view(): return "๐Ÿ“‹ Showing all database records..."
def handle_create(): return "โž• Creating new database record..."
def handle_delete(): return "๐Ÿ—‘๏ธ Deleting specified record..."
def handle_exit(): return "๐Ÿ‘‹ Application closed."

# Function Dispatch Table:
COMMANDS_DISPATCH = {
    "1": handle_view,
    "2": handle_create,
    "3": handle_delete,
    "4": handle_exit
}

def execute_command(user_choice):
    action = COMMANDS_DISPATCH.get(user_choice)
    if action:
        return action() # Dynamically invoke the mapped function!
    return "โŒ Invalid selection! Please enter a valid number."

# Test command dispatch:
for choice in ["1", "2", "3", "99", "4"]:
    print(f"Command '{choice}' -> {execute_command(choice)}")
๐Ÿ” Clean Code Insight:

Adding a new feature is as easy as writing a new function and registering it in COMMANDS_DISPATCH with zero changes to the core execution loop!

3Capstone Project: Comprehensive Student Management & Banking System

A complete, production-ready menu-driven application featuring account creation, balance inquiry, deposits, withdrawals, and transaction logging:

๐Ÿ’ป Example 3: Comprehensive Banking Management System Project
# =========================================================================
# CAPSTONE PROJECT: MODULAR BANKING & ACCOUNT MANAGEMENT APPLICATION
# =========================================================================

accounts_database = {
    "ACC101": {"holder": "Balaji", "balance": 5000.0, "history": []},
    "ACC102": {"holder": "Alex", "balance": 2500.0, "history": []}
}

def check_balance(acc_id):
    acc = accounts_database.get(acc_id)
    if not acc: return f"โŒ Account {acc_id} not found."
    return f"๐Ÿ’ณ Account: {acc['holder']} | Balance: Rs.{acc['balance']:.2f}"

def deposit_funds(acc_id, amount):
    acc = accounts_database.get(acc_id)
    if not acc: return f"โŒ Account {acc_id} not found."
    if amount <= 0: return "โŒ Deposit amount must be positive!"
    
    acc["balance"] += amount
    acc["history"].append(f"Deposited +Rs.{amount:.2f}")
    return f"โœ… Deposited Rs.{amount:.2f} successfully! New Balance: Rs.{acc['balance']:.2f}"

def withdraw_funds(acc_id, amount):
    acc = accounts_database.get(acc_id)
    if not acc: return f"โŒ Account {acc_id} not found."
    if amount > acc["balance"]:
        return f"โŒ Insufficient funds! Current Balance: Rs.{acc['balance']:.2f}"
        
    acc["balance"] -= amount
    acc["history"].append(f"Withdrawn -Rs.{amount:.2f}")
    return f"โœ… Withdrew Rs.{amount:.2f} successfully! Remaining: Rs.{acc['balance']:.2f}"

# Execute banking simulation:
print("--- ๐Ÿฆ Online Banking Simulation ---")
print(check_balance("ACC101"))
print(deposit_funds("ACC101", 1500.0))
print(withdraw_funds("ACC101", 2000.0))
print(withdraw_funds("ACC101", 10000.0)) # Insufficient funds test
print("\nFinal State ACC101:", accounts_database["ACC101"])
๐Ÿ” Software Engineering Principles:
  • Single Responsibility: Each function does one job (deposit, withdraw, balance check).
  • Defensive Validation: Verifies account existence, prevents negative deposits, and guards against overdrafts.
โš ๏ธ Common Developer Pitfall: Missing Parentheses When Calling Dispatched Functions

In a dispatch dictionary, store the function name without parentheses (e.g. {"1": my_func}). If you write {"1": my_func()}, the function executes immediately at dictionary creation time rather than when selected!

๐Ÿ’ป Hands-on Interactive Practice Challenge

Build a menu-driven mini inventory app with options to: 1. View Inventory, 2. Add Stock, 3. Sell Stock.

Python 3 Practice Challenge โ–ถ Run in Compiler
inventory = {"Laptops": 10, "Mice": 25, "Keyboards": 15}

def add_stock(item, qty):
    inventory[item] = inventory.get(item, 0) + qty
    return f"Added {qty} {item}. Current Stock: {inventory[item]}"

def sell_stock(item, qty):
    if inventory.get(item, 0) < qty:
        return f"Insufficient stock for {item}!"
    inventory[item] -= qty
    return f"Sold {qty} {item}. Remaining: {inventory[item]}"

print("Initial Inventory:", inventory)
print(add_stock("Laptops", 5))
print(sell_stock("Mice", 10))
print("Updated Inventory:", inventory)
Run This Challenge in Online Python IDE โ†’
โ“ Frequently Asked Questions (FAQ)

Q What is a function dispatch table in Python?

A dispatch table is a dictionary mapping user command keys to function reference objects. When a command is selected, Python looks up and executes the mapped function in O(1) time.

Q How do I handle invalid user inputs in a CLI menu gracefully?

Use try-except blocks when converting strings to numbers (e.g. try: choice = int(input()) except ValueError:) and dictionary .get(key) with a default error message.

Q How can I persist data between program executions in a menu app?

Use the built-in json module (json.dump() and json.load()) or the sqlite3 module to save the data dictionary to disk so it reloads automatically on launch.

OC
Written by Our Compiler Technical Editorial Team
Reviewed for accuracy & tested on Python 3.12+ runtime ยท Last updated August 2026