T_lastname
T_lastname

Reputation: 122

Python - converting function values to int or float for comparison

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

Answers (3)

Toothpick Anemone
Toothpick Anemone

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

T_lastname
T_lastname

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

U13-Forward
U13-Forward

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

Related Questions