Reputation: 122
So essentially, I'm simulating a cash box, where I take in coins and build a user credit, then when the user requests to buy an item I check to make sure they have enough credit for that item.
The problem I'm running into is that when I get to the haveYou function, and I try and compare the two values price and credit In the current version of the code, self.price is just set to 35 in CashBox.init, so that the if statements in Selector.select() work properly.
If I include self.price = 0 in the init function, it keeps that value and says that credit and price are equal, therefore it continues if I try return self.credit >= self.price, referencing the return from the getPrice method, it says I can't compare an int to a function value. I've checked and it's definitely the self.price that is the issue.
So my question is, how do I convert the function value to int, or set the return of getPrice to be an int to begin with? I've looked but the internet is so saturated with int to float to string stuff, I couldn't find anything about this. I'm at about 5 hours of banging my head on my desk on this one, help is much appreciated. Thank you
import time
import sys
class CashBox(object):
def __init__(self):
self.credit = 0
self.totalReceived = 0
#self.price = 35
def deposit(self,amount):
self.credit = amount + self.credit
self.totalReceived = amount + self.totalReceived
print(self.credit)
print(type(self.credit))
return self.credit
def returnCoins(self):
print("Returning ", self.credit/100, " dollars.")
self.totalReceived = 0
def haveYou(self,amount):
price = Product.getPrice
return self.credit >= price
def deduct(self,amount):
pass
def totalCoins(self):
return self.totalReceived
class CoffeeMachine(object):
def __init__(self):
self.cashBox = CashBox()
self.credit = CashBox.__init__
self.selector = self.cashBox
def oneAction(self):
while True:
command = input("""
______________________________________________________
PRODUCT LIST: all 35 cents, except bouillon (25 cents)
1=black, 2=white, 3=sweet, 4=sweet & white, 5=bouillon
Sample Commands: insert 25, select 1, cancel, quit.
Your command:
""")
words = command.lower().split()
if 'select' in words:
Selector.select(self,int(words[1]))
elif 'insert' in words:
coinsAllowed = [5,10,25,50]
if int(words[1]) in coinsAllowed:
self.cashBox.deposit(int(words[1]))
else:
print("""
That is not one of the allowed coins,
please insert a penny, nickel, dime, quarter,
or half-dollar. Thank you.
""")
elif 'cancel' in words:
print("Cancelling transaction. Returning to main menu: ")
self.cashBox.returnCoins()
elif 'quit' in words:
print("Have a nice day!")
break
else:
print("That is not an option")
def totalCash(self):
return self.cashBox.totalReceived
class Product(object):
def __init__(self,name,price,recipe):
self.name = name
self.price = price
self.recipe = recipe
def getPrice(self):
return self.price
def make(self):
for item in self.recipe:
print("dispensing", item)
time.sleep(0.5)
print("Enjoy your", self.name)
time.sleep(0.5)
print(self.price)
class Selector(object):
def __init__(self):
#self.Product = Product()
self.cashBox = CashBox()
self.credit = CashBox.deposit
#self.products.append(Product.
def select(self, choiceIndex):
recipes = {
1 : ["Black coffee",35,["cup", "coffee", "water"]],
2 : ["White coffee",35,["cup", "coffee", "creamer", "water"]],
3 : ["Sweet coffee",35,["cup", "coffee", "sugar", "water"]],
4 : ["White & Sweet coffee",35,["cup", "coffee", "sugar", "creamer", "water"]],
5 : ["Bouillon",25,["cup bouillonPowder", "water"]]
}
if choiceIndex in range(1,len(recipes)+1):
if self.cashBox.haveYou(self.credit) == True:
self.choiceIndex = choiceIndex
self.recipe = recipes.get(choiceIndex)
#print(self.recipe,"Great selection")
product = Product(*self.recipe)
price = CashBox.haveYou(*self.recipe)
product.make()
else:
print("You don't have enough credit for that, please insert more money.")
else:
print("That selection does not exist")
def main():
m = CoffeeMachine()
while m.oneAction():
pass
total = m.totalCash()
print(f"Total Cash: ${total/100:.2f}")
if __name__ == "__main__":
Depending on what I'm trying: Uncomment self.price = 35
Exception has occurred: AttributeError
'int' object has no attribute 'price'
File "C:\Users\Tanner Harmer\Desktop\Coffee2\CashBox.py", line 81, in getPrice
return self.price
File "C:\Users\Tanner Harmer\Desktop\Coffee2\CashBox.py", line 22, in haveYou
price = Product.getPrice(self.price) + self.price
File "C:\Users\Tanner Harmer\Desktop\Coffee2\CashBox.py", line 108, in select
if self.cashBox.haveYou(self.credit) == True:
File "C:\Users\Tanner Harmer\Desktop\Coffee2\CashBox.py", line 50, in oneAction
Selector.select(self,int(words[1]))
File "C:\Users\Tanner Harmer\Desktop\Coffee2\CashBox.py", line 122, in main
while m.oneAction():
File "C:\Users\Tanner Harmer\Desktop\Coffee2\CashBox.py", line 128, in <module>
main()
or if in haveYou I use
price = Product.getPrice
return self.credit >= price
Exception has occurred: TypeError
'>=' not supported between instances of 'int' and 'function'
File "C:\Users\Tanner Harmer\Desktop\Coffee2\CashBox.py", line 23, in haveYou
return self.credit >= price
File "C:\Users\Tanner Harmer\Desktop\Coffee2\CashBox.py", line 108, in select
if self.cashBox.haveYou(self.credit) == True:
File "C:\Users\Tanner Harmer\Desktop\Coffee2\CashBox.py", line 50, in oneAction
Selector.select(self,int(words[1]))
File "C:\Users\Tanner Harmer\Desktop\Coffee2\CashBox.py", line 122, in main
while m.oneAction():
File "C:\Users\Tanner Harmer\Desktop\Coffee2\CashBox.py", line 128, in <module>
main()
Upvotes: 2
Views: 183
Reputation: 4644
If exactness is key (as it often is in finance) never use floating point numbers. Instead, I recommend that you store currencies as integers written in terms of number of pennies.
For example, if someone's bank account balance is $1,343.98 then you store that as exactly 134,398 pennies. Whenever you cast the object to string, it gets a nice little decimal point.
import math
class PecuniaryPurse:
currency_codes = frozenset((
"EUR", "USD", "GBP", "JPY", "CHF",
"AUD", "CAD"
))
@classmethod
def to_int(cls, amount):
if isinstance(amount, cls):
_amount_int = amount._amount
else:
_amount_flt = float(str(amount))
_amount_int = int(amount)
if not math.isclose(amount, _amount_flt):
raise ValueError()
return _amount_int
def __init__(self, currency_code, _amount = 0):
try:
assert (currency_code in self.currency_codes)
self._currency_code = currency_code
self._amount = type(self).to_int(_amount)
finally:
pass
def __str__(self):
return ''.join(str(x) for x in (
self._currency_code,
" ",
str(self._amount // 100),
".",
str(self._amount % 100)
))
def __add__(self, other):
if isinstance(other, type(self)):
assert(self._currency_code == other._currency_code)
return type(self)(self._currency_code, self._amount + other._amount)
else:
other = type(self).to_int(other)
return type(self)(self._currency_code, self._amount + other)
PP = PecuniaryPurse
p = PP("USD", 1234) + PP("USD", 99)
print(p) # USD 13.33
Upvotes: 1
Reputation: 122
import time
import sys
class CashBox(object):
def __init__(self):
self.credit = 0
self.totalReceived = 0
#self.price = 35
def deposit(self,amount):
self.credit = amount + self.credit
self.totalReceived = amount + self.totalReceived
print(self.credit)
print(type(self.credit))
return self.credit
def returnCoins(self):
print("Returning ", self.credit/100, " dollars.")
self.totalReceived = 0
def haveYou(self,name,price,recipe):
return self.credit >= price
def deduct(self,amount):
pass
def totalCoins(self):
return self.totalReceived
class CoffeeMachine(object):
def __init__(self):
self.cashBox = CashBox()
self.credit = CashBox.__init__
self.selector = self.cashBox
def oneAction(self):
while True:
command = input("""
______________________________________________________
PRODUCT LIST: all 35 cents, except bouillon (25 cents)
1=black, 2=white, 3=sweet, 4=sweet & white, 5=bouillon
Sample Commands: insert 25, select 1, cancel, quit.
Your command:
""")
words = command.lower().split()
if 'select' in words:
Selector.select(self,int(words[1]))
elif 'insert' in words:
coinsAllowed = [5,10,25,50]
if int(words[1]) in coinsAllowed:
self.cashBox.deposit(int(words[1]))
else:
print("""
That is not one of the allowed coins,
please insert a penny, nickel, dime, quarter,
or half-dollar. Thank you.
""")
elif 'cancel' in words:
print("Cancelling transaction. Returning to main menu: ")
self.cashBox.returnCoins()
elif 'quit' in words:
print("Have a nice day!")
break
else:
print("That is not an option")
def totalCash(self):
return self.cashBox.totalReceived
class Product(object):
def __init__(self,name,price,recipe):
self.name = name
self.price = price
self.recipe = recipe
def getPrice(self):
return self.price
def make(self):
for item in self.recipe:
print("dispensing", item)
time.sleep(0.5)
print("Enjoy your", self.name)
time.sleep(0.5)
print(self.price)
class Selector(object):
def __init__(self):
#self.Product = Product()
self.cashBox = CashBox()
self.credit = CashBox.deposit
#self.products.append(Product.
def select(self, choiceIndex):
recipes = {
1 : ["Black coffee",35,["cup", "coffee", "water"]],
2 : ["White coffee",35,["cup", "coffee", "creamer", "water"]],
3 : ["Sweet coffee",35,["cup", "coffee", "sugar", "water"]],
4 : ["White & Sweet coffee",35,["cup", "coffee", "sugar", "creamer", "water"]],
5 : ["Bouillon",25,["cup bouillonPowder", "water"]]
}
if choiceIndex in range(1,len(recipes)+1):
self.choiceIndex = choiceIndex
self.recipe = recipes.get(choiceIndex)
product = Product(*self.recipe)
if self.cashBox.haveYou(*self.recipe) == True:
#print(self.recipe,"Great selection")
#price = CashBox.haveYou(*self.recipe)
product.make()
else:
print("You don't have enough credit for that, please insert more money.")
else:
print("That selection does not exist")
def main():
m = CoffeeMachine()
while m.oneAction():
pass
total = m.totalCash()
print(f"Total Cash: ${total/100:.2f}")
if __name__ == "__main__":
main()
Upvotes: 0
Reputation: 71570
You need to add ()
at the end to actually get the value.
So instead of:
price = Product.getPrice
return self.credit >= price
Use:
price = Product(<Here put the 3 values that this class needs>).getPrice()
return self.credit >= price
Upvotes: 3