More problem solving

Project 1

We talked about the ideas behind project 1. See the lecture capture for details!

Shopping discount problem

We’re working for an online artisanal vegan fair-trade clothing retailer. We want to write a function that takes in a customer’s shopping cart and returns the pre-shipping, pre-tax total. There are a couple of discounts we want to apply:

  • If the customer is purchasing at least $100 worth of shoes, take 20% off the cost of all shoes in the cart
  • If the customer is purchasing at least two hats, take $10 off the cart’s total

Items in the shopping cart look like this:

from dataclasses import dataclass

@dataclass
class CartItem:
    name: str
    price: int

How would we write a checkout function to compute the total price of a cart? What are the subproblems?

Solution 1

def checkout(cart: list):
  shoes = list(filter(lambda item: item.name == "shoes", cart))
  shoes_cost = sum(map(lambda item: item.cost, shoes))
  shoes_discount = 0
  if shoes_cost > 100:
    shoes_discount = shoes_cost * 0.20

  hats = list(filter(lambda item: item.name == "hat", cart))
  hats_discount = 0
  if len(hats) >= 2:
    hats_discount = 10

  return sum(map(lambda item: item.cost, cart)) - shoes_discount - hats_discount

Solution 2

def checkout(cart: list):
  shoe_total = 0
  hats_seen = 0
  total = 0
  for item in cart:
    if item.name == "shoes":
      shoe_total += item.cost
    if item.name == "hats":
      hats_seen += 1
    total += item.cost
  if shoe_total >= 100:
    total -= shoe_total * 0.20
  if hats_seen >= 2:
    total -= 10
  return total

List comprehensions

Python has a special way of writing combinations of map and filter, called list comprehensions. These look sort of like for-loops, but inside lists. For instance:

> l = ["doug", "alex", "brantley"]
> [x for x in l if not x.startswith("d")]
["alex", "brantley"]
> ["HTA " + x for x in l if not x.startswith("d")]
["HTA alex", "HTA brantley"]

We can also write dictionary comprehensions:

> l = [1, 2, 3, 4]
> {x: x + 1 for x in l}
{1: 2, 2: 3, 3: 4, 4: 5}