I need this function to take the following
mycounter = Counter("C001")
mycounter.add("Spaghetti", 5, 1.8)
mycounter.status()
The above will return this C001 5 9.0, which is correct but I need to be 9.00 and I need to be a float. Python will righly write only one digit after the floating point like 9.0, but because this is a price it needs to be 9.00
it will be checked by the following:
assert mycounter.status()=="C001 5 9.00"
class Counter:
id : str
_items: dict
def __init__(self, ID: str):
'''creates a new counter with a given ID'''
self.id = ID
self._items={}
#dict[str, list[int, float]]
def add(self, item_name: str, amount: int, price_of_unit: float)-> None:
'''Adds amount of items with item_name and specifies price_of_unit. You can assume that every addition for the same item_name will have the same price_of_unit.'''
# price_of_unit = f"{price_of_unit:.2f}"
# float(price_of_unit)
if item_name not in self._items:
self._items[item_name]=[amount,price_of_unit]
else:
self._items[item_name][0]=self._items[item_name][0] amount
#self._items[item_name]=[amount,price_of_unit]
return self._items
def remove(self, item_name: str, amount: int)->None:
'''Removes the given amount of items with the given item name.'''
self._items[item_name][0]=self._items[item_name][0]-amount
# return self._items
def reset(self):
'''Removes all the records of items previously added.'''
self._items={}
# return self._items
def get_total(self)-> float:
'''Returns the total sum rounded to two digits after decimal point .'''
total_sum=0.0
for x in self._items:
total_sum= total_sum self._items[x][0]*self._items[x][1]
# total_sum= round(total_sum,2)
return total_sum
def status(self)-> str:
'''Returs string of form "Id N M", where Id is id of counter, N is total amount of all items and M total price of them rounded to two digits after decimal point (with both digits printed).'''
total_items=0
for x in self._items:
total_items= total_items self._items[x][0]
my_string =f"{self.id} {total_items} {Counter.get_total(self)}"
print (my_string)
CodePudding user response:
Customized round function as you need
from decimal import Decimal
def custom_round(num, digits=2, Isstr=False):
tmp = Decimal(num)
x = ("{0:.%sf}" % digits).format(round(tmp, digits))
if Isstr:
return x
return Decimal(x)
print(custom_round(13.0)) // 13.00
CodePudding user response:
Currencies should never be stored as floats, because floating point errors can cause real errors with real money. Store them as an integer number of cents, then add the decimal point when you go to display them.
Assuming you switch over to integer cents, you can display this as a currency using this piece of code:
cents_string = f'{Counter.get_total(self):0>3}'
my_string = f" ... ${cents_string[:-2]}.{cents_string[-2:]}"
If you insist on using a float, you can use float formatting inside your f-string to make it always display to exactly 2 decimal places, but again this is really not good practice.
my_string =f" ... ${Counter.get_total(self):.2f}"