Python class bug - python

My remove and new quantity methods dont work and I have no idea why. Here is my code:
# Type code for classes here
class ItemToPurchase():
def __init__(self):
self.item_description = 'none'
self.item_name = 'none'
self.item_price= 0
self.item_quantity = 0
def print_item_description(self):
print(f'{self.item_name}: {self.item_description}')
class ShoppingCart():
def __init__(self, customer_name='none', current_date='January 1, 2016'):
self.customer_name = customer_name
self.current_date = current_date
self.items = []
def add_item(self, item ):
''' Adds an item to cart_items list. Has parameter of type ItemToPurchase. Does not return anything. '''
self.items.append(item)
def remove_item(self, item ):
''' Removes item from cart_items list. Has a string (an item's name) parameter. Does not return anything.
If item name cannot be found, output this message: Item not found in cart. Nothing removed. '''
delete = False
for item in self.items:
if self.items == item:
to_be_deleted = self.items[item]
delete = True
else:
print("Item not found in cart. Nothing removed.")
if delete == True:
del self.items[to_be_deleted]
def modify_item(self, item, new_quantity):
'''Modifies an item's quantity. Has a parameter of type ItemToPurchase. Does not return anything.
If item can be found (by name) in cart, modify item in cart.'''
if item in self.items:
item.quantity = new_quantity
else:
print("Item not found in cart. Nothing modified.")
def get_num_items_in_cart(self):
'''Returns quantity of all items in cart. Has no parameters.'''
num_items = 0
for item in self.items:
num_items += item.item_quantity
#return the num_Items
return num_items
def get_cost_of_cart(self):
'''Determines and returns the total cost of items in cart. Has no parameters.'''
return sum(item.item_price * item.item_quantity for item in self.items)
def print_total(self):
'''Outputs total of objets in cart.
If cart is empty, outputs this message: CART IS EMPTY.'''
print(f"{self.customer_name}'s Shopping Cart - {self.current_date}")
number_items = self.get_num_items_in_cart()
print(f'Number of Items: {number_items}\n')
total_cost = self.get_cost_of_cart()
if total_cost == 0:
print("SHOPPING CART IS EMPTY\n")
print(f'Total: ${total_cost}')
return False
else:
for item in self.items:
item_cost = item.item_quantity * item.item_price
print(f'{item.item_name} {item.item_quantity} # ${item.item_price} = ${item_cost}')
print()
total_cost = self.get_cost_of_cart()
print(f'Total: ${total_cost}')
def print_descriptions(self):
''' Outputs each item's description'''
print(f"{self.customer_name}'s Shopping Cart - {self.current_date}\n")
for item in self.items:
print("Item Descriptions")
print(f'{item.item.name}: {item.item_description}')
def print_menu():
print("MENU\na - Add item to cart\nr - Remove item from cart\nc - Change item quantity\ni - Output items' descriptions\no - Output shopping cart\nq - Quit\n")
def execute_menu(choice , shopping_cart):
if choice == "o":
print("OUTPUT SHOPPING CART")
shopping_cart.print_total()
elif choice == "i":
print("OUTPUT ITEMS' CART")
shopping_cart.print_descriptions()
elif choice == "a":
print("ADD ITEM TO CART\nEnter the item name:")
item_name = input()
print("Enter the item description:")
item_description = input()
print("Enter the item price:")
item_price = int(input())
print("Enter the item quantity:")
item_quantity = int(input())
New_item = ItemToPurchase()
New_item.item_name = item_name
New_item.item_price = item_price
New_item.item_quantity = item_quantity
New_item.item_description = item_description
shopping_cart.add_item(New_item)
elif choice =="r":
print("REMOVE ITEM FROM CART\nEnter name of item to remove:")
removed_item = input()
shopping_cart.remove_item(removed_item)
elif choice == "i":
'''Implement Change item quantity menu option in execute_menu(). Hint: Make new ItemToPurchase object before using ModifyItem() method. '''
print("CHANGE ITEM QUANTITY\nEnter the item name:")
Item = ItemToPurchase()
Item.item_name = input()
print("Enter the new quantity:")
Item.item_quantity = input()
if __name__ == "__main__":
shopping_cart = ShoppingCart()
print("Enter customer's name:")
shopping_cart.customer_name = input()
print("Enter today's date:")
shopping_cart.current_date = input()
print()
print(f"Customer name: {shopping_cart.customer_name}\nToday's date: {shopping_cart.current_date}")
print()
print_menu()
print("Choose an option:")
while True:
choice = input()
if choice in "arcioq":
if choice == 'q':
break
else:
execute_menu(choice, shopping_cart)
print()
print_menu()
print("Choose an option:")
I think with remove I'm comparing wrong data types and i cant seem to make it work. By the way, the function names cannot change and i cannot add any new functions. I can only use doc strings of preexisting methods and classes and functions

You're not using del correctly. I think you've confused del with the .remove() method of a list.
del self.items[to_be_deleted] makes no sense. self.items is a list, and list indexes must be integers. But to_be_deleted is not an integer; it is an actual item in the list.
If you want to use del, you need the integer index of the list item to be removed.
But since you have the actual object itself, you can call self.items.remove() instead, which takes the actual object as an argument.

Related

Why can a class be called from within another class?

Hi I'm not sure if I've used the right terminology, but I've been assigned a homework for OOP in Python. We have to make a basket system that users can add items to etc... I've completed the homework but I can't figure out why something that I did worked.
I have two classes, Basket() and Shop(). But in the checkout function in Basket, I've used Shop.getPrice(Shop, x). For the life of me I can't figure out why this works.
Also please ignore the sheer number of comments, I had to explain my code to someone.
Thank you in advance
class Shop():
def __init__(self):
self.items = {"eggs":1.95, "bread":0.5, "cheese":2.45}
def addItem(self, item, price):
item = item.lower() #? lower case
self.items[item] = price #? add item to dictionary with price
def deleteItem(self, item):
if item in self.items:
self.items.pop(item) #? remove item from dictionary
else:
print("Item not found") #? item not found
def getPrice(self, item):
return self.items[item] #? returns the price of item
#! DONT LOOK AT THIS FUNCTION
def changePrice(self, item, newPrice):
if newPrice > 0:
self.items.update({item:newPrice})
else:
print("Price must be greater than 0")
def getInput(self):
choice = int(input("""
1. Display Basket
2. Select Item
3. Checkout
4. Exit
Please enter your choice: """))
return choice #? return the input
def main(self):
running = True
basket = Basket() #? instantiate basket
while running:
choice = shop.getInput() #? get input from user
if choice == 1:
basket.showBasket() #? show basket
elif choice == 2:
#! Select Item
found = False #? sets up loop
while not(found): #? loop until item is found
choice = input("Enter the name of the item: ")
choice.lower()
if choice in shop.items: #? checks if item is in shop
basket.addToBasket(choice) #? add item to basket
found = True #? exit loop
else:
print("Item not found, please try again")
elif choice == 3:
#! Checkout
basket.checkout() #? run checkout function
elif choice == 4:
#! Exit
running = False #? exit loop
else:
print("Invalid choice")
shop = Shop()
class Basket():
def __init__(self):
self.contents = {} #? basket is empty to begin with
def addToBasket(self, item):
if item in self.contents: #? if item is in basket, add 1 to quantity
self.contents[item] += 1
else: #? if item is not in basket, add item to basket
self.contents[item] = 1
def removeFromBasket(self, item):
if item in self.contents:
if self.contents[item] > 1: #? if item is more than 1, remove 1
self.contents[item] -= 1
else: #? else remove item
self.contents.pop(item)
else:
print("Item not found")
def checkout(self):
total = 0
for x in self.contents:
total += self.contents[x] * Shop.getPrice(Shop, x)
print("Total: " + str(total))
def showBasket(self):
for x in self.contents:
print(self.contents[x])
shop.main()
Your function Shop.getPrice(Shop, x), worked because you have the classes in the same file, and Shop() class it's in the scope of Basket() class

while loop exiting instead of looping when criteria not met

i'm writing a function as part of a larger overall class project, and i'm having multiple issues with this looping statement, could any of you tell me how it's not looping even though its not meeting the exit criteria? i get what i need up until the loop, i'm trying to get it to ask you to select an item to add, print out the print statement, then start over and if you select the same item twice, add it to the cart
print("**********ITEMS**********")
print("1................Shirts - $10")
print("2.................Pants - $20")
print("3.................Shoes - $40")
print("4.................Dress - $50")
print("Complete Purchase")
cart = []
items = 0
def addItems():
items = int(input("please add an item to your cart: "))
while items > 0:
if items == 1:
print("Shirts,{}x,${}".format(+1, +10))
cart.count("Shirt")
cart.append("Shirt")
print(cart)
return cart
elif items == 2:
print("Pants,{}x,${}".format(+1, +20))
#cart.count("Pants")
cart.append("Pants")
return cart
elif items == 3:
print("Shoes,{}x,${}".format(+1, +40))
#cart.append("Shoes")
cart.count("Shoes")
return cart
elif items == 4:
print("Dress,{}x,${}".format(+1, +50))
#cart.append("Dress")
cart.count("Dress")
return cart
elif items > 5:
break
#return cart
# print(cart.count("Shirt") * 10 + cart.count("Pants") * 20 + cart.count("Shoes") * 40 + cart.count("Dress") * 50)
addItems()
this is my output below
please add an item to your cart: 1
Shirts,1x,$10
['Shirt']
Process finished with exit code 0
You should remove 'return cart' from your if-elif ladder and add it to outside of the while loop. Also you could take input from the user in while loop in addition to the previous one, at the end of the while loop.
def addItems():
items = int(input("please add an item to your cart: "))
while items > 0:
if items == 1:
print("Shirts,{}x,${}".format(+1, +10))
cart.count("Shirt")
cart.append("Shirt")
print(cart)
elif items == 2:
print("Pants,{}x,${}".format(+1, +20))
#cart.count("Pants")
cart.append("Pants")
elif items == 3:
print("Shoes,{}x,${}".format(+1, +40))
#cart.append("Shoes")
cart.count("Shoes")
elif items == 4:
print("Dress,{}x,${}".format(+1, +50))
#cart.append("Dress")
cart.count("Dress")
elif items > 5:
break
items = int(input("please add an item to your cart: "))
return cart

Python elif statements are changing type from float to list

First time posting so apologizes if formatting is incorrect. My program has 2 lists for now. I I will be adding 4 more after solving this initial issue. One for and item the user selects, and a second with prices for the each item. I have written a code for user selection which runs.
My issue comes with the code for the program associating the item selected with the price list. My first if statement registers item_price as a float, which I gives me what I need. Item_price in the following elif statements are being seen as a list. How can I change them to a float so that the price prints instead of the list?
food=["burger", "pizza", "hotdogs", "tacos"]
food_price=[8.99, 22.50, 3.50, 6.00]
def get_menu_item(item,item_list,):
phrase = "Would you like" + item + "? [y/n] "
response = input(phrase)
if response == "y":
print("Here are your menu options:", item_list)
idx = input("please enter the item you would like from our menu[1,2,3,4]: ")
idx = int(idx) -1
return item_list[idx]
#if user selects [n]
else:
return (None)
#item price function
def get_item_price(item_price,item,item_list):
if item == item_list[0]:
item_price = item_price[0]
elif item == item_list[1]:
item_price == item_price[1]
elif item == item_list[2]:
item_price == item_price[2]
elif item == item_list[3]:
item_price == item_price[3]
return item_price
entree_choice = get_menu_item(" dinner",food)
print('You have selected: ' + entree_choice + ".")
entree_price = get_item_price(food_price,entree_choice,food)
print(entree_price)
I answered this for myself shortly after. I was using == instead of = for all of my elif statements. I feel dumb but writing this out helped me solve it.
You could simplify things further by using a dictionary to store your data :
food_price = {"burger":8.99, "pizza":22.50, "hotdogs":3.50, "tacos":6.00}
def get_menu_item(item,item_list,):
phrase = "Would you like" + item + "? [y/n] "
response = input(phrase)
if response == "y":
print("Here are your menu options:", item_list)
idx = input("please enter the item you would like from our menu[1,2,3,4]: ")
idx = int(idx) -1
return item_list[idx]
else:
return (None)
entree_choice = get_menu_item(" dinner",food)
print('You have selected: ' + entree_choice + ".")
# if entree_choice is not found in the food_price dictionary, the output becomes the string "Entree choice not available."
entree_price = food_price.get(entree_choice, "Entree choice not available.")
print(entree_price)

Problems reading and calculating items in list

I'm trying to use menus to accepts menu options that append an empty list that acts as a cart. When the list is done with i have the option to add more lists if necessary. In the end im supposed to calculate the total number of carts, total number of items, and the total price. The first issue is the calcuation of carts is wrong as it treats every new entry as list rather than na item, which elads to the item count being wrong as well for each cart. Along with this, i get "TypeError: unsupported operand type(s) for +: 'int' and 'str'" when trying calculating the final price and im just not sure what to do
def main():
#Flag for full checking out or not
checkout = False
#Flag to start a new cart or not
new_cart = True
#Placeholder list
cart = []
#List of items
book_list = [['My Own Words', 18.00], ['Grant', 24.50], ['The Overstory', 18.95], ['Becoming', 18.99]]
elec_list = [['HP Laptop', 429.50], ['Eyephone', 790.00], ['Bose Speakers', 220.00]]
cloth_list = [['T-shirt', 9.50], ['Shoes', 45.00], ['Pants', 24.00], ['Nationals Hat', 32.00]]
groc_list = [['Coho Salmon', 12.50], ['Spaghetti', 2.75], ['Milk', 3.99], ['Eggs', 1.99], ['Flat Tire Ale', 9.95]]
while checkout == False or new_cart == True:
#Main Menu
if checkout == False:
#Main Item menu
print("""
1 - Books
2 - Electronics
3 - Clothes
4 - Groceries
c - Continue to checkout
""")
choice = input("Select one of the categories or checkout(1-4 or 'c'): ")
#Variable to return user to past menu
Return = False
if choice == '1':
while Return == False:
#Sub item menu
print("""
1 - "My Own Words", $18.00
2 - "Grant", $24.50
3 - "The Overstory", $18.95
4 - "Becoming", $18.99
x - return to menu
""")
item = input("Please select from the menu or go back to the categories: ")
if item == '1' or item == '2' or item =='3' or item == '4':
#Adds item onto the the cart
cart.append(book_list[int(item)-1])
elif item == 'x':
#Returns user to main menu
Return = True
else: print("Invalid input try again")
elif choice == '2':
while Return == False:
#Sub item menu
print("""
1 - HP Laptop, $429.50
2 - EyePhone 10, $790.00
3 - Bose 20 Speakers, $220.00
x - return to menu
""")
item = input("Please select from the menu or go back to the categories: ")
if item == '1' or item == '2' or item == '3':
#Adds item onto the the cart
cart.append(elec_list[int(item)-1])
elif item == 'x':
Return = True
else:
print("Invalid input try again")
elif choice == '3':
while Return == False:
#Sub item menu
print("""
1 - T-shirt, $9.50
2 - Shoes, $45.00
3 - Pants, $24.00
4 - Nationals Hat, $32.00
x - return to menu
""")
item = input("Please select from the menu or go back to the categories: ")
if item == '1' or item == '2' or item == '3':
#Adds item onto the the cart
cart.append(cloth_list[int(item)-1])
elif item == 'x':
Return = True
else:
print("Invalid input try again")
elif choice == '4':
while Return == False:
#Sub item menu
print("""
1 – Coho Salmon, $12.50
2 − Spaghetti, $2.75
3 – Milk, $3.99
4 – Eggs, $1.99
5 – Flat Tire Ale, $9.95
x - return to menu
""")
item = input("Please select from the menu or go back to the categories: ")
if item == '1' or item == '2' or item == '3' or item == '4' or item == '5':
#Adds item onto the the cart
cart.append(groc_list[int(item)-1])
elif item == 'x':
Return = True
else:
print("Invalid input try again")
elif choice == 'c':
checkout = True
print(cart)
else: print("Invalid input, please try again!")
else:
print("Do you want a new cart y/n")
choice = input()
if choice == 'y':
checkout = False
#Create new cart
cart.append([])
elif choice == 'n':
#Proceed to item summary
new_cart = False
else:
print("Invalid Option, Choose again")
#Print total number of carts
print("Total number of carts :",len(cart))
for v in range(len(cart)):
#Increment for each existing cart
print("Cart",v+1)
#Add total number of items within every cart
print("Total Number of items:",len(cart[v]))
#Add total price of items within every cart
print("Total cost of the items: $",sum(cart[v]))
main()
Your cart contains a list of items which themselves are array:
example, i ran your code and your cart looks like this:
[['My Own Words', 18.0], ['My Own Words', 18.0], ['My Own Words', 18.0], ['My Own Words', 18.0]]
you're trying to apply a sum on a position of an array, so for example when you do
sum(cart[0]) you call sum on ['My Own Words', 18.0] so your code tries to do:
'My Own Words'+18 which gives a type error.
if all you need is the just the total price you could just append the prices instead of the whole items, or you could simply append the prices to a seperate array and call sum on that

Why won't these class attributes multiply?

I have to prompt the user for 2 items. For each Item the program needs to know the name, price, and quantity. Once received it outputs
'{Item name} {Item quantity} # ${Item price} = {Item total}'
The item total takes the price and multiplies it by the quantity. However I can't see the total in the output?'
class Item:
def __init__(self, name = 'none', price = 0, quantity = 0, total = 0):
self.item_name = name
self.item_price = price
self.item_quantity = quantity
self.total = price * quantity
def __add__(self, other):
return self.total + other.total
def print_item_cost(self):
return print('{} {} # ${} = ${}'.format(self.item_name,
self.item_price,
self.item_quantity,
self.total))
#Grab first item
item_1 = Item()
print('Item 1\nEnter the item name:')
item_1.item_name = input()
print('Enter the item price:')
item_1.item_price = input()
print('Enter the item quanity:')
item_1.item_quantity = input()
#Grab second item
item_2 = Item()
print('\nItem 2\nEnter the item name:')
item_2.item_name = input()
print('Enter the item price:')
item_2.item_price = input()
print('Enter the item quanity:')
item_2.item_quantity = input()
#Output cost
print('TOTAL COST\n', item_1.print_item_cost(), item_2.print_item_cost())
You're creating your items using the empty parameter list:
item_1 = Item()
so that default values are used in __init__: price = 0, quantity = 0, thus self.total is calculated as 0. Later, you change price and quantity properties of existing object:
item_2.item_price = input()
item_2.item_quantity = input()
but this does not change total. What you probably should do is:
#Grab first item
print('Item 1')
name = input('Enter the item name:')
price = input('Enter the item price:')
quantity = input('Enter the item quanity:')
item_1 = Item(name, price, quantity)
(and the same for item_2)
What you are doing in the following function is that you are returning a print of the statement. What you need to do is just return the statement and the print statment from where you made the call will print the returned output. Change from this
def print_item_cost(self):
return print('{} {} # ${} = ${}'.format(self.item_name,
self.item_price,
self.item_quantity,
self.total))
To this
def print_item_cost(self):
return('{} {} # ${} = ${}'.format(self.item_name,
self.item_price,
self.item_quantity,
self.total))
Edit:
Your total value does not change and stays the same once its initialized so add a new calculate total method
def calculate_total(self):
self.total = self.price * self.quantity
And call this method calculate_total() for each object to recalculate the total
A couple of things, you are setting the total price during initialization, therefore you have to set the item_price and item_quantity at __init__. Another thing when you accept number input from user you have to parse it appropriate data type, because by default it's string.
This would work as you intended it
class Item:
def __init__(self, name = 'none', price = 0, quantity = 0, total = 0):
self.item_name = name
self.item_price = price
self.item_quantity = quantity
self.total = price * quantity
def __add__(self, other):
return self.total + other.total
def print_item_cost(self):
return ('{} {} # ${} = ${}'.format(self.item_name,
self.item_price,
self.item_quantity,
self.total))
#Grab first item
print('Item 1\nEnter the item name:')
item_name = input()
print('Enter the item price:')
item_price = int(input())
print('Enter the item quanity:')
item_quantity = int(input())
item_1 = Item(item_name, item_price, item_quantity)
#Grab second item
print('\nItem 2\nEnter the item name:')
item_name = input()
print('Enter the item price:')
item_price = int(input())
print('Enter the item quanity:')
item_quantity = int(input())
item_2 = Item(item_name, item_price, item_quantity)
#Output cost
print('TOTAL COST\n', item_1.print_item_cost(), item_2.print_item_cost())
total must be calculated after you provide the actual values
input() returns string in python 3, should be converted to integers (or float)
changed the name of the print_item_cost function and removed print from the function; either print or return string but not both
class Item:
def __init__(self, name = 'none', price = 0, quantity = 0, total = 0):
self.item_name = name
self.item_price = price
self.item_quantity = quantity
# self.total = price * quantity
def total(self):
return self.item_price * self.item_quantity
def __add__(self, other):
return self.total + other.total
def item_cost_string(self):
return '{} {} # ${} = ${}'.format(self.item_name,
self.item_price,
self.item_quantity,
self.total())
#Grab first item
item_1 = Item()
print('Item 1\nEnter the item name:')
item_1.item_name = input()
print('Enter the item price:')
item_1.item_price = int(input())
print('Enter the item quanity:')
item_1.item_quantity = int(input())
#Grab second item
item_2 = Item()
print('\nItem 2\nEnter the item name:')
item_2.item_name = input()
print('Enter the item price:')
item_2.item_price = int(input())
print('Enter the item quanity:')
item_2.item_quantity = int(input())
#Output cost
print('TOTAL COST\n', item_1.item_cost_string(), '\n', item_2.item_cost_string())
When you do something like
self.total = price * quantity
It uses the current values of price and quantity to set the value of self.total when this line is executed. This does not define a formula that will automatically update self.total when the value of price or quantity changes.

Categories

Resources