170 lines
5.9 KiB
Python
170 lines
5.9 KiB
Python
class item:
|
|
def __init__(self, name: str, price: float, quantity=0):
|
|
# Run validations to the received arguments
|
|
assert price >= 0, f"Price {price} is not greater than or equal to zero!"
|
|
assert quantity >= 0, f"Quantity {quantity} is not greater than or equal to zero!"
|
|
|
|
# Assign to self object
|
|
self.name = name
|
|
self.price = price
|
|
self.quantity = quantity
|
|
|
|
def calculate_total_price(self):
|
|
return self.price * self.quantity
|
|
|
|
def apply_discount(self, discount):
|
|
self.price = self.price * (1 - discount)
|
|
assert self.price >= 0, f"Price {self.price} is not greater than or equal to zero!"
|
|
return self.price
|
|
|
|
def __repr__(self):
|
|
return f"item('{self.name}', {self.price}, {self.quantity})"
|
|
|
|
def __str__(self):
|
|
return f"Item: {self.name}, Price: {self.price}, Quantity: {self.quantity}"
|
|
|
|
@property
|
|
def name(self):
|
|
return self._name
|
|
|
|
@property
|
|
def price(self):
|
|
return self._price
|
|
|
|
@property
|
|
def quantity(self):
|
|
return self._quantity
|
|
@name.setter
|
|
def name(self, value):
|
|
if len(value) > 10:
|
|
raise Exception("The name is too long!")
|
|
else:
|
|
self._name = value
|
|
|
|
@price.setter
|
|
def price(self, value):
|
|
if value < 0:
|
|
raise Exception("Price cannot be negative!")
|
|
else:
|
|
self._price = value
|
|
|
|
@quantity.setter
|
|
def quantity(self, value):
|
|
if value < 0:
|
|
raise Exception("Quantity cannot be negative!")
|
|
else:
|
|
self._quantity = value
|
|
|
|
@classmethod
|
|
def instantiate_from_csv(cls, filename):
|
|
import csv
|
|
with open(filename, 'r') as f:
|
|
reader = csv.DictReader(f)
|
|
items = list(reader)
|
|
for item in items:
|
|
item['price'] = float(item['price'])
|
|
item['quantity'] = int(item['quantity'])
|
|
return [cls(**item) for item in items]
|
|
@staticmethod
|
|
def is_integer(num):
|
|
# We will count out the floats that are point zero
|
|
if isinstance(num, float):
|
|
# Count out the floats that are point zero
|
|
return num.is_integer()
|
|
elif isinstance(num, int):
|
|
return True
|
|
else:
|
|
return False
|
|
def __add__(self, other):
|
|
if isinstance(other, item):
|
|
return self.quantity + other.quantity
|
|
else:
|
|
raise Exception("You cannot add these two objects")
|
|
def __radd__(self, other):
|
|
return self.__add__(other)
|
|
def __mul__(self, other):
|
|
if isinstance(other, (int, float)):
|
|
return self.price * other
|
|
else:
|
|
raise Exception("You cannot multiply these two objects")
|
|
def __rmul__(self, other):
|
|
return self.__mul__(other)
|
|
def __eq__(self, other):
|
|
if isinstance(other, item):
|
|
return self.price == other.price and self.quantity == other.quantity
|
|
else:
|
|
return False
|
|
def __lt__(self, other):
|
|
if isinstance(other, item):
|
|
return self.price < other.price
|
|
else:
|
|
raise Exception("You cannot compare these two objects")
|
|
def __le__(self, other):
|
|
if isinstance(other, item):
|
|
return self.price <= other.price
|
|
else:
|
|
raise Exception("You cannot compare these two objects")
|
|
def __gt__(self, other):
|
|
if isinstance(other, item):
|
|
return self.price > other.price
|
|
else:
|
|
raise Exception("You cannot compare these two objects")
|
|
def __ge__(self, other):
|
|
if isinstance(other, item):
|
|
return self.price >= other.price
|
|
else:
|
|
raise Exception("You cannot compare these two objects")
|
|
|
|
def __ne__(self, other):
|
|
if isinstance(other, item):
|
|
return self.price != other.price or self.quantity != other.quantity
|
|
else:
|
|
return True
|
|
def __hash__(self):
|
|
return hash((self.name, self.price, self.quantity))
|
|
def __bool__(self):
|
|
return self.quantity > 0
|
|
def __len__(self):
|
|
return len(self.name)
|
|
def __getitem__(self, index):
|
|
return self.name[index]
|
|
def __setitem__(self, index, value):
|
|
name_list = list(self.name)
|
|
name_list[index] = value
|
|
self.name = ''.join(name_list)
|
|
def __delitem__(self, index):
|
|
name_list = list(self.name)
|
|
del name_list[index]
|
|
self.name = ''.join(name_list)
|
|
def __contains__(self, item):
|
|
return item in self.name
|
|
def __dir__(self):
|
|
return ['name', 'price', 'quantity', 'calculate_total_price', 'apply_discount', 'instantiate_from_csv', 'is_integer']
|
|
def __format__(self, format_spec):
|
|
if format_spec == 'name':
|
|
return self.name
|
|
elif format_spec == 'price':
|
|
return f"{self.price:.2f}"
|
|
elif format_spec == 'quantity':
|
|
return str(self.quantity)
|
|
else:
|
|
return str(self)
|
|
def __getstate__(self):
|
|
return self.__dict__
|
|
def __setstate__(self, state):
|
|
self.__dict__.update(state)
|
|
def __copy__(self):
|
|
return item(self.name, self.price, self.quantity)
|
|
def __deepcopy__(self, memo):
|
|
from copy import deepcopy
|
|
return item(deepcopy(self.name, memo), deepcopy(self.price, memo), deepcopy(self.quantity, memo))
|
|
def __reversed__(self):
|
|
return item(self.name[::-1], self.price, self.quantity)
|
|
# The following methods are already defined above, so they should not be duplicated.
|
|
# Remove the duplicate definitions to avoid syntax errors and keep only one implementation.
|
|
|
|
# (No code needed here, as the correct implementations are already present earlier in the class.)
|
|
example = item("Example", 10.0, 5)
|
|
print(example) # Output: Item: Example, Price: 10.0, Quantity: 5
|
|
print(repr(example)) # Output: item('Example', 10.0, 5)
|
|
print(example.calculate_total_price()) # Output: 50.0 |