from decimal import Decimal class Trade: """ Represents a cryptocurrency trade, including the amount traded, total cost, and the date of trade. Provides methods to modify the trade and access various attributes. """ def __init__(self, amount: float|Decimal, total_cost: float|Decimal, date: str) -> None: """ Initialize a new Trade instance. Args: amount (Decimal): The amount of cryptocurrency traded. total_cost (Decimal): The total cost of the trade. date (str): The date of the trade, formatted as a string. """ if amount <= 0 or total_cost <= 0: raise ValueError("Amount and total cost must be > 0") self.__amount: Decimal = Decimal(amount) self.__total_cost: Decimal = Decimal(total_cost) self.__date: str = date def remove_coins(self, amount: float|Decimal) -> None: """ Reduce the amount of cryptocurrency in the trade by a specified amount. This effectively "loses" coins. The price-per-coin remains the same. Args: amount (Decimal): The amount of cryptocurrency to remove. Raises: ValueError: If the amount to remove exceeds the current amount in the trade. """ if amount > self.__amount: raise ValueError(f"Can't remove more than {self.__amount}") amount = Decimal(amount) self.__total_cost -= amount * self.price_per_coin self.__amount -= amount @property def amount(self) -> Decimal: """ Get the current amount of cryptocurrency in the trade. Returns: Decimal: The amount of cryptocurrency. """ return self.__amount @property def total_cost(self) -> Decimal: """ Get the total cost of the trade. Returns: Decimal: The total cost of the trade. """ return self.__total_cost @property def date(self) -> str: """ Get the date of the trade. Returns: str: The trade date as a string. """ return self.__date @property def price_per_coin(self) -> Decimal: """ Calculate the price per coin based on the total cost and current amount. Returns: Decimal: The price per coin. Raises: ZeroDivisionError: If the current amount is zero. """ if self.amount == 0: raise ZeroDivisionError("Price per coin cannot be calculated when the amount is zero") return self.total_cost / self.amount def __repr__(self) -> str: """ Get a string representation of the Trade instance. Returns: str: A formatted string displaying the trade details. """ return f"Trade(amount={self.amount:.2f}, price_per_coin={self.price_per_coin:.2f}, total_cost={self.total_cost:.2f}, date={self.date})"