The goal of this assignment is to work with object-oriented programming and exceptions in Python.
You will be doing your work in Python for this assignment. You may
choose to work on this assignment on a hosted environment (e.g. tiger) or on your own local
installation of Jupyter and Python. You should use Python 3.9 or higher
for your work. To use tiger, use the credentials you received. If you
work remotely, make sure to download the .py files to turn in. If you
choose to work locally, Anaconda is the easiest way
to install and manage Python. If you work locally, you may launch
Jupyter Lab either from the Navigator application or via the
command-line as jupyter-lab
.
In this assignment, we will be implementing a collection of classes that work together to orchestrate an online market. There will be products, including both grocery and household, the inventory, and a customer’s shopping cart. You will need to test your classes to make sure they work properly.
The assignment is due at 11:59pm on Wednesday, April 20.
You should submit the completed notebook file required for this
assignment on Blackboard. The
filename of the notebook should be a6.ipynb
.
Please make sure to follow instructions to receive full credit. Because you will be writing classes and adding to them, you do not need to separate each part of the assignment. Please document any shortcomings with your code. You may put the code for each part into one or more cells.
The first cell of your notebook should be a markdown cell with a line for your name and a line for your Z-ID. If you wish to add other information (the assignment name, a description of the assignment), you may do so after these two lines.
Create four classes related to the products your online store will sell: StoreItem, HouseholdItem, GroceryItem and BulkItem.
StoreItem is the base class which has a name, SKU and price.
The sku
, which stands for "stock keeping unit", is a unique
identifier for each item.
GroceryItem subclasses from StoreItem and has a nutrition field that defaults to an empty dictionary.
HouseholdItem also is a subclass of StoreItem but has a brand name.
BulkItem subclasses from GroceryItem and adds a unit field (lbs, kg, ml, oz).
Add constructors and method(s) to support printing human-readable strings for these items. Note that the bulk items should display their units with the strings.
Think about which class to put the method(s) in. For example,
= GroceryItem("Cheerios", 38942, 3.99, {'calories': 200, 'fat': 0})
cereal = BulkItem("Bananas", 4011, 0.59, "lb")
bananas print(f"Two items: {cereal}, {bananas}")
prints
"Two items: Cheerios (38942) @ 3.99, Bananas (4011) @ 0.59/lb"
Create an Inventory class that stores both the items the store carries and the amount of each item that the store has in stock.
It
should have add_items
and remove_items
methods
that take a StoreItem object and an amount and adds or removes,
respectively, that to the current inventory.
In addition, add a
find_item
method that takes a SKU and returns the
StoreItem
object with that SKU.
It should also have a method has_enough
that given an
item and amount, returns a boolean that indicates whether the
inventory has more than that that amount.
Finally, add a method that again returns a human-readable string with all the items in the inventory and their amounts.
Create a ShoppingCart class that tracks the items a customer wishes to buy. It should store products and the amount of each item in the cart.
It should have add_items
and
remove_items
methods that take a StoreItem object and an
amount and adds or removes, respectively, that to the current cart.
Also, add a method that returns a human-readable string with all the items in the cart and their amounts.
In addition, add support for
+=
and -=
operators that will add or remove a
single (1) item (or unit) from the cart.
Finally, add a cost method that computes the total cost for all of the items in the cart.
Important: Think about the similarities between classes and whether you can use OOP concepts to minimize your work for this class.
The Store class will keep track of both the inventory and the customers shopping.
To that end, it has a get_cart
method
that returns a new ShoppingCart object and keeps track of it.
Define a
MAX_CARTS
class constant that specifies the ten (10) as the
maximum number of carts in the store, and raise an exception if too many
carts are in use.
In addition, write a checkout
method that
checks the inventory to make sure the number of items being bought in
the shopping cart are available and then deducts the quantities selected
in the shopping cart from the inventory.
If there is not enough left in
the inventory, the checkout method should raise an exception
alerting that about which item(s) are not in stock.
checkout
should return the cost of all the items bought and
remove the cart from the store.
We should add more exceptions to our classes to avoid particular issues. Here is the list of exceptions to raise and the circumstances:
BulkItem
.
Bulk items do allow fractional amounts!find_item
if the SKU doesn’t
existremove_items
if more items are
removed from the inventory than exist.The final list of classes and methods to be added. Note that all classes should have constructors that properly initialize objects, and the instance fields are not listed here.
The following code should help you test your work:
= Store()
store "Cheerios", 38942, 3.99, {'calories': 200, 'fat': 0}), 10)
store.inventory.add_items(GroceryItem("Trash Bags", 38902, 5.99, "Hefty"), 30)
store.inventory.add_items(HouseholdItem("Bananas", 4011, 0.59, "lb"), 20)
store.inventory.add_items(BulkItem("Lettuce", 3982, 2.99, "head"), 25)
store.inventory.add_items(BulkItem("Oreos", 27894, 3.29), 1)
store.inventory.add_items(GroceryItem(
print("Inventory:")
print(store.inventory)
= store.get_cart()
my_cart 4011), 3)
my_cart.add_items(store.inventory.find_item(38902))
my_cart.add_items(store.inventory.find_item(27894), 1)
my_cart.add_items(store.inventory.find_item(print("Cart:")
print(my_cart)
= store.checkout(my_cart)
total_cost print(f"You spent ${total_cost}")
print("Updated Inventory:")
print(store.inventory)
which outputs something similar to:
Inventory:
10 Cheerios (38942) @ 3.99
30 Trash Bags (38902) @ 5.99
20 Bananas (4011) @ 0.59/lb
25 Lettuce (3982) @ 2.99/head
1 Oreos (27894) @ 3.29
Cart:
3 Bananas (4011) @ 0.59/lb
1 Trash Bags (38902) @ 5.99
1 Oreos (27894) @ 3.29
You spent $11.05
Updated Inventory:
10 Cheerios (38942) @ 3.99
29 Trash Bags (38902) @ 5.99
17 Bananas (4011) @ 0.59/lb
25 Lettuce (3982) @ 2.99/head
0 Oreos (27894) @ 3.29
This code should raise an exception (too many carts):
for i in range(20):
store.get_cart()
For CSCI 503 students, the following can be used to test Part 5:
= store.get_cart()
my_cart 4013), 3) # raises your exception
my_cart.add_items(store.inventory.find_item(38902), 1.5) # raises your exception
my_cart.add_items(store.inventory.find_item(27894), 3) # raises your exception store.inventory.remove_items(store.inventory.find_item(