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.
Related
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.
The code should Capture products in stock (i.e. name, price, date supplied, supplier name, quantity), Retrieve the price when name is given upon each purchase and deducts the quantity in
stock, Calculate the total price for each purchase and prints value indicating date and time of
purchase, Sends an alert when quantity reaches 5 to shopkeeper and places order to supplier.
My code right now is not looping so that I can add a number of products then be able to access them, I tried using a while loop but it is running forever. Kindly help
import datetime
class Stock:
def __init__(self, name, price, supplier, quantity,date):
self.name = name
self.price = price
self.date = date
self.supplier = supplier
self. quantity = quantity
def check_item(self, name):
for i in range(len(ls)):
if (ls[i].name == name):
return i
def sale(self):
n = int(input("How many products to sale: "))
total = 0
for j in range(n):
name = input("Enter Product name : ")
quantity = int(input("Enter quantity: "))
i = obj.check_item(name)
if i and ls[i].quantity >= quantity:
ls[i].quantity -= quantity
if ls[i].quantity < 5:
print("Low Stock! Low Stock! Order Placed")
obj.place_order(name, ls[i].supplier, quantity+10)
print("....Uncle G Shop....")
print(datetime.date.today())
print("Product Name | Quantity | Cost $")
print(ls[i].name, end=" ")
print(quantity, end=" ")
print(ls[i].price * quantity)
total += ls[i].price * quantity
print("\n")
print("Total Cost----->", "$" + total)
else:
print("Product out of stock or not enough quantity")
def purchase(self):
name = input("Enter Product name: ")
date = datetime.date.today()
i = obj.check_item(name)
if i:
ls[i].quantity += int(input("Enter quantity: "))
ls[i].price = int(input("Enter product price: "))
ls[i].date = date
else:
quantity = int(input("Enter quantity: "))
price = int(input("Enter product price: "))
supplier = input("Enter Supplier: ")
ob = Stock(name, price, supplier, quantity, date)
ls.append(ob)
def place_order(self,name, supplier, quantity):
return name, supplier, quantity
def print_products(self):
def __repr__(self):
return str(self.name) + str(self.price) + str(supplier) + str(self.quantity) + str(self.date)
return __repr__
def main(self):
print("Welcome To Uncle G Shop")
print("choose an option below")
print("\n1.Enter a Product\n2.Make a sale \n3.See all Products\n4.Exit")
option = int(input("Enter option here: "))
while True:
if option == 1:
obj.purchase()
elif option == 2:
obj.sale()
elif option == 3:
obj.print_products()
elif option == 4:
print("Have a good day")
break
else:
print("Enter a valid input!")
# A list to add Products
ls = []
# an object of Stock class
obj = Stock('', 0, 0, 0, '')
obj.main()
Your main menu doesn't have a break from the while loop for option 4.
You also need to think again about how to use your class. At present, you have multiple methods referring to a variable, ls, created outside of the class. Either treat Stock as a class to deal with individual purchase records, or to deal with stock overall. You could maintain in the class itself a list of instances of the class and offer class methods, as well as instance methods, to manage that overall stock.
I need to use Sum() instead of
if name in ingredients.keys():
ingredients[name] += units
else:
ingredients[name] = units
but I have no idea how, because I have a long chain of relations. Here is my code:
def shopping_list_ingredients(request):
shopping_list = ShoppingList.objects.filter(user=request.user).all()
ingredients = {}
for item in shopping_list:
for x in item.recipe.recipe_ingredient.all():
name = f'{x.ingredient.title} ({x.ingredient.unit})'
units = x.count
if name in ingredients:
ingredients[name] += units
else:
ingredients[name] = units
download = []
for key, units in ingredients.items():
download.append(f'{key} - {units} \n')
return download
def shopping_list_ingredients(request):
shopping_list = ShoppingList.objects.filter(user=request.user).all()
ingredients = {}
for item in shopping_list:
#if item.recipe.recipe_ingredient.all().ingredient.unit is dict
values = item.recipe.recipe_ingredient.all().ingredient.unit.values()
total = sum(values)
#if it's list
total = sum(item.recipe.recipe_ingredient.all().ingredient.unit)
I am working on this
class Product:
def __init__(self, date=0, product_name=0,qty=0,supplier=0):
self.product_name = product_name
self.date = date
self.qty = qty
self.supplier= supplier
self.my_list = []
def purchase(self, date, product_name, qty, supplier_name ):
self.my_list.append([supplier_name,date,product_name,qty])
def calculation(self):
for i in self.my_list:
print(i)
choice=None
p=Product()
while True:
choice=int(input("1 for the add record\n2 For the display result.\n"))
if choice == 1:
product_name=input("Enter the product name\n")
qty = int(input("Enter the qty.\n"))
date= input("Enter the date")
supplier_name = input("Enter the supplier name.\n ")
p.purchase(date,product_name,qty, supplier_name)
elif choice == 2:
p.calculation()
after executing this i have added data like this... when we choose 2 number option i am having data like this
eg.[supplier_name, date, product_name, quantity]
[supplierA, 2019-01-01, pencil, 20]
[supplierA, 2019-01-01, pencil, 30]
[supplierA, 2018-02-02, pen, 20]
[supplierB, 2017-02-02, scale, 10]
[supplierB, 2017-10-10, scale, 20]
[supplierC, 2019-01-01, pencil,10]
[supplierC, 2019-01-01, pencil,10]
[supplierC, 2019-01-01, pencil,10]
I want to filter this data in a way that if date and product name are same, its quantity should be added. and it must be group by supplier name .I means only individual supplier's date and qty be added in
expected output is
Supplier A:
[2019-01-01, pencil, 50]
[2018-02-02, pen, 20]
Supplier B:
[2017-02-02, scale, 10]
[2017-10-10, scale, 20]
Supplier C:
[2019-01-01, pencil, 30]
i have tried with lambda and filter but could not able to make it. any idea how to make it possible?
this will work i think:
class Product:
#init
def __init__(self, date=0, product_name=0,qty=0,supplier=0):
self.product_name = product_name
self.date = date
self.qty = qty
self.supplier= supplier
#make self.my_dict
self.my_dict={}
def purchase(self, date, product_name, qty, supplier_name ):
#make a new key if needing
try:
#add the data to the list
self.my_dict[supplier_name].append([date,product_name,qty])
except:
#make a new list with data
self.my_dict[supplier_name] = [[date,product_name,qty]]
def calculation(self):
#getting keys
for i in list(self.my_dict):
#print key
print(i)
#get items
for k in self.my_dict[i]:
#print item
print(k)
choice=None
p=Product()
while True:
choice=int(input("1 for the add record\n2 For the display result.\n"))
if choice == 1:
product_name=input("Enter the product name\n")
qty = int(input("Enter the qty.\n"))
date= input("Enter the date")
supplier_name = input("Enter the supplier name.\n ")
p.purchase(date,product_name,qty, supplier_name)
elif choice == 2:
p.calculation()
you can also modify existing purchase method :
def purchase(self, date, product_name, qty, supplier_name ):
for item in self.my_list:
if item[2] == product_name and item[1] == date and item[0] == supplier_name:
item[3] = item[3] + qty
return
self.my_list.append([supplier_name,date,product_name,qty])
You could do this:
from itertools import groupby
from operator import itemgetter
def calculation(self):
# sort and group items by supplier_name, date, product_name
x = groupby(sorted(self.my_list, key=itemgetter(slice(None, 3))), itemgetter(slice(None, 3)))
# sum the quantities
y = [i + [sum(map(itemgetter(3), j))] for i, j in x]
# group items by supplier
z = [(i, list(map(itemgetter(slice(1, None)), j))) for i, j in groupby(y, itemgetter(0))]
# output
for supplier, values in z:
print("{0}:".format(supplier))
print("\n".join(map(str, values)))
I have an intro class in Python where part of the instructions are:
(2) Build the ShoppingCart class with the following data attributes and related methods. Note: Some can be method stubs (empty methods) initially, to be completed in later steps.
Parameterized constructor which takes the customer name and date as parameters
Attributes
customer_name (string) - Initialized in default constructor to "none"
current_date (string) - Initialized in default constructor to "January 1, 2016"
cart_items (list)
Methods
add_item()
Adds an item to cart_items list. Has parameter ItemToPurchase. Does not return anything.
The code is:
class ItemToPurchase:
def __init__(self):
self._name = "none"
self._price = 0
self._quantity = 0
self._description = "none"
def item_name(self, name):
self._name = name
def item_price(self, price):
self._price = price
def item_quantity(self, quantity):
self._quantity = quantity
def item_description(self, description):
self._description = description
def __str__(self):
print("For item " + self._name + ": " + self._description + " there are " + str(self._quantity) + " available at $" + str(self._price) + ".")
def print_item_cost(self):
print(self._name + " " + str(self._quantity) + " # $" + str(self._price) + " = $" + str(self._quantity * self._price))
def print_item_description(self):
print(self._name + ": " + self._description)
class ShoppingCart:
def __init__(self, name="none", date="January 1, 2016"):
cart_items = []
_customer_name = name
_current_date = date
def add_item(self, cartItem):
self.cart_items.append(cartItem)
def remove_item(self, item_name):
count = 0
itms = self.cart_items[:]
for i in range(len(itms)):
itm = itms[i]
if itm._name == item_name:
del self.cart_items[i]
count += 1
if count == 0:
print(" ")
print("Item not found in cart. Nothing removed.")
def modify_item(self, ItemToPurchase):
count = 0
itms = self.cart_items[:]
for i in range(len(itms)):
itm = itms[i]
if itm._name == ItemToPurchase._name:
count += 1
if ItemToPurchase._description != "none":
itm.item_description(ItemToPurchase._description)
if ItemToPurchase._price != 0:
itm.item_price(ItemToPurchase._price)
if ItemToPurchase._quantity != 0:
itm.item_quantity(ItemToPurchase._quantity)
if count == 0:
print(" ")
print("Item not found in cart. Nothing modified.")
def get_num_items_in_cart(self):
count = 0
itms = self.cart_items[:]
for i in range(len(itms)):
itm = itms[i]
count += itm._quantity
return count
def get_cost_of_cart(self):
cost = 0
itms = self.cart_items[:]
for i in range(len(itms)):
itm = itms[i]
cost += (itm._quantity * itm._price)
return cost
def print_total(self):
print(self._customer_name + "'s Shopping Cart - " + self._current_date)
count = len(self.cart_items)
if count == 0:
print(" ")
print("SHOPPING CART IS EMPTY")
return 0
print("Number of Items: " + str(count))
print(" ")
for itm in self.cart_items:
itm.print_item_cost()
total = self.get_cost_of_cart()
print("Total: $" + str(total))
def print_descriptions(self):
print(self._customer_name + "'s Shopping Cart - " + self._current_date)
print(" ")
print("Item Descriptions")
for itm in self.cart_itmes:
print(itm.item_name() + ": " + itm.item_description())
def print_menu(cart):
print(" ")
print("MENU")
print("a - Add item to cart")
print("r - Remove item from cart")
print("c - Change item quntity")
print("i - Output items' descriptions")
print("o - Output shopping cart")
print("q - Quit")
print(" ")
def main():
#Define Constants and variables
custName = ""
dateToday = ""
custName = input("Enter customer's name: ")
dateToday = input("Enter today's date: ")
print("Customer name: " + custName)
print("Today's date: " + dateToday)
myCart = ShoppingCart(custName,dateToday)
option = ""
while option != "q":
print_menu(myCart)
option = input("Choose an option: ").lower().strip()
if option == "o":
myCart.print_descriptions()
elif option == "a":
print("ADD ITEM TO CART")
itemName = input("Enter the item name: ")
itemDescr = input("Enter the item description: ")
itemPrice = int(input("Enter the item price: "))
itemQuantity = int(input("Enter the item quantity: "))
print(" ")
cartItem = ItemToPurchase()
cartItem.item_name(itemName)
cartItem.item_description(itemDescr)
cartItem.item_price(itemPrice)
cartItem.item_quantity(itemQuantity)
myCart.add_item(cartItem)
elif option == "r":
print("REMOVE ITEM FROM CART")
itemName = input("Enter name of item to remove: ")
myCart.remove_item(itemName)
elif option == "c":
print("CHANGE ITEM QUNATITY")
itemName = input("Enter the item name: ")
itemQuantity = int(input("Enter the new quantity: "))
changeItem = ItemToPurchase(itemName)
changeItem.item_quantity(itemQuantity)
myCart.modify_item(changeItem)
main()
I am getting the following error:
Enter customer's name: Rog
Enter today's date: Oct 20
Customer name: Rog
Today's date: Oct 20
MENU
a - Add item to cart
r - Remove item from cart
c - Change item quntity
i - Output items' descriptions
o - Output shopping cart
q - Quit
Choose an option: a
ADD ITEM TO CART
Enter the item name: Sketchers
Enter the item description: Black
Enter the item price: 120
Enter the item quantity: 2
Traceback (most recent call last): File
"C:\PythonWorkspace\Chapter9Assignment\src\onlineShoppingCart2.py",
line 176, in
main() File "C:\PythonWorkspace\Chapter9Assignment\src\onlineShoppingCart2.py",
line 163, in main
myCart.add_item(cartItem) File "C:\PythonWorkspace\Chapter9Assignment\src\onlineShoppingCart2.py",
line 44, in add_item
self.cart_items.append(cartItem) AttributeError: 'ShoppingCart' object has no attribute 'cart_items'
Can anyone tell me what I am doing incorrectly?
class ShoppingCart:
def __init__(self, name="none", date="January 1, 2016"):
cart_items = []
_customer_name = name
_current_date = date
These are all local variable. If you want them to be attributes of the instance, you have to explicitly refer to self:
class ShoppingCart:
def __init__(self, name="none", date="January 1, 2016"):
self.cart_items = []
self._customer_name = name
self._current_date = date