S3Q1 · Shopping List¶
⚡ Quick Reference
Function: process_grocery_list(grocery_list: list, request: str)
def process_grocery_list(grocery_list: list, request: str):
if request == "total_bill_amount":
return sum(item["price"] * item["quantity"] for item in grocery_list)
if request == "max_quantity_item":
return max(grocery_list, key=lambda item: item["quantity"])["name"]
if request == "sort_by_total_amount":
return sorted(grocery_list,
key=lambda item: (-item["price"] * item["quantity"],
item["name"]))
Key rules:
- total_bill_amount → sum of price × quantity for all items
- max_quantity_item → name of item with highest quantity; ties → first occurrence
- sort_by_total_amount → descending by price × quantity; ties → ascending by name
Problem Statement¶
Problem
Write a function process_grocery_list(grocery_list, request) that handles three operations on a list of {name, quantity, price} dictionaries.
Sample data:
grocery_list = [
{"name": "apple", "quantity": 2, "price": 3},
{"name": "banana", "quantity": 5, "price": 2},
{"name": "carrot", "quantity": 4, "price": 1},
]
Expected outputs:
process_grocery_list(grocery_list, "total_bill_amount")
# → 20 (2×3 + 5×2 + 4×1 = 6 + 10 + 4)
process_grocery_list(grocery_list, "max_quantity_item")
# → "banana" (quantity 5 is the highest)
process_grocery_list(grocery_list, "sort_by_total_amount")
# → [banana(10), apple(6), carrot(4)]
Operation 1 - total_bill_amount¶
Sum price × quantity across all items:
From sample: (3×2) + (2×5) + (1×4) = 6 + 10 + 4 = 20 ✓
Operation 2 - max_quantity_item¶
Find the item with the highest quantity and return its name. Ties → first occurrence.
max() scans left to right and only updates on strictly greater - ties naturally return the first occurrence. From sample: banana(5) > carrot(4) > apple(2) → "banana" ✓
Operation 3 - sort_by_total_amount¶
Sort by total amount descending, name ascending on ties:
The tuple key (-total, name):
- -total → negated so sorted() (ascending) gives descending total order
- name → alphabetical tiebreaker
From sample: banana(10) > apple(6) > carrot(4) → [banana, apple, carrot] ✓
Complete solution approaches¶
def process_grocery_list(grocery_list: list, request: str):
if request == "total_bill_amount":
return sum(item["price"] * item["quantity"] for item in grocery_list)
if request == "max_quantity_item":
return max(grocery_list, key=lambda item: item["quantity"])["name"]
if request == "sort_by_total_amount":
return sorted(grocery_list,
key=lambda item: (-item["price"] * item["quantity"],
item["name"]))
def process_grocery_list(grocery_list: list, request: str):
if request == "total_bill_amount":
total = 0
for item in grocery_list:
total += item["price"] * item["quantity"]
return total
if request == "max_quantity_item":
max_item = grocery_list[0]
for item in grocery_list[1:]:
if item["quantity"] > max_item["quantity"]:
max_item = item
return max_item["name"]
if request == "sort_by_total_amount":
def sort_key(item):
total = item["price"] * item["quantity"]
return (-total, item["name"])
return sorted(grocery_list, key=sort_key)
def process_grocery_list(grocery_list: list, request: str):
total = lambda item: item["price"] * item["quantity"]
ops = {
"total_bill_amount": lambda gl: sum(total(i) for i in gl),
"max_quantity_item": lambda gl: max(gl, key=lambda i: i["quantity"])["name"],
"sort_by_total_amount": lambda gl: sorted(gl, key=lambda i: (-total(i), i["name"])),
}
return ops[request](grocery_list)
Each operation is stored as a lambda - ops[request] selects the right one and calls it. Clean and extensible if more operations are added later.
Key takeaways¶
Negate total for descending sort
sorted() always sorts ascending. Using -total as the first element of the key tuple flips the order - the item with the highest total gets the smallest key and sorts first.
Tuple key for multi-criteria sorting
key=lambda i: (-total, name) sorts by two criteria in one pass. Python compares tuples lexicographically - the first element breaks most ties; the second handles the rest.
max() first-occurrence tie-breaking
max() scans left to right and only replaces the current best on strictly greater values. For tied quantities, the item that appeared first in the list is returned - no extra logic needed.