In [ ]:
from __future__ import print_function

Naming conventions

The python community has some naming convections, defined in PEP-8:

https://www.python.org/dev/peps/pep-0008/

The widely adopted ones are:

  • class names start with an uppercase, and use "camelcase" for multiword names, e.g. ShoppingCart

  • varible names (including objects which are instances of a class) are lowercase and use underscores to separate words, e.g., shopping_cart

  • module names should be lowercase with underscores

Modules

This class is useful to other codes, not just this notebook. This is where modules come in -- we can put all of this code into a .py file and then import it to use its functionality. Here, it is called vector2d.py:


In [ ]:
import vector2d

In [ ]:
u = vector2d.Vector(1,2)

In [ ]:
u

This module has a special section, starting with:

if __name__ == "__main__":

This tests whether we are executing the code directly, e.g., as python3 vector2d.py instead of importing it. This allows us to put some tests, demonstrations, etc. directly in the module.

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:


In [ ]:
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)

In [ ]:
INVENTORY

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 two Items that don't have the same name.

Here's a start:


In [ ]:
class Item(object):
    """ an item to buy """
    
    def __init__(self, name, quantity=1):
        if name not in INVENTORY:
            raise ValueError
        self.name = name
        self.quantity = quantity
        
    def __repr__(self):
        pass
        
    def __eq__(self, other):
        pass
    
    def __add__(self, other):
        pass

Here are some tests your code should pass:


In [ ]:
a = Item("apple", 10)
b = Item("banana", 20)

In [ ]:
c = Item("apple", 20)

In [ ]:
# won't work
a + b

In [ ]:
# will work
a += c

In [ ]:
a

In [ ]:
a == b

In [ ]:
a == c

How do they behave in a list?


In [ ]:
items = []
items.append(a)
items.append(b)
items

In [ ]:
c in items

ShoppingCart

Now we want to create a shopping cart. The main thing it will do is hold a list of items.


In [ ]:
class ShoppingCart(object):
    
    def __init__(self):
        self.items = []
        
    def subtotal(self):
        """ return a subtotal of our items """
        pass

    def add(self, name, quantity):
        """ add an item to our cart """
        pass
        
    def remove(self, name):
        """ remove all of item name from the cart """
        pass
        
    def report(self):
        """ print a summary of the cart """
        pass

Here are some tests


In [ ]:
sc = ShoppingCart()
sc.add("orange", 19)

In [ ]:
sc.add("apple", 2)

In [ ]:
sc.report()

In [ ]:
sc.add("apple", 9)

In [ ]:
sc.report()

In [ ]:
sc.subtotal()

In [ ]:
sc.remove("apple")

In [ ]:
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


In [ ]:

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.


In [ ]: