Practicing Classes#
Exercise 1 (shopping cart)#
Let’s write a simple shopping cart class – this will hold items that you intend to purchase as well as the amount, etc. And allow you to add / remove items, get a subtotal, etc.
We’ll use two classes: Item
will be a single item and ShoppingCart
will be the collection of items you wish to purchase.
First, our store needs an inventory – here’s what we have for sale:
INVENTORY_TEXT = """
apple, 0.60
banana, 0.20
grapefruit, 0.75
grapes, 1.99
kiwi, 0.50
lemon, 0.20
lime, 0.25
mango, 1.50
papaya, 2.95
pineapple, 3.50
blueberries, 1.99
blackberries, 2.50
peach, 0.50
plum, 0.33
clementine, 0.25
cantaloupe, 3.25
pear, 1.25
quince, 0.45
orange, 0.60
"""
# this will be a global -- convention is all caps
INVENTORY = {}
for line in INVENTORY_TEXT.splitlines():
if line.strip() == "":
continue
item, price = line.split(",")
INVENTORY[item] = float(price)
INVENTORY
{'apple': 0.6,
'banana': 0.2,
'grapefruit': 0.75,
'grapes': 1.99,
'kiwi': 0.5,
'lemon': 0.2,
'lime': 0.25,
'mango': 1.5,
'papaya': 2.95,
'pineapple': 3.5,
'blueberries': 1.99,
'blackberries': 2.5,
'peach': 0.5,
'plum': 0.33,
'clementine': 0.25,
'cantaloupe': 3.25,
'pear': 1.25,
'quince': 0.45,
'orange': 0.6}
Item
#
Here’s the start of an item class – we want it to hold the name and quantity.
You should have the following features:
the name should be something in our inventory
Our shopping cart will include a list of all the items we want to buy, so we want to be able to check for duplicates. Implement the equal test,
==
, using__eq__
we’ll want to consolidate dupes, so implement the
+
operator, using__add__
so we can add items together in our shopping cart. Note, add should raise a ValueError if you try to add twoItems
that don’t have the same name.
Here’s a start:
class Item:
""" an item to buy """
def __init__(self, name, quantity=1):
"""keep track of an item that is in our inventory"""
if name not in INVENTORY:
raise ValueError("invalid item name")
self.name = name
self.quantity = quantity
def __repr__(self):
return f"{self.name}: {self.quantity}"
def __eq__(self, other):
"""check if the items have the same name"""
return self.name == other.name
def __add__(self, other):
"""add two items together if they are the same type"""
if self.name == other.name:
return Item(self.name, self.quantity + other.quantity)
else:
raise ValueError("names don't match")
Here are some tests your code should pass:
a = Item("apple", 10)
b = Item("banana", 20)
c = Item("apple", 20)
# won't work
a + b
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[6], line 2
1 # won't work
----> 2 a + b
Cell In[3], line 23, in Item.__add__(self, other)
21 return Item(self.name, self.quantity + other.quantity)
22 else:
---> 23 raise ValueError("names don't match")
ValueError: names don't match
# will work
a += c
print(a)
apple: 30
d = Item("dog")
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[8], line 1
----> 1 d = Item("dog")
Cell In[3], line 7, in Item.__init__(self, name, quantity)
5 """keep track of an item that is in our inventory"""
6 if name not in INVENTORY:
----> 7 raise ValueError("invalid item name")
8 self.name = name
9 self.quantity = quantity
ValueError: invalid item name
# should be False
a == b
False
# should be True -- they have the same name
a == c
True
How do they behave in a list?
items = []
items.append(a)
items.append(b)
items
[apple: 30, banana: 20]
# should be True -- they have the same name
c in items
True
ShoppingCart
#
Now we want to create a shopping cart. The main thing it will do is hold a list of items.
class ShoppingCart:
def __init__(self):
# the list of items we control
self.items = []
def subtotal(self):
""" return a subtotal of our items """
pass
def add(self, name, quantity):
""" add an item to our cart -- the an item of the same name already
exists, then increment the quantity. Otherwise, add a new item
to the cart with the desired quantity."""
pass
def remove(self, name):
""" remove all of item name from the cart """
pass
def report(self):
""" print a summary of the cart """
for item in self.items:
print(f"{item.name} : {item.quantity}")
Here are some tests
sc = ShoppingCart()
sc.add("orange", 19)
sc.add("apple", 2)
sc.report()
sc.add("apple", 9)
# apple should only be listed once in the report, with a quantity of 11
sc.report()
sc.subtotal()
sc.remove("apple")
# apple should no longer be listed
sc.report()
Exercise 2: Poker Odds#
Use the deck of cards class from the notebook we worked through outside of class to write a Monte Carlo code that plays a lot of hands of straight poker (like 100,000). Count how many of these hands has a particular poker hand (like 3-of-a-kind). The ratio of # of hands with 3-of-a-kind to total hands is an approximation to the odds of getting a 3-of-a-kind in poker.
You’ll want to copy-paste those classes into a .py
file to allow you to import and reuse them here
Exercise 3: Tic-Tac-Toe#
Revisit the tic-tac-toe game you developed in the functions exercises but now write it as a class with methods to do each of the main steps.