HackerRank Python (Basic) certification
Shopping Cart
A small classes question. It checks whether you can store state on an object and make len() work on your own class.
What the question asks
Write two classes:
Item(name, price), wherenameis a string andpriceis an integer. Both must be readable as plain attributes, for exampleitem.name.ShoppingCart(), created with no arguments. It hasadd(item)to put an item in the cart,total()to return the sum of the prices of everything in the cart, and callinglen(cart)must return the number of items in it.
The same item can be added more than once, and every add call counts. There are at most 5 different items and at most 500 operations.
The stub first reads the item list (name and price per line), then runs commands: add <name>, total and len. It writes the result of each total and len on its own line.
Function to write
class Item:
def __init__(self, name, price): ...
class ShoppingCart:
def __init__(self): ...
def add(self, item): ...
def total(self): ...
def __len__(self): ...Solution
class Item:
def __init__(self, name, price):
self.name = name
self.price = price
class ShoppingCart:
def __init__(self):
self.items = []
def add(self, item):
self.items.append(item)
def total(self):
return sum(item.price for item in self.items)
def __len__(self):
return len(self.items)How it works
Itemjust stores its name and price.- Each
ShoppingCartgets its own empty list in__init__.addappends to it, so adding the same item twice puts it in the list twice. total()adds up thepriceof every item in the list. An empty cart returns 0, becausesumof nothing is 0.len(cart)callscart.__len__(). Returning the length of the list gives the item count, duplicates included.
Mistakes that fail the hidden tests
- Lists declared on the class instead of in
__init__. Writingitems = []directly underclass ShoppingCart:creates one list shared by every cart, so a second cart starts with the first cart’s items. The stub happens to build only one cart per test, so this bug can slip through on HackerRank, but it is still wrong and an interviewer will spot it. Create the list inside__init__withself.items = []. - Storing items in a set or a dict keyed by name. That silently ignores the second
addof the same item, so bothlenandtotalcome out too low. - No
__len__. A method calledlenorsizeis not enough.len(cart)raises “object of type ‘ShoppingCart’ has no len()”. - Keeping a running total and forgetting to update it. Computing the sum when
total()is called is simpler and cannot go out of sync.
Try it on sample data
Input in the stub’s format: three items, then seven commands.
3
bike 1000
headphones 100
phone 500
7
len
add bike
add phone
total
add bike
len
total
Output from my run with a copy of the stub’s loop:
0
1500
3
2500
The cart starts empty (0). Bike plus phone is 1500. After the second bike there are 3 items worth 2500.