← Computer Programming I

Variant 1: The Banking Transaction Processor

You are processing transfers for a bank. The difficulty lies in calculating dynamic transaction fees based on the account type before ensuring the user has enough money to cover both the transfer amount AND the fee.

Requirements:

  1. Helper Function: process_transfer(accounts_db, user_id, amount)
    • Logic (Strict Order):
      1. User Check: If user_id is not in accounts_db, raise KeyError (“User not found”).
      2. Type Check: If amount is not a number (int or float), raise TypeError (“Invalid amount type”).
      3. Fee Calculation: Check the user’s “type”.
        • If “premium”, fee is 0.
        • If “standard”, fee is 5% of the amount.
        • Note: You must calculate total_cost = amount + fee.
      4. Balance Check: If balance < total_cost, raise ValueError (“Insufficient funds for transfer + fee”).
    • Action: Deduct total_cost from balance.
    • Return: The actual fee charged (float).
  2. Main Function: run_batch(accounts_db, transaction_list)
    • Logic: Iterate through the list of transactions.
    • Error Handling: Catch errors from the helper.
    • Return: A dictionary with two keys: {"success_count": int, "total_fees_collected": float}.

Testing Inputs:

# Format: {ID: {"balance": float, "type": string}}
db = {
    "U1": {"balance": 100.0, "type": "standard"}, # 5% fee
    "U2": {"balance": 200.0, "type": "premium"}   # No fee
}

# Format: [(User, Amount)]
transactions = [
    ("U1", 50.0),    # Valid. Fee=2.5. Total=52.5. Rem=47.5
    ("U2", 500.0),   # Error: Insufficient funds
    ("U3", 10.0),    # Error: User not found
    ("U1", "twenty") # Error: Invalid type
]

Expected Output:

Transaction (U2, 500.0): Insufficient funds for transfer + fee
Transaction (U3, 10.0): 'User not found'
Transaction (U1, twenty): Invalid amount type
{'success_count': 1, 'total_fees_collected': 2.5}

Variant 2: The University Prerequisite Checker

You are enrolling students in courses. The difficulty lies in Cross-Referencing: You must check the Course Database for prerequisites and then check the Student Database to see if they have completed them.

Requirements:

  1. Helper Function: enroll_student(student_db, course_db, student_id, course_code)
    • Logic (Strict Order):
      1. Database Checks: If student_id not in student_db OR course_code not in course_db, raise KeyError (“Record not found”).
      2. Already Enrolled: If course_code is already in the student’s "current_courses" list, raise ValueError (“Already enrolled”).
      3. Prerequisite Check: Look up the "prereq" for the course.
        • If the course has a prereq (not None), check if that prereq exists in the student’s "passed_courses" list.
        • If not, raise ValueError (f”Missing Prereq: {prereq_name}”).
    • Action: Append course_code to the student’s "current_courses".
    • Return: True.
  2. Main Function: process_enrollments(student_db, course_db, request_list)
    • Logic: Iterate through requests.
    • Error Handling: Catch errors.
    • Return: A dictionary: {"successful": [list of student_ids], "failed": [list of student_ids]}.

Testing Inputs:

courses = {
    "CS101": {"prereq": None},
    "CS102": {"prereq": "CS101"}
}

students = {
    "Alice": {"passed_courses": ["CS101"], "current_courses": []},
    "Bob":   {"passed_courses": [],        "current_courses": []}
}

requests = [
    ("Alice", "CS102"), # Valid (Has CS101)
    ("Bob", "CS102"),   # Error: Missing Prereq
    ("Charlie", "CS101"), # Error: User not found
    ("Alice", "CS102")  # Error: Already enrolled (After first step)
]

Expected Output:

Enrollment failed for Bob in CS102: Missing Prereq: CS101
Enrollment failed for Charlie in CS101: 'Record not found'
Enrollment failed for Alice in CS102: Already enrolled
{'successful': ['Alice'], 'failed': ['Bob', 'Charlie', 'Alice']}

Variant 3: The Crafting Recipe System

You are building a crafting system for a game. The difficulty lies in Nested Iteration: To craft ONE item, you must verify that the user has ENOUGH of ALL required ingredients defined in a recipe dictionary.

Requirements:

  1. Helper Function: craft_item(inventory, recipes, item_name)
    • Logic (Strict Order):
      1. Recipe Check: If item_name not in recipes, raise KeyError (“Recipe unknown”).
      2. Ingredient Verification (The Loop): Iterate through the required ingredients for that item.
        • Check if the ingredient exists in inventory AND if inventory[ing] >= required_qty.
        • If any ingredient is missing or insufficient, raise ValueError (“Missing ingredients”).
    • Action: If validation passes, run a second loop to deduct materials from inventory and add the crafted item to inventory.
    • Return: The string "Crafted {item_name}".
  2. Main Function: craft_batch(inventory, recipes, to_craft_list)
    • Logic: Iterate through the list of items to craft.
    • Error Handling: Catch errors.
    • Return: A list of strings containing only the success messages.

Testing Inputs:

# Format: {Item: {Ingredient: Qty, Ingredient: Qty}}
recipes = {
    "Sword": {"Iron": 2, "Wood": 1},
    "Shield": {"Wood": 4}
}

# Current Inventory
inventory = {"Iron": 5, "Wood": 2, "Sword": 0}

queue = [
    "Sword",        # Valid. Consumes 2 Iron, 1 Wood. (Rem: 3 Iron, 1 Wood)
    "Shield",       # Error: Needs 4 Wood, have 1.
    "LaserGun",     # Error: Recipe unknown
    "Sword"         # Valid: Needs 1 Wood, have 1. Needs 2 Iron, have 3.
]

Expected Output:

Missing ingredients
Recipe unknown
['Crafted Sword', 'Crafted Sword']

Variant 4: The Hotel Reservation System

You are building the booking engine for a hotel chain. You must calculate the total cost of a stay—including a fixed cleaning fee—before checking if the guest has sufficient funds.

Requirements:

  1. Helper Function: book_stay(guests_db, room_catalog, guest_id, room_type, nights)
    • Logic (Strict Order):
      1. Guest Check: If guest_id is not in guests_db, raise KeyError (“Guest ID not found”).
      2. Room Check: If room_type is not in room_catalog, raise KeyError (“Invalid room type”).
      3. Input Validation: If nights is not an integer or is less than 1, raise ValueError (“Nights must be positive integer”).
      4. Cost Calculation: Calculate total: (nights * room_price) + cleaning_fee.
        • Note: room_price and cleaning_fee come from room_catalog.
      5. Balance Check: If guest’s balance < total_cost, raise ValueError (“Insufficient funds”).
    • Action: Deduct total_cost from guest’s balance.
    • Return: The total_cost (float).
  2. Main Function: process_bookings(guests_db, room_catalog, booking_list)
    • Logic: Iterate through the booking_list.
    • Error Handling: Catch exceptions. Print "Booking Error for [Guest]: [Message]".
    • Return: A dictionary: {'total_revenue': float, 'failed_bookings': int}.

Testing Inputs:

# Format: {Type: {"price": float, "cleaning_fee": float}}
rooms = {
    "Standard": {"price": 100.0, "cleaning_fee": 20.0},
    "Suite":    {"price": 200.0, "cleaning_fee": 50.0}
}

# Format: {GuestID: {"balance": float}}
guests = {
    "G1": {"balance": 300.0},
    "G2": {"balance": 50.0}
}

bookings = [
    ("G1", "Standard", 2),    # Valid. Cost: 200+20=220. Rem: 80.
    ("G2", "Suite", 1),       # Error: Cost 250 > Bal 50.
    ("G3", "Standard", 1),    # Error: Guest ID not found.
    ("G1", "Penthouse", 1),   # Error: Invalid room type.
    ("G1", "Standard", 0)     # Error: Nights must be positive.
]

Expected Output:

Booking Error for G2: Insufficient funds
Booking Error for G3: 'Guest ID not found'
Booking Error for G1: 'Invalid room type'
Booking Error for G1: Nights must be positive integer
{'total_revenue': 220.0, 'failed_bookings': 4}

Variant 5: The Car Rental Fleet

You are managing a car rental service. You must calculate the total rental price—adding a “Young Driver Surcharge” if applicable—before authorizing the rental against the driver’s credit limit.

Requirements:

  1. Helper Function: rent_vehicle(drivers_db, fleet_catalog, driver_id, model, days)
    • Logic (Strict Order):
      1. Driver Check: If driver_id is not in drivers_db, raise KeyError (“Driver not found”).
      2. Model Check: If model is not in fleet_catalog, raise KeyError (“Vehicle model unavailable”).
      3. Input Validation: If days is not an integer or is less than 1, raise ValueError (“Days must be positive integer”).
      4. Cost Calculation: Calculate total: days * daily_rate.
        • Condition: If the driver’s age < 25, add a fixed surcharge (found in fleet_catalog) to the total.
      5. Credit Check: If driver’s credit < total_cost, raise ValueError (“Credit limit exceeded”).
    • Action: Deduct total_cost from driver’s credit.
    • Return: The total_cost (float).
  2. Main Function: process_rentals(drivers_db, fleet_catalog, rental_list)
    • Logic: Iterate through the rental_list.
    • Error Handling: Catch exceptions. Print "Rental Error for [Driver]: [Message]".
    • Return: A dictionary: {'total_profit': float, 'rejected_requests': int}.

Testing Inputs:

# Format: {Model: {"rate": float, "surcharge": float}}
fleet = {
    "Sedan": {"rate": 50.0, "surcharge": 25.0},
    "SUV":   {"rate": 80.0, "surcharge": 40.0}
}

# Format: {DriverID: {"credit": float, "age": int}}
drivers = {
    "D1": {"credit": 200.0, "age": 30}, # No surcharge
    "D2": {"credit": 100.0, "age": 20}  # Pays surcharge
}

rentals = [
    ("D1", "Sedan", 3),    # Valid. Cost: 150. Rem: 50.
    ("D2", "Sedan", 2),    # Error: Cost (50*2)+25 = 125 > 100.
    ("D1", "Truck", 1),    # Error: Vehicle model unavailable.
    ("D1", "Sedan", -1),   # Error: Days must be positive.
    ("D9", "SUV", 1)       # Error: Driver not found.
]

Expected Output:

Rental Error for D2: Credit limit exceeded
Rental Error for D1: 'Vehicle model unavailable'
Rental Error for D1: Days must be positive integer
Rental Error for D9: 'Driver not found'
{'total_profit': 150.0, 'rejected_requests': 4}

Variant 6: The Cloud Server Provisioner

You are writing a script for a cloud computing provider. You must calculate the monthly contract value—applying a bulk discount if the contract is long enough—before checking the client’s budget.

Requirements:

  1. Helper Function: provision_server(clients_db, server_tiers, client_name, tier, months)
    • Logic (Strict Order):
      1. Client Check: If client_name is not in clients_db, raise KeyError (“Client unknown”).
      2. Tier Check: If tier is not in server_tiers, raise KeyError (“Tier does not exist”).
      3. Input Validation: If months is not an integer or is less than 1, raise ValueError (“Contract length invalid”).
      4. Cost Calculation: Calculate total: months * monthly_cost.
        • Condition: If months >= 12, subtract a fixed discount_amount (found in server_tiers) from the total.
      5. Budget Check: If client’s budget < total_cost, raise ValueError (“Budget exceeded”).
    • Action: Deduct total_cost from client’s budget.
    • Return: The total_cost (float).
  2. Main Function: run_provisioning(clients_db, server_tiers, request_list)
    • Logic: Iterate through the request_list.
    • Error Handling: Catch exceptions. Print "Provisioning Failed: [Message]".
    • Return: A dictionary: {'contract_value': float, 'errors_logged': int}.

Testing Inputs:

# Format: {Tier: {"cost": float, "discount": float}}
tiers = {
    "Basic": {"cost": 10.0, "discount": 10.0}, # Discount applies if 12+ months
    "Pro":   {"cost": 50.0, "discount": 50.0}
}

# Format: {ClientName: {"budget": float}}
clients = {
    "StartupCo": {"budget": 200.0},
    "MegaCorp":  {"budget": 1000.0}
}

requests = [
    ("StartupCo", "Basic", 12),  # Valid. Cost: (12*10)-10 = 110. Rem: 90.
    ("StartupCo", "Pro", 5),     # Error: Cost 250 > 90.
    ("MegaCorp", "Ultra", 1),    # Error: Tier does not exist.
    ("GhostLLC", "Basic", 1),    # Error: Client unknown.
    ("MegaCorp", "Pro", 0.5)     # Error: Contract length invalid (type/value).
]

Expected Output:

Provisioning Failed: Budget exceeded
Provisioning Failed: 'Tier does not exist'
Provisioning Failed: 'Client unknown'
Provisioning Failed: Contract length invalid
{'contract_value': 110.0, 'errors_logged': 4}

Variant 7: The Food Delivery App

You are writing the backend for a food delivery service. You must calculate the total order cost—applying a discount if the customer has a “Gold” membership status—before validating their wallet balance.

Requirements:

  1. Helper Function: place_order(customers_db, menu_catalog, customer_id, item_name, quantity)
    • Logic (Strict Order):
      1. Customer Check: If customer_id is not in customers_db, raise KeyError (“Customer not found”).
      2. Item Check: If item_name is not in menu_catalog, raise KeyError (“Item not on menu”).
      3. Input Validation: If quantity is not an integer or is less than 1, raise ValueError (“Quantity must be positive integer”).
      4. Cost Calculation: Calculate total: quantity * item_price.
        • Condition: Check the customer’s "status". If it equals "Gold", apply a 10% discount to the total (multiply cost by 0.9).
      5. Balance Check: If customer’s "wallet" < total_cost, raise ValueError (“Insufficient balance”).
    • Action: Deduct total_cost from customer’s wallet.
    • Return: The total_cost (float).
  2. Main Function: run_delivery_batch(customers_db, menu_catalog, order_list)
    • Logic: Iterate through order_list.
    • Error Handling: Catch exceptions. Print "Order Failed for [Customer]: [Message]".
    • Return: A dictionary: {'total_sales': float, 'failed_orders': int}.

Testing Inputs:

# Format: {Item: {"price": float}}
menu = {
    "Burger": {"price": 10.0},
    "Pizza":  {"price": 15.0}
}

# Format: {ID: {"wallet": float, "status": str}}
customers = {
    "C1": {"wallet": 20.0, "status": "Regular"},
    "C2": {"wallet": 50.0, "status": "Gold"}    # Gets 10% off
}

orders = [
    ("C1", "Burger", 2),    # Valid. Cost: 20.0. Rem: 0.
    ("C2", "Pizza", 4),     # Valid. Cost: (60 * 0.9) = 54. Error: Insufficient balance (50 < 54).
    ("C3", "Salad", 1),     # Error: Customer not found.
    ("C1", "Soda", 1),      # Error: Item not on menu.
    ("C1", "Burger", 0)     # Error: Quantity must be positive integer.
]

Expected Output:

Order Failed for C2: Insufficient balance
Order Failed for C3: 'Customer not found'
Order Failed for C1: 'Item not on menu'
Order Failed for C1: Quantity must be positive integer
{'total_sales': 20.0, 'failed_orders': 4}

Variant 8: The RPG Spell Casting System

You are coding the combat logic for a Role-Playing Game (RPG). You must calculate the Mana cost of a spell—reducing it if the player’s class matches the spell’s affinity—before deducting Mana points.

Requirements:

  1. Helper Function: cast_spell(players_db, spellbook, player_name, spell_name, power_level)
    • Logic (Strict Order):
      1. Player Check: If player_name is not in players_db, raise KeyError (“Player not found”).
      2. Spell Check: If spell_name is not in spellbook, raise KeyError (“Unknown spell”).
      3. Input Validation: If power_level is not an integer or is less than 1, raise ValueError (“Power level must be positive integer”).
      4. Mana Cost Calculation: Calculate total mana: power_level * base_cost.
        • Condition: Check if player’s "class" matches the spell’s "type". If they match, divide the cost by 2.
      5. Mana Check: If player’s "mana" < total_cost, raise ValueError (“Not enough mana”).
    • Action: Deduct total_cost from player’s mana.
    • Return: The total_cost (float or int).
  2. Main Function: process_combat_turn(players_db, spellbook, action_list)
    • Logic: Iterate through action_list.
    • Error Handling: Catch exceptions. Print "Cast Failed for [Player]: [Message]".
    • Return: A dictionary: {'total_mana_consumed': float, 'fizzled_spells': int}.

Testing Inputs:

# Format: {Spell: {"base_cost": int, "type": str}}
spells = {
    "Fireball": {"base_cost": 10, "type": "Mage"},
    "Heal":     {"base_cost": 5,  "type": "Cleric"}
}

# Format: {Name: {"mana": float, "class": str}}
players = {
    "Gandalf": {"mana": 50.0, "class": "Mage"},  # Half cost for Mage spells
    "Aragorn": {"mana": 20.0, "class": "Warrior"} # Full cost
}

actions = [
    ("Gandalf", "Fireball", 4), # Valid. Cost: (4*10)/2 = 20. Rem: 30.
    ("Aragorn", "Heal", 5),     # Error: Cost 25 > 20. (Full cost because Warrior != Cleric)
    ("Legolas", "Arrow", 1),    # Error: Player not found.
    ("Gandalf", "IceBeam", 1),  # Error: Unknown spell.
    ("Gandalf", "Fireball", -1) # Error: Power level must be positive integer.
]

Expected Output:

Cast Failed for Aragorn: Not enough mana
Cast Failed for Legolas: 'Player not found'
Cast Failed for Gandalf: 'Unknown spell'
Cast Failed for Gandalf: Power level must be positive integer
{'total_mana_consumed': 20.0, 'fizzled_spells': 4}

Variant 9: The Gym Class Booking System

You are building a booking system for a fitness center. You must calculate the credits required to book spots—waiving the fee if the member has a “Premium” pass—before checking their credit balance.

Requirements:

  1. Helper Function: book_session(members_db, schedule_db, member_id, class_name, spots)
    • Logic (Strict Order):
      1. Member Check: If member_id is not in members_db, raise KeyError (“Member ID not found”).
      2. Class Check: If class_name is not in schedule_db, raise KeyError (“Class not found”).
      3. Input Validation: If spots is not an integer or is less than 1, raise ValueError (“Spots must be positive integer”).
      4. Cost Calculation: Calculate total credits: spots * cost_per_spot.
        • Condition: Check the member’s "pass_type". If it equals "Premium", the total cost is 0.
      5. Credit Check: If member’s "credits" < total_cost, raise ValueError (“Insufficient credits”).
    • Action: Deduct total_cost from member’s credits.
    • Return: The total_cost (int).
  2. Main Function: process_gym_bookings(members_db, schedule_db, booking_queue)
    • Logic: Iterate through booking_queue.
    • Error Handling: Catch exceptions. Print "Booking Error for [Member]: [Message]".
    • Return: A dictionary: {'credits_used': int, 'declined_bookings': int}.

Testing Inputs:

# Format: {Class: {"cost": int}}
schedule = {
    "Yoga":   {"cost": 5},
    "Boxing": {"cost": 10}
}

# Format: {ID: {"credits": int, "pass_type": str}}
members = {
    "M1": {"credits": 20, "pass_type": "Standard"},
    "M2": {"credits": 5,  "pass_type": "Premium"} # Free classes
}

queue = [
    ("M1", "Yoga", 2),      # Valid. Cost: 10. Rem: 10.
    ("M2", "Boxing", 10),   # Valid. Cost: 0 (Premium). Rem: 5.
    ("M1", "Boxing", 2),    # Error: Cost 20 > 10.
    ("M9", "Zumba", 1),     # Error: Member ID not found.
    ("M1", "Pilates", 1),   # Error: Class not found.
    ("M2", "Yoga", 0)       # Error: Spots must be positive integer.
]

Expected Output:

Booking Error for M1: Insufficient credits
Booking Error for M9: 'Member ID not found'
Booking Error for M1: 'Class not found'
Booking Error for M2: Spots must be positive integer
{'credits_used': 10, 'declined_bookings': 4}

Variant 10: The University Printing Quota System

You are writing the print-job manager for a campus lab. You must calculate the credits required to print a document—waiving the cost completely if the user is “Staff”—before checking their quota balance.

Requirements:

  1. Helper Function: print_document(users_db, printer_config, user_id, printer_type, pages)
    • Logic (Strict Order):
      1. User Check: If user_id is not in users_db, raise KeyError (“User unknown”).
      2. Printer Check: If printer_type is not in printer_config, raise KeyError (“Invalid printer type”).
      3. Input Validation: If pages is not an integer or is less than 1, raise ValueError (“Page count must be positive integer”).
      4. Cost Calculation: Calculate total credits: pages * cost_per_page.
        • Condition: Check the user’s "role". If it equals "Staff", the total cost is 0.0.
      5. Quota Check: If user’s "quota" < total_cost, raise ValueError (“Insufficient quota”).
    • Action: Deduct total_cost from user’s quota.
    • Return: The total_cost (float).
  2. Main Function: process_print_queue(users_db, printer_config, job_list)
    • Logic: Iterate through the job_list.
    • Error Handling: Catch exceptions. Print "Print Error for [User]: [Message]".
    • Return: A dictionary: {'total_credits_burned': float, 'failed_jobs': int}.

Testing Inputs:

# Format: {Type: {"cost": float}}
printers = {
    "BW":    {"cost": 0.10},
    "Color": {"cost": 0.50}
}

# Format: {ID: {"quota": float, "role": str}}
users = {
    "U1": {"quota": 2.00, "role": "Student"},
    "U2": {"quota": 5.00, "role": "Staff"}    # Prints for free
}

jobs = [
    ("U1", "BW", 10),      # Valid. Cost: 1.00. Rem: 1.00.
    ("U2", "Color", 20),   # Valid. Cost: 0.00 (Staff). Rem: 5.00.
    ("U1", "Color", 10),   # Error: Cost 5.00 > 1.00.
    ("U9", "BW", 1),       # Error: User unknown.
    ("U1", "3D", 1),       # Error: Invalid printer type.
    ("U1", "BW", 0)        # Error: Page count must be positive integer.
]

Expected Output:

Print Error for U1: Insufficient quota
Print Error for U9: 'User unknown'
Print Error for U1: 'Invalid printer type'
Print Error for U1: Page count must be positive integer
{'total_credits_burned': 1.0, 'failed_jobs': 4}

Variant 11: The EV Charging Network

You are managing an Electric Vehicle (EV) charging network. You must calculate the charging cost—applying a discount if the driver is a “Subscriber”—before authorizing the session against their wallet.

Requirements:

  1. Helper Function: start_charging(drivers_db, stations_db, driver_id, station_id, kwh_amount)
    • Logic (Strict Order):
      1. Driver Check: If driver_id is not in drivers_db, raise KeyError (“Driver not found”).
      2. Station Check: If station_id is not in stations_db, raise KeyError (“Station offline”).
      3. Input Validation: If kwh_amount is not a number (int or float) or is <= 0, raise ValueError (“Invalid kWh amount”).
      4. Cost Calculation: Calculate total: kwh_amount * price_per_kwh.
        • Condition: Check driver’s "plan". If it equals "Subscriber", apply a 25% discount (multiply cost by 0.75).
      5. Wallet Check: If driver’s "wallet" < total_cost, raise ValueError (“Insufficient funds”).
    • Action: Deduct total_cost from driver’s wallet.
    • Return: The total_cost (float).
  2. Main Function: batch_charge_requests(drivers_db, stations_db, request_list)
    • Logic: Iterate through the request_list.
    • Error Handling: Catch exceptions. Print "Charge Error for [Driver]: [Message]".
    • Return: A dictionary: {'revenue': float, 'denied_sessions': int}.

Testing Inputs:

# Format: {StationID: {"price": float}}
stations = {
    "S_Fast": {"price": 0.50},
    "S_Slow": {"price": 0.20}
}

# Format: {DriverID: {"wallet": float, "plan": str}}
drivers = {
    "D1": {"wallet": 10.0, "plan": "Guest"},
    "D2": {"wallet": 10.0, "plan": "Subscriber"} # 25% off
}

requests = [
    ("D1", "S_Slow", 20),      # Valid. Cost: 4.0. Rem: 6.0.
    ("D2", "S_Fast", 20),      # Valid. Cost: (10.0 * 0.75) = 7.5. Rem: 2.5.
    ("D1", "S_Fast", 50),      # Error: Cost 25.0 > 6.0.
    ("D1", "S_Hyper", 10),     # Error: Station offline.
    ("D9", "S_Slow", 10),      # Error: Driver not found.
    ("D1", "S_Slow", -5)       # Error: Invalid kWh amount.
]

Expected Output:

Charge Error for D1: Insufficient funds
Charge Error for D1: 'Station offline'
Charge Error for D9: 'Driver not found'
Charge Error for D1: Invalid kWh amount
{'revenue': 11.5, 'denied_sessions': 4}

Variant 12: The Arcade Prize Counter

You are coding the redemption system for an arcade prize counter. You must calculate the ticket cost of items—giving a “bulk discount” of 100 tickets off if the user buys 3 or more of the same item—before checking their ticket balance.

Requirements:

  1. Helper Function: redeem_prize(players_db, prize_catalog, player_id, item_name, quantity)
    • Logic (Strict Order):
      1. Player Check: If player_id is not in players_db, raise KeyError (“Player not found”).
      2. Prize Check: If item_name is not in prize_catalog, raise KeyError (“Prize not available”).
      3. Input Validation: If quantity is not an integer or is less than 1, raise ValueError (“Quantity must be positive integer”).
      4. Cost Calculation: Calculate total: quantity * ticket_cost.
        • Condition: If quantity >= 3, subtract 100 from the total cost. (Ensure cost doesn’t go below 0).
      5. Balance Check: If player’s "tickets" < total_cost, raise ValueError (“Not enough tickets”).
    • Action: Deduct total_cost from player’s tickets.
    • Return: The total_cost (int).
  2. Main Function: process_redemptions(players_db, prize_catalog, queue)
    • Logic: Iterate through the queue.
    • Error Handling: Catch exceptions. Print "Redemption Error for [Player]: [Message]".
    • Return: A dictionary: {'tickets_spent': int, 'failed_redemptions': int}.

Testing Inputs:

# Format: {Item: {"cost": int}}
prizes = {
    "Bear": {"cost": 500},
    "Candy": {"cost": 50}
}

# Format: {PlayerID: {"tickets": int}}
players = {
    "P1": {"tickets": 1000},
    "P2": {"tickets": 100}
}

queue = [
    ("P1", "Candy", 4),     # Valid. Cost: (200 - 100) = 100. Rem: 900.
    ("P2", "Bear", 1),      # Error: Cost 500 > 100.
    ("P9", "Toy", 1),       # Error: Player not found.
    ("P1", "PS5", 1),       # Error: Prize not available.
    ("P1", "Bear", 0)       # Error: Quantity must be positive integer.
]

Expected Output:

Redemption Error for P2: Not enough tickets
Redemption Error for P9: 'Player not found'
Redemption Error for P1: 'Prize not available'
Redemption Error for P1: Quantity must be positive integer
{'tickets_spent': 100, 'failed_redemptions': 4}


This is a simplified alternative to the standard Week 11 assignments. If you choose to submit one of these options instead of the standard assignment, the maximum grade you can achieve is 70%.

Variant A: The E-Commerce Order Fulfillment System

You are writing the backend for an online store. You need to process a customer’s shopping cart against the warehouse inventory.

Requirements:

  1. Helper Function: validate_and_sell(inventory, item_name, quantity)
    • Logic (Check strictly in this order):
      1. Type Check: Check if quantity is strictly an integer. If not, raise a TypeError with message “Quantity must be an integer”.
      2. Value Check: Check if quantity is greater than 0. If not, raise a ValueError with message “Quantity must be positive”.
      3. Existence Check: Check if item_name exists in inventory. If not, raise a KeyError with message “Item not found”.
      4. Stock Check: Check if the inventory count is sufficient (>= quantity). If not, raise a ValueError with message “Insufficient stock”.
    • Action: If all checks pass, subtract quantity from the inventory count.
    • Return: Return True.
  2. Main Function: process_cart(inventory, cart_list)
    • Logic: Iterate through the cart_list (a list of tuples: (item_name, qty)).
    • Error Handling: Use a try/except block to call validate_and_sell.
      • Catch KeyError, ValueError, and TypeError.
      • Print: "Skipping [Item]: [Error Message]"
    • Success: If successful, print "Shipped [Qty] x [Item]".

Testing Inputs:

warehouse = {"Laptop": 5, "Mouse": 10, "Monitor": 2}
cart = [
    ("Laptop", 2),       # Valid
    ("Monitor", "two"),  # Error: TypeError (String)
    ("Mouse", -5),       # Error: ValueError (Negative)
    ("Keyboard", 1),     # Error: KeyError (Not found)
    ("Monitor", 20)      # Error: ValueError (Stock)
]

Expected Output:

Shipped 2 x Laptop
Skipping Monitor: Quantity must be an integer
Skipping Mouse: Quantity must be positive
Skipping Keyboard: 'Item not found'
Skipping Monitor: Insufficient stock

Variant B: The Library Book Loan System

You are building a digital kiosk for a library. Users request to borrow books, but strict age verification and data validation are required.

Requirements:

  1. Helper Function: borrow_book(catalog, book_title, user_age)
    • Logic (Check strictly in this order):
      1. Type Check: Check if user_age is strictly an integer. If not, raise a TypeError with message “Age must be an integer”.
      2. Existence Check: Check if book_title exists in catalog. If not, raise a KeyError with message “Title not in catalog”.
      3. Restriction Check: If the book is “restricted” (flag is True) AND user_age is less than 18, raise a ValueError with message “Age restricted content”.
      4. Availability Check: Check if the book’s copies count is greater than 0. If not, raise a ValueError with message “No copies available”.
    • Action: If all checks pass, decrement the copies count by 1.
    • Return: Return True.
  2. Main Function: process_requests(catalog, request_list)
    • Logic: Iterate through request_list (list of tuples: (title, age)).
    • Error Handling: Use try/except to call borrow_book.
      • Catch the errors and print: "Loan Denied for [Title]: [Error Message]"
    • Success: Print "Loan Approved: [Title]"

Testing Inputs:

# Format: {Title: {copies: int, restricted: bool}}
library = {
    "Python 101": {"copies": 2, "restricted": False},
    "Horror Story": {"copies": 1, "restricted": True}
}

requests = [
    ("Python 101", 15),     # Valid
    ("Horror Story", "12"), # Error: TypeError (String)
    ("Unknown Book", 25),   # Error: KeyError
    ("Horror Story", 12),   # Error: ValueError (Age)
    ("Horror Story", 20),   # Valid (Takes last copy)
    ("Horror Story", 25)    # Error: ValueError (Copies)
]

Expected Output:

Loan Approved: Python 101
Loan Denied for Horror Story: Age must be an integer
Loan Denied for Unknown Book: 'Title not in catalog'
Loan Denied for Horror Story: Age restricted content
Loan Approved: Horror Story
Loan Denied for Horror Story: No copies available

Variant C: The Event Ticketing Service

You are coding a ticket reservation system. You must validate the section requested and ensure the number of tickets requested is a valid number before checking availability.

Requirements:

  1. Helper Function: reserve_seat(venue, section_name, num_tickets)
    • Logic (Check strictly in this order):
      1. Type Check: Check if num_tickets is strictly an integer. If not, raise a TypeError with message “Input must be an integer”.
      2. Value Check: Check if num_tickets is between 1 and 4 (inclusive). If not, raise a ValueError with message “Ticket limit is 1-4”.
      3. Existence Check: Check if section_name exists in venue. If not, raise a KeyError with message “Invalid section”.
      4. Capacity Check: Check if the section has enough capacity remaining. If not, raise a ValueError with message “Sold out”.
    • Action: If valid, subtract num_tickets from the section’s capacity.
    • Return: Return the total cost (price * num_tickets).
  2. Main Function: process_ticket_queue(venue, queue_list)
    • Logic: Iterate through queue_list (tuples: (section, quantity)).
    • Error Handling: Use try/except to call reserve_seat.
      • Catch errors and print: "Reservation Failed: [Error Message]"
    • Success: Print "Confirmed: [Qty] seats in [Section]. Cost: $[Total]"

Testing Inputs:

# Format: {Section: {capacity: int, price: float}}
stadium = {
    "VIP": {"capacity": 5, "price": 100.0},
    "General": {"capacity": 100, "price": 50.0}
}

queue = [
    ("VIP", 2),         # Valid
    ("VIP", 2.5),       # Error: TypeError (Float)
    ("General", 10),    # Error: ValueError (Limit)
    ("Balcony", 2),     # Error: KeyError
    ("VIP", 4)          # Error: ValueError (Sold out - only 3 left)
]

Expected Output:

Confirmed: 2 seats in VIP. Cost: $200.0
Reservation Failed: Input must be an integer
Reservation Failed: Ticket limit is 1-4
Reservation Failed: 'Invalid section'
Reservation Failed: Sold out