Why do I get an attribute error with my class? - python

EDIT BELOW!
Here is my retail_item class:
#RetailItem Class
class RetailItem:
def __init__(self, desc, inventory, price):
self.__desc=desc
self.__inventory=inventory
self.__price=price
#mutators
def set_desc (self, desc):
self.__desc=desc
def set_inventory (self, inventory):
self.__inventory=inventory
def set_price (self, price):
self.__price = price
#accessors
def get_desc(self):
return self.__desc
def get_inventory(self):
return self.__inventory
def get_price(self):
return self.__price
def __str__(self):
return 'Item Description:' + self.__desc, \
'\tNumber of Units:' + self.__inventory, \
'\tPrice: $' + self.__price
And my cash_register class:
#CashRegister Class
class CashRegister:
def __init__(self, purchase, total, show, clear):
self.__purchase=purchase
self.__total=total
self.__show=show
self.__clear=clear
#mutators
def purchase_item(self, purchase):
self.__purchase=purchase
def get_total(self, total):
self.__total=total
def show_item(self, show):
self.__show=show
def clear(self, clear):
self.__clear=clear
#accessors
def acc_purchase(self):
return self.__purchase
def acc_total(self):
return self.__total
def acc_show(self):
return self.__show
def acc_clear(self):
return self.__clear
And finally my program:
import retail_item
import cash_register
SHOW = 1
PURCHASE = 2
CART = 3
TOTAL = 4
EMPTY = 5
QUIT = 6
def main():
mylist = make_list()
#mycr = cash_register.CashRegister(mylist)
choice = 0
# Process menu selections until user quits program.
while choice != QUIT:
# Get the user's menu choice.
choice = get_menu_choice()
# Proces the choice.
if choice == SHOW:
show_items(mylist)
elif choice == PURCHASE:
purchase_item(mylist)
elif choice == TOTAL:
get_total(mylist)
elif choice == EMPTY:
clear(mylist)
def make_list():
item_list = {}
desc = 'Jacket'
inventory = 12
price = 59.95
entry = retail_item.RetailItem(desc, inventory, price)
item_list[desc]=entry
desc = 'Jeans'
inventory = 40
price = 34.95
entry = retail_item.RetailItem(desc, inventory, price)
item_list[desc]=entry
desc = 'Shirt'
inventory = 20
price = 24.95
entry = retail_item.RetailItem(desc, inventory, price)
item_list[desc]=entry
return item_list
# The get_menu_choice function displays the menu and gets
# a validated choice from the user.
def get_menu_choice():
print()
print('CASH REGISTER MENU')
print('-------------------------')
print('1. Show Retial Items')
print('2. Purchase Item(s)')
print('3. Show Current Shopping Cart')
print('4. Show Total of Items Purchased')
print('5. Empty Your Shopping Cart')
print('6. Quit the program')
print()
# Get the user's choice.
choice = int(input('Enter your choice: '))
# Validate the choice.
while choice < SHOW or choice > QUIT:
choice = int(input('Enter a valid choice: '))
# Return the user's choice.
return choice
def show_items(mylist):
print('\t\tDescription\t\tUnits in Inventory\t\tPrice')
print('--------------------------------------------------------------------------------')
x=1
for item in mylist:
print('Item #', x, '\t\t', item.get_desc(), '\t\t\t\t', item.get_inventory(), '\t\t\t$', format(item.get_price(), ',.2f'),sep='')
print()
x+=1
def purchase_item(mylist):
desc = input('Enter the item you wish to purchase: ')
if desc in mylist:
amount=int(input('How many would you like to buy: '))
if mylist[units]>0:
mylist[units]-=amount
elif (units-amount<0):
mylist[units]=0
else:
mylist[units] = 0
entry=cash_register.CashRegister(desc, units,)
mylist[desc]=entry
print()
def get_total(mylist):
print()
def clear(mylist):
print(mylist)
mylist.clear()
print(mylist)
main()
So my question is, how to I update only one object of a class?
And how do I call on the cash_register class?
Here are the instructions for the assignment, if that helps:
This exercise assumes that you have created the RetailItem class for Programming
Exercise 5. Create a CashRegister class that can be used with the RetailItem class. The
CashRegister class should be able to internally keep a list of RetailItem objects. The
class should have the following methods:
• A method named purchase_item that accepts a RetailItem object as an argument.
Each time the purchase_item method is called, the RetailItem object that is passed as
an argument should be added to the list.
• A method named get_total that returns the total price of all the RetailItem objects
stored in the CashRegister object’s internal list.
• A method named show_items that displays data about the RetailItem objects stored
in the CashRegister object’s internal list.
• A method named clear that should clear the CashRegister object’s internal list.
Demonstrate the CashRegister class in a program that allows the user to select several
items for purchase. When the user is ready to check out, the program should display a list
of all the items he or she has selected for purchase, as well as the total price.
EDIT: Here's my somewhat final code. I know it's not pretty, and I apologize for the lack of comments. I would still like some feedback even though I'll be submitting it shortly (for my own betterment and for job opportunities!) Here it is:
import retail_item
import cash_register
SHOW = 1
PURCHASE = 2
TOTAL = 3
EMPTY = 4
QUIT = 5
def main():
#set all variables to zero
lister = []
inv=[]
cost=[]
desc=''
inventory=0
price=0
total=0
purchase=0
#setting variable for each class
cash=cash_register.CashRegister(purchase, total, lister, inv, cost)
retail=retail_item.RetailItem(desc, inventory, price)
#classes
desc = 'Jacket'
inventory = 12
price = 59.95
#setting classes
retail.set_desc(desc)
retail.set_inventory(inventory)
retail.set_price(price)
#Adding to cart
cash.purchase_item(retail.get_desc(), lister)
cash.purchase_item(retail.get_inventory(), inv)
cash.purchase_item(retail.get_price(), cost)
desc = 'Jeans'
inventory = 40
price = 34.95
retail.set_desc(desc)
retail.set_inventory(inventory)
retail.set_price(price)
cash.purchase_item(retail.get_desc(), lister)
cash.purchase_item(retail.get_inventory(), inv)
cash.purchase_item(retail.get_price(), cost)
desc = 'Shirt'
inventory = 20
price = 24.95
retail.set_desc(desc)
retail.set_inventory(inventory)
retail.set_price(price)
cash.purchase_item(retail.get_desc(), lister)
cash.purchase_item(retail.get_inventory(), inv)
cash.purchase_item(retail.get_price(), cost)
choice = 0
# Process menu selections until user quits program.
while choice != QUIT:
# Get the user's menu choice.
choice = get_menu_choice()
# Proces the choice.
if choice == SHOW:
show_items(cash, retail, lister, inv, cost)
elif choice == PURCHASE:
purchase_item(cash, retail, lister, inv, cost)
elif choice == TOTAL:
get_total(cash, retail, lister)
elif choice == EMPTY:
price=0
cash.set_total(price)
clear(cash, lister)
# The get_menu_choice function displays the menu and gets
# a validated choice from the user.
def get_menu_choice():
print()
print('CASH REGISTER MENU')
print('-------------------------')
print('1. Show Retail Items')
print('2. Purchase Item(s)')
print('3. Show Total of Items Purchased')
print('4. Empty Your Shopping Cart')
print('5. Quit the program')
print()
# Get the user's choice.
choice = int(input('Enter your choice: '))
# Validate the choice.
while choice < SHOW or choice > QUIT:
choice = int(input('Please enter a valid choice: '))
# Return the user's choice.
return choice
def show_items(cash, retail, lister, inv, cost):
print('\t\tDescription\t\tUnits in Inventory\t\tPrice')
print('--------------------------------------------------------------------------------')
cash.show_item(lister, inv, cost)
def purchase_item(cash, retail, lister, inv, cost):
JACKET=1
JEANS=2
SHIRT=3
QUIT=4
choice=0
print()
print('WHICH WOULD YOU LIKE TO BUY')
print('-------------------------')
print('1. Jacket')
print('2. Jeans')
print('3. Shirt')
print('4. Quit')
print()
print('Choose as many as you like. Press 4 then ENTER to quit.')
while choice != QUIT:
# Get the user's menu choice.
choice = int(input('Which would you like to buy: '))
if choice < JACKET or choice > QUIT:
choice = int(input('Please enter a valid choice: '))
while choice != QUIT:
# Proces the choice.
if choice == JACKET:
desc = 'Jacket'
inventory = 12
price = 59.95
retail.set_desc(desc)
retail.set_inventory(inventory)
retail.set_price(price)
cash.purchase_item(retail.get_desc(), lister)
cash.purchase_item(retail.get_inventory(), inv)
cash.purchase_item(retail.get_price(), cost)
cash.set_total(price)
break
elif choice == JEANS:
desc = 'Jeans'
inventory = 40
price = 34.95
retail.set_desc(desc)
retail.set_inventory(inventory)
retail.set_price(price)
cash.purchase_item(retail.get_desc(), lister)
cash.purchase_item(retail.get_inventory(), inv)
cash.purchase_item(retail.get_price(), cost)
cash.set_total(price)
break
elif choice == SHIRT:
desc = 'Shirt'
inventory = 20
price = 24.95
retail.set_desc(desc)
retail.set_inventory(inventory)
retail.set_price(price)
cash.purchase_item(retail.get_desc(), lister)
cash.purchase_item(retail.get_inventory(), inv)
cash.purchase_item(retail.get_price(), cost)
cash.set_total(price)
break
print()
def get_total(cash, retail, lister):
print()
cash.show_items(cash.get_list(lister))
print('Your total is: $', format(cash.cost_total(),',.2f'))
def clear(cash, lister):
print('Shopping cart emptied.')
lister=lister.clear()
price=0
cash.set_total(price)
return lister
main()
RetailItem Class:
class RetailItem:
def __init__(self, desc, inventory, price):
self.__desc=desc
self.__inventory=inventory
self.__price=price
#mutators
def set_desc (self, desc):
self.__desc=desc
def set_inventory (self, inventory):
self.__inventory=inventory
def set_price (self, price):
self.__price = price
#accessors
def get_desc(self):
return self.__desc
def get_inventory(self):
return self.__inventory
def get_price(self):
return self.__price
def __str__(self):
return 'Item Description:' + self.__desc, \
'\tNumber of Units:' + self.__inventory, \
'\tPrice: $' + self.__price
And again, lastly my CashRegister Class:
#CashRegister Class
class CashRegister:
def __init__(self, purchase, total, lister, inv, cost):
self.__purchase=purchase
self.__total=total
self.__lister=[]
self.__inv=[]
self.__cost=[]
#mutators
def purchase_item(self, purchase, lister):
self.__purchase=purchase
lister.append(purchase)
return lister
def set_total(self, price):
self.__total+=price
def show_item(self, lister, inventory, price):
i=0
while i<len(lister):
s=('Item # %i\t%s\t\t\t\t%i\t\t\t%4.2f') % ((i+1),lister[i],inventory[i],price[i])
s = s.strip(' \t\n\r')
print(s)
i+=1
def show_items(self, lister):
i=0
print('You have purchased the following items')
while i<len(lister):
print(lister[i])
i+=1
def clear(self, lister):
i=0
while i<len(lister):
del lister[i]
i+=1
return lister
def get_list(self, lister):
return lister
#accessors
def acc_purchase(self):
return self.__purchase
def cost_total(self):
return self.__total
def acc_show(self):
return self.__show
def acc_clear(self):
return self.__clear
Thanks again guys! I used this site often, and though I didn't use much of what y'all gave me this time, you're still awesome!

This code has a couple of major problems. Without a stack trace I can't say exactly why you're getting an AttributeError, but I can tell that CashRegister objects can't be instantiated as written. Its __init__ refers to nonexistent variables - item and items.
Your CashRegister class is taking arguments to __init__ that aren't necessary - and in some cases should be methods. I don't see any reason your CashRegister class should take any __init__ arguments - it should initialize the list of RetailItem objects and probably a running total and do nothing else. purchase_item should update those internal attributes, get_total and show_items should read them (or get_total should calculate the total based on the list if you don't keep a running total) and clear should reset them both.
Stylistically, mutators and accessors and hidden internal data are not a Pythonic idiom. In general Python classes get and set member data directly, and get refactored to use properties if the behavior ever needs to change. I see that this is for a class/exercise, so you might be using them because they're required, but if not you're better off without them.
edit
This is what my main() would look like, making the minimal edits to show the logic:
def main():
items = make_list()
mycr = cash_register.CashRegister()
# at this point, mycr.show_items() should return [] and mycr.get_total() should return 0
choice = 0
while choice != QUIT:
choice = get_menu_choice()
if choice == SHOW:
mycr.show_items()
elif choice == PURCHASE:
item, quantity = get_purchase(items)
if item and quantity:
item.set_inventory(max(0, item.get_inventory() - quantity))
mycr.purchase_item(item, quantity)
elif choice == TOTAL:
print(mycr.get_total())
elif choice == EMPTY:
mycr.clear()
def get_purchase(items):
desc = input('Enter the item you wish to purchase: ')
if desc in items:
amount=int(input('How many would you like to buy: '))
return items[desc], amount
else:
return None, 0
This doesn't cover every possibility - for instance, as with your original code it allows entering higher quantities than are currently available with no side effect besides setting the quantity to 0. But the exercise description doesn't mention inventory tracking, so maybe that's not a requirement.

Related

Rounds integer even with float- python

Below is my code. the issue is in MAIN. The code works as a person trying to buy items into a cart and you can see the total price of those items. They have to enter in the price for each item that they want. If a person inputs a number to two decimal places, it rounds it to the nearest whole number.
import locale
class CashRegister:
def __init__(self):
mself.items = 0
self.price = int(float(0.00))
def addItems(self,price): #keeps track of total number of items in cart
self.price += price
self.items += 1
print(self.price)
def getTotal(self): #returns total price
return self.price
def getCount(self): #return the item count of the cart
return self.items
def clearCart(self): #clears cart for another user or checkout
self.items = 0
self.price = int(float(0.00))
def main():
user_name = input('What is your name?\n') #weclomes user
print("Hello",user_name)
locale.setlocale(locale.LC_ALL, 'en_US')
user_name = CashRegister() #user is using the cash register
while True:
line = input ("Would you like to add another food item to your cart? Choose y or n \n")
if line == "y":
** price = int(float(input("please input the price of the item\n")))
print(price)**
user_name.addItems(price) #user adds prices to cart
elif line == "n":
print("Your total checkout price:", locale.currency(user_name.getTotal()) )
# int(float(locale.currency(user_name.getTotal())))
print("Your total item count", user_name.getCount())
user_name.clearCart() #clears cart for another user/checkout
break
else:
print("Error")
if __name__ == '__main__':
main()
As soon as the person inputs the number, I printed it to see if that's where the problems lies. I'll enter 3.20 but it automatically converts it to 3. I have no idea how to force it to keep those decimals. I even tried printing it with the int/float and it still doesn't work.
The int() function always returns an integer. An integer never has any decimal points. So use only
float(input("please input the price of the item\n"))
instead of
int(float(input("please input the price of the item\n")))

User input not saving into inventory list

Basically I am making an app to better assist me at managing my ebay store. I am still very new to programming and OOP. After watching some tutorials I pieced together the following code. Everything so far works pretty well. What I am currently stuck on is when the user inputs an item for inventory, it is not saving it. And, when the user wants to view the inventory the item they added wont populate. Any input or suggestions would be much apprenticed.
def Inventory():
All_Inventory = {}
class Ebay_Inventory:
def __init__(self, manufacturer, object_type, price):
self.manufacturer = manufacturer
self.object_type = object_type
self.price = price
def add_item(self):
manufacturer = input("Enter Manufacturer: ")
object_type = input("Enter what the item is: ")
price = input("Enter price: ")
item_info = Ebay_Inventory(manufacturer, object_type, price)
All_Inventory = item_info
print("Item added successfully")
def delete_item(self):
delete = input("What is the item you want to delete?: ")
if delete in All_Inventory.keys():
del[delete]
print("The item entered has been deleted.")
else:
print("Item not found")
def sale_status(self):
update = input("What is the item you want to update?:")
if update in All_Inventory.keys():
pass
else:
print("Item not found")
user=True
while user:
print("\n1. Add to item inventory")
print("2. Remove item from inventory")
print("3. Update sale status")
print("4. View inventory")
print("5. Exit program")
user_wants=input("What would you like to do today?")
if user_wants=="1":
Ebay_Inventory.add_item(input)
elif user_wants=="2":
Ebay_Inventory.delete_item(input)
elif user_wants=="3":
Ebay_Inventory.sale_status(input)
elif user_wants=="4":
print(All_Inventory)
elif user_wants=="5":
print("\n Thank you for using item inventory.")
break
elif user_wants!="":
print("\n Input not understood. Please try again.")
You need to read about Scope, OOP and dicts:
You are not adding to your Inventory.All_Inventory - you create a new local with All_Inventory = item_info
https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces
Short description of the scoping rules?
You mix up static class attributes and instance attributes, read:
https://docs.python.org/3/tutorial/classes.html#class-objects.
What is the difference between #staticmethod and #classmethod?
You are deleting / accessing your dictionary wrongly - see :
https://docs.python.org/3/tutorial/datastructures.html#dictionaries
Delete an element from a dictionary
Fixed:
class Ebay_Inventory:
Inventory = {} # class property
#staticmethod
def print_inventory():
for k in Ebay_Inventory.Inventory:
for i in Ebay_Inventory.Inventory[k]:
print(k,i)
class Ebay_Item:
def __init__(self, key, manufacturer, object_type, price):
self.manufacturer = manufacturer
self.object_type = object_type
self.price = price
self.key = key
def __str__(self):
return f"{self.manufacturer} {self.object_type} {self.price}"
def __repr__(self):
return str(self)
#staticmethod
def add_item(key=None, man=None, obj=None, pri=None):
# use values if given, else ask - this is for demo purposes only
key = key or input("Enter key: ")
manufacturer = man or input("Enter Manufacturer: ")
object_type = obj or input("Enter what the item is: ")
price = pri or input("Enter price: ")
# create new item
item_info = Ebay_Inventory.Ebay_Item(key, manufacturer, object_type, price)
# add to class member, create key if need be
Ebay_Inventory.Inventory.setdefault(item_info.key,[]).append(item_info)
def delete_item(key=None):
delete = key or input("What is the item you want to delete?: ")
if delete in Ebay_Inventory.Inventory:
del Ebay_Inventory.Inventory[delete]
print("The item entered has been deleted.")
else:
print("Item not found")
def __str__(self):
return Ebay_Inventory.print_inventory()
# add 2 items and print
Ebay_Inventory.add_item(1,"Me","Me",1000)
Ebay_Inventory.add_item(2,"You","You",1000)
Ebay_Inventory.print_inventory()
# remove non existent and existent item and print
Ebay_Inventory.delete_item(3)
Ebay_Inventory.delete_item(2)
Ebay_Inventory.print_inventory()
Output:
1 Me Me 1000
2 You You 1000
Item not found
The item entered has been deleted.
1 Me Me 1000
Sorry to rework your code pretty extensively, but I think this is more like what you are going for:
class EbayInventory:
def __init__(self):
self.all_inventory = []
def print_items(self):
print('Current item list by index:')
for i in range(0, len(self.all_inventory)):
print("{} -> {}".format(i+1, self.all_inventory[i]))
def add_item(self):
manufacturer = input("Enter Manufacturer: ")
object_type = input("Enter what the item is: ")
price = input("Enter price: ")
item = {'manufacturer': manufacturer, 'type': object_type, 'price': price}
self.all_inventory.append(item)
print("Item added successfully")
def delete_item(self):
self.print_items()
delete = int(input("Item id you want to delete: "))
try:
del self.all_inventory[delete - 1]
print("The item entered has been deleted.")
except Exception as e:
print("An error occurred deleting that item, details below")
print(e)
def sale_status(self):
self.print_items()
update_index = int(input("Item id you want to update: "))
if update_index > len(self.all_inventory) or update_index <= 0:
print("You're trying to change an item that doesn't exist!!")
return
print("OK. Let's get that item up to date!")
manufacturer = input("Enter Manufacturer: ")
object_type = input("Enter what the item is: ")
price = input("Enter price: ")
item = {'manufacturer': manufacturer, 'type': object_type, 'price': price}
self.all_inventory[update_index - 1] = item
print("OK. We got that update taken care of")
if __name__ == "__main__":
my_app = EbayInventory()
while True:
print("\n1. Add to item inventory")
print("2. Remove item from inventory")
print("3. Update sale status")
print("4. View inventory")
print("5. Exit program")
user_wants = input("Please enter the number corresponding to how you would like help: ")
if user_wants == "1":
my_app.add_item()
elif user_wants == "2":
my_app.delete_item()
elif user_wants == "3":
my_app.sale_status()
elif user_wants == "4":
my_app.print_items()
elif user_wants == "5":
print("Thank you for using item inventory.")
break
else:
print("Input not understood. Please try again.")
You had a variable user that did nothing. You can simply enter an infinite loop with while True:. If you wanted to loop the way you did, then instead of a break you could have put a user = False to break out of the loop. This is sometimes a nifty trick, but doesn't make sense here I think. It seemed to me the inventory was really the only thing that would benefit by being stored in your class, and the methods could then access it to adjust it via a self.all_inventory. I moved your code to ask for item inputs to the add_item() and sale_status() methods, so now the main block of code looks a lot cleaner. I also wrapped it in if __name__ == "__main__": so that you can import this class to another project without running the entire program! I threw in some basic error checking with try: and except: clauses also. I think you were misunderstanding the difference between a Class and an Instance. So in my code the Class is EbayInventory, but the Instance is my_app. You create instances of your class just like I did with my_app = EbayInventory() and then the self now refers to my_app. In this manner I can call my_app.add_item(). You can have several instances of objects though, and they each have their own space in your computers memory. So you could have said:
app1 = EbayInventory()
app2 = EbayInventory()
app1.add_item()
And only the app1 will have any items, whereas app2 is still an empty list, but still has the methods to build an inventory via app2.add_item(). To answer your main question though, you never call your function Inventory() and therefore it doesn't exist to hold your information. When you call item_info = Ebay_Inventory(manufacturer, object_type, price) in fact you are making an Instance of a class, which is really nonsensical to do here because that means on the next line you could say item_info.add_item() and this would make another instance, yet you are not saving this information anywhere so you can never retrieve it!

Making a Cash Register on Python

I'm trying to make a store program on Python 3.6 and my code's not working.I made a lot of revisions, now I'm encountering more internal coding problems such as making the menu run in a loop until the customer exits the program and creating lists inside of lists with all of the information of the respective items. Code may not appear indented correctly here but that's more a copy and pasting error.
Here's the code:
class RetailItem:
def __init__(self):
self.price = price
self.units = units
self.description = description
class CashRegister:
def __init__(RetailItem, self):
self.totalprice=0
self.cart=[]
self.items=[]
duck = RetailItem
duck.description = "Large plush duck"
duck.units = 3
duck.price = 6.99
porcupine = RetailItem
porcupine.description = "Pink plush porcupine"
porcupine.units = 5
porcupine.price = 9.99
bunny = RetailItem
bunny.description = "small white plush bunny"
bunny.units = 7
bunny.price = 4.99
self.items=[duck,bunny,porcupine]
print("Welcome to The Toy Store.\n Selection:\n 1.Duck \n 2.Bunny \n 3.Porcupine")
def menu(self):
item = int(input("What would you like to select? "))
item=+1
item = self.items[item]
return item
def purchase(RetailItem):
self.items = self.items.append(item)
self.totalprice = totalprice.append(item.price)
item.units=item.units-1
self.cart= self.items.append(item)
print("You have added"+(item)+"to your cart")
def get_total(self):
return("Your total is", self.totalprice)
def show_item(RetailItem):
return(description(RetailItem), units(RetailItem), price(RetailItem))
def clear_register(self):
self.totalprice = []
self.items = []
def main():
C1=CashRegister(CashRegister)
C1.menu()
choice=int(input(("Options: \n 1.Add to Cart 2. View item \n 3.Return to Main Menu ")))
if choice==1:
purchase(item)
if choice==2:
show_item(item)
choice=int(input(("Would you like to purchase this item? \n 1. Yes \n 2. No"))
if choice==3:
C1.menu()
choice=int(input(("Options: \n 1. Add more items to your cart. 2.View cart 3. Quit"))
if choice!= 3:
if choice==1:
menu()
It seems as though def menu(self) is not inside any class, so it shouldn't have a self parameter. Remove it, and it should work. Or put menu into a class.
The self parameter is reserved for class methods. More info here
EDIT: Actually, if I understand your code, your menu(self) belongs to the CashRegister class. If so, just indent the entire menu(self) block.
class CashRegister:
def __int__(self,RetailItem):
self.total= ()
Duck = RetailItem()
Duck.description = "Large plush duck"
Duck.units = 3
Duck.price = 6.99
Porcupine = RetailItem()
Porcupine.description = "Pink plush porcupine"
Porcupine.units = 5
Porcupine.price = 9.99
Bunny = RetailItem()
Bunny.description = "small white plush bunny"
Bunny.unitsininv = 7
Bunny.price = 4.99
def menu(self):
print("Welcome to The Toy Store.\n Selection:\n 1.Bunny \n 2.Porcupine \n 3.Duck")
choice = int(input("What would you like to buy? "))
if choice==1:
item = Bunny
elif choice == 2:
item = Porcupine
elif choice==3:
item = Duck
else:
print("Error")
How to deal with menu not defined:
Keyword self is used for methods inside classes. menu is a
method at top level.
Just indent menu so it becomes a method of class CashRegister.
There are also other issues with your program.
You forgot to indent the Porcupine and Bunny objects so it will be in the __init__ of CashRegister
Your inputting with choice does not work.
Your CashRegister C1 isn't correctly initiated. You need to initialize it as an object: C1 = CashRegister(*some RetailObject*) not C1 = CashRegister
Bunny.unitsininv: unitsininv doesn't exist as a RetailItem field.
total for CashRegister should be a list.
purchase, get_total, show_items, clear_register should also be methods of CashRegister with a self.
There is a typo for init: you typed __int__ instead
Here is the updated code, you can take time to read to understand what you need to set up your CashRegister, and you can just use the Python Shell to make purchases to your CashRegister.
class RetailItem:
def __init__(self, price, units, description):
self.price = price
self.units = units
self.description = description
def __str__(self):
string = str(self.description)
string += ": $" + str(self.price)
string += " Units:" + str(self.units)
return string
class CashRegister:
def __init__(self):
self.total_items = [] # Should be a List
self.total_price = 0; # Missing
def menu(self):
print("Welcome to The Toy Store.\n Selection:\n 1.Bunny \n 2.Porcupine \n 3.Duck")
choice = int(input("What would you like to buy? "))
if choice==1:
item = Bunny
elif choice == 2:
item = Porcupine
elif choice==3:
item = Duck
else:
print("Error")
def purchase(self, item: RetailItem):
self.total_items.append(item.description)
self.total_price += item.price
def get_total(self):
print("Your total items are: ", self.total_items)
def show_items(self):
print("Your total price is: ", self.total_price)
def clear_register():
total_price = []
total_items = 0

I am having problems with my elif statements

I'm programming a game to try and improve my skills in python. In this part of the code I am trying to program a shop with a money system testing one variable against 5 different possible answers
while True:
choice=str(input("What would you like to buy? (Type in 'nothing' when you don't want anymore items) "))
if choice!="health potion" and "strength potion" and "strength booster" and "armour piece" and "nothing":
print()
next_line=input("I do not understand what you wrote. Try again please ")
print()
elif choice=="nothing":
next_line=input("The merchant says 'Thanks for business' ")
print()
break
elif choice=="health potion":
gold=gold-10
if gold<0:
gold=gold+10
next_line=input("Sorry but you don't have enough gold ")
print()
else:
next_line=input("You bought a health potion ")
health_potions=health_potions+1
next_line=input("You now have "+str(gold)+" gold coins ")
print()
elif choice=="strength potion":
gold=gold-15
if gold<0:
gold=gold+15
next_line=input("Sorry but you don't have enough gold ")
print()
else:
next_line=input("You bought a strength potion ")
strength_potions=strength_potions+1
next_line=input("You now have "+str(gold)+" gold coins ")
print()
elif choice=="strength booster":
gold=gold-45
if gold<0:
gold=gold+45
next_line=input("Sorry but you don't have enough gold ")
print()
else:
next_line=input("You boosted your strength ")
strength_booster=strength_booster+1
next_line=input("You now have "+str(gold)+" gold coins ")
print()
elif choice=="armour piece":
gold=gold-30
if gold<0:
gold=gold+30
next_line=input("Sorry but you don't have enough gold ")
print()
else:
next_line=input("You bought an armour piece ")
armour=armour+1
next_line=input("You now have "+str(gold)+" gold coins ")
print()
When you input health potion the code goes on like normal but with the other inputs it goes to this part of the code
if choice!="health potion" and "strength potion" and "strength booster" and "armour piece" and "nothing":
print()
next_line=input("I do not understand what you wrote. Try again please ")
print()
For fun, here is a significantly more advanced version.
Don't worry if it doesn't all make sense right away; try tracing through it and figuring out how it works. Once you fully understand it you will have a much better grasp of Python!
class Character:
def __init__(self, name, health=50, strength=20, gold=200, inventory=None):
"""
Create a new character
inventory is a list of items (may have repeats)
"""
self.name = name
self.health = health
self.strength = strength
self.gold = gold
self.inventory = [] if inventory is None else list(inventory)
def buy(self, item):
"""
Buy an item
"""
if self.gold >= item.cost:
print(item.buy_response.format(name=item.name, cost=item.cost)) # print acceptance
self.gold -= item.cost # pay gold
item.buy_action(self) # apply purchased item to character
return True
else:
print("Sorry but you don't have enough gold.")
return False
class Item:
def __init__(self, name, cost, buy_response="You bought a {name} for {cost} GP", buy_action=None):
# store values
self.name = name
self.cost = cost
# what to print on a successful purchase
self.buy_response = buy_response
# apply a purchased item to the character
self.buy_action = self.make_buy_action() if buy_action is None else buy_action
def make_buy_action(self):
def buy_action(char):
"""
Purchase default action: add item to character inventory
"""
char.inventory.append(self)
return buy_action
#staticmethod
def buy_strength_booster(char):
"""
Purchase strength booster action: increase character strength
"""
char.strength += 1
def __str__(self):
return self.name
class Shop:
def __init__(self, name, *inventory):
"""
Create a shop
inventory is a list of (num, item); if num is None the store has an unlimited supply
"""
self.name = name
self.inventory = {item.name:(num, item) for num,item in inventory}
def visit(self, char):
"""
Serve a customer
"""
print("\nHowdy, {}, and welcome to {}!".format(char.name, self.name))
while True:
print("\nWhat would you like to buy today? (type 'list' to see what's available or 'done' to leave)")
opt = input("{} GP> ".format(char.gold)).strip().lower()
if opt == 'done':
print("Have a great day, and c'mon back when you've got more gold!")
break
elif opt == 'list':
item_names = sorted(name for name, (num, item) in self.inventory.items() if num is None or num > 0)
if item_names:
print(", ".join(item_names))
else:
print("Huh - looks like we're all sold out. Try again next week!")
break
elif opt in self.inventory:
num, item = self.inventory[opt]
if num is None or num > 0:
yn = input("That's {} GP. You want it? [Y/n]".format(item.cost)).strip().lower()
if yn in {'', 'y', 'yes'}:
if char.buy(item) and num is not None:
self.inventory[opt] = (num - 1, item)
else:
print("(scowling, the proprietor stuffs the {} back under the counter)".format(item.name))
else:
print("'Fraid we're all out of those.")
else:
print("Sorry, hain't had one o' those around in a coon's age!")
def main():
# stock the store
shop = Shop("Dwarven Dave's Delving Deal Depot",
(6, Item("health potion", 10)),
(6, Item("strength potion", 15)),
(3, Item("strength booster", 45, "You boosted your strength!", Item.buy_strength_booster)),
(None, Item("armor piece", 30)) # unlimited stock
)
# create a buyer
jeff = Character("Jeff")
# visit the store
shop.visit(jeff)
if __name__ == "__main__":
main()
Your issue is with this statement:
if choice!="health potion" and "strength potion" and "strength booster" and "armour piece" and "nothing":
Comparing strings like this doesn't work. You need to make sure it isn't in an array of the strings
if choice not in ("health potion","strength potion","strength booster","armour piece","nothing"):
Otherwise it will always be true, so the first statement will always execute.

Getting functions to interact with each other

The project: Write a program in python in which the virtual dealer Jake plays against the virtual players: Mike and Will. Mike and Will are free to bet on different outcomes with different payout ratios. This will allow the comparison of various strategies. You should keep track of each player's bank roll (including the dealer)
The game is played with a 7 faced die with numbers [0 - 6] numbers[1, 2, 3] are blue and numbers [4, 5, 6] are green.
Correct Parity Pays: 2/1
Correct Colour Pays: 2/1
Exact Number Pays: 5/1
Here is the first draft with the modifications #Harvey Summer suggested. Comments on how I can improve the code's structure and performance are appreciated.
from random import choice
from random import randint
class die_face():
# This class is used to define the properties linked to each outcome on the dice.
def __init__(self, num, colour, parity):
self.num = num
self.colour = colour
self.parity = parity
# Determine the properties linked to each outcome on the dice.
zero = die_face(0, 'none', 'none')
one = die_face(1, 'blue', 'odd')
two = die_face(2, 'blue', 'even')
three = die_face(3, 'blue', 'odd')
four = die_face(4, 'green', 'even')
five = die_face(5, 'green', 'odd')
six = die_face(6, 'green', 'even')
options = [zero, one, two, three, four, five, six,]
class bet():
# Define the bets
def __init__(self, bet_type, odds):
self.bet_type = bet_type
self.odds = odds
num_bet = bet('num', 5)
colour_bet = bet('colour', 2)
parity_bet = bet('parity', 2)
class broker():
# Define the properties of the broker.
def __init__(self, name, balance):
self.name = name
self.balance = balance
def __str__(self):
result = "Name: {} \n" \
"Balance: {}" .format(self.name, self.balance)
return result
def modify_balance(self, amount):
self.balance += amount
main_broker = broker('Main',1e3)
def random_strategy():
# Bet a random amount on a random game with a random guess.
guess = 'empty'
game_mode= choice([num_bet, colour_bet, parity_bet])
if game_mode == num_bet:
guess = randint(0,6)
elif game_mode == colour_bet:
guess = choice(['blue','green'])
elif game_mode == parity_bet:
guess = choice(['even','odd'])
value = randint(1,10)
return game_mode , value, guess
class player():
# This class defines each player
def __init__(self, name, strategy, bank_roll):
self.name = name
self.strategy = strategy
self.bank_roll = bank_roll
def modify_balance(self, amount):
self.bank_roll += amount
def __str__(self):
result = "Name: {} \n" \
"Bank Roll: {}" .format(self.name, self.bank_roll)
return result
def play(self):
return self.strategy()
# Add the players
Will = player("Will",random_strategy,100)
def dealer(type, bet_value, guess):
#Roll the dice
correct = choice(options)
#Return amount based on Win or Lose
if type == num_bet.bet_type:
if correct.num == guess:
return num_bet.odds * bet_value - bet_value
else:
return -bet_value
if type == colour_bet.bet_type:
if correct.colour == guess:
return colour_bet.odds * bet_value - bet_value
else:
return -bet_value
if type == parity_bet.bet_type:
if correct.parity == guess:
return parity_bet.odds * bet_value - bet_value
else:
return -bet_value
def main_play(player):
# Collect the bets from the players
bets = player.play()
# Roll and return bets
amount = dealer(bets[0].bet_type, bets[1], bets[2])
# Distribute the money
main_broker.modify_balance(amount*-1)
player.modify_balance(amount)
print(player)
print(main_broker)
I would create a bettingtable as a broker where money is put at risk and the outcome to the dealer and players are exchanged based on the play outcome, and allow players and dealer to place bet and collect winnings. Encapsulate betting logic to the players and abstracted it from a game rules class. Each player should have a risk tolerance or game play style (lame, aggressive, cheater, etc.)
If you build this right, it shouldn't matter what the game is: dice, cards, etc. should basically play the same.

Categories