Projects/item_class.py
2025-09-12 20:37:36 -07:00

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