X-Git-Url: https://wannabe.guru.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=type%2Fmoney.py;h=99637d1f23bd607c8856f4fada204b1859c51f3d;hb=532df2c5b57c7517dfb3dddd8c1358fbadf8baf3;hp=290c2c86f91a7a6da652b21e670d2579c51ba6c0;hpb=a08ca309cb5bd7971210a9247a38c9bbe376a6e6;p=python_utils.git diff --git a/type/money.py b/type/money.py index 290c2c8..99637d1 100644 --- a/type/money.py +++ b/type/money.py @@ -1,13 +1,14 @@ #!/usr/bin/env python3 -from decimal import Decimal -import re -from typing import Optional, TypeVar, Tuple +# © Copyright 2021-2022, Scott Gasch -import math_utils +"""A class to represent money. See also centcount.py""" +import re +from decimal import Decimal +from typing import Optional, Tuple -T = TypeVar('T', bound='Money') +import math_utils class Money(object): @@ -15,12 +16,12 @@ class Money(object): different currencies. """ - def __init__ ( - self, - amount: Decimal = Decimal("0"), - currency: str = 'USD', - *, - strict_mode = False + def __init__( + self, + amount: Decimal = Decimal("0"), + currency: str = 'USD', + *, + strict_mode=False, ): self.strict_mode = strict_mode if isinstance(amount, str): @@ -35,16 +36,16 @@ class Money(object): if not currency: self.currency: Optional[str] = None else: - self.currency: Optional[str] = currency + self.currency = currency def __repr__(self): a = float(self.amount) a = round(a, 2) s = f'{a:,.2f}' if self.currency is not None: - return '%s %s' % (s, self.currency) + return f'{s} {self.currency}' else: - return '$%s' % s + return f'${s}' def __pos__(self): return Money(amount=self.amount, currency=self.currency) @@ -55,10 +56,7 @@ class Money(object): def __add__(self, other): if isinstance(other, Money): if self.currency == other.currency: - return Money( - amount = self.amount + other.amount, - currency = self.currency - ) + return Money(amount=self.amount + other.amount, currency=self.currency) else: raise TypeError('Incompatible currencies in add expression') else: @@ -66,17 +64,14 @@ class Money(object): raise TypeError('In strict_mode only two moneys can be added') else: return Money( - amount = self.amount + Decimal(float(other)), - currency = self.currency + amount=self.amount + Decimal(float(other)), + currency=self.currency, ) def __sub__(self, other): if isinstance(other, Money): if self.currency == other.currency: - return Money( - amount = self.amount - other.amount, - currency = self.currency - ) + return Money(amount=self.amount - other.amount, currency=self.currency) else: raise TypeError('Incompatible currencies in add expression') else: @@ -84,8 +79,8 @@ class Money(object): raise TypeError('In strict_mode only two moneys can be added') else: return Money( - amount = self.amount - Decimal(float(other)), - currency = self.currency + amount=self.amount - Decimal(float(other)), + currency=self.currency, ) def __mul__(self, other): @@ -93,8 +88,8 @@ class Money(object): raise TypeError('can not multiply monetary quantities') else: return Money( - amount = self.amount * Decimal(float(other)), - currency = self.currency + amount=self.amount * Decimal(float(other)), + currency=self.currency, ) def __truediv__(self, other): @@ -102,8 +97,8 @@ class Money(object): raise TypeError('can not divide monetary quantities') else: return Money( - amount = self.amount / Decimal(float(other)), - currency = self.currency + amount=self.amount / Decimal(float(other)), + currency=self.currency, ) def __float__(self): @@ -124,10 +119,7 @@ class Money(object): def __rsub__(self, other): if isinstance(other, Money): if self.currency == other.currency: - return Money( - amount = other.amount - self.amount, - currency = self.currency - ) + return Money(amount=other.amount - self.amount, currency=self.currency) else: raise TypeError('Incompatible currencies in sub expression') else: @@ -135,8 +127,8 @@ class Money(object): raise TypeError('In strict_mode only two moneys can be added') else: return Money( - amount = Decimal(float(other)) - self.amount, - currency = self.currency + amount=Decimal(float(other)) - self.amount, + currency=self.currency, ) __rmul__ = __mul__ @@ -148,10 +140,7 @@ class Money(object): if other is None: return False if isinstance(other, Money): - return ( - self.amount == other.amount and - self.currency == other.currency - ) + return self.amount == other.amount and self.currency == other.currency if self.strict_mode: raise TypeError("In strict mode only two Moneys can be compared") else: @@ -193,11 +182,11 @@ class Money(object): def __ge__(self, other): return self > other or self == other - def __hash__(self): - return self.__repr__ + def __hash__(self) -> int: + return hash(self.__repr__) - AMOUNT_RE = re.compile("^([+|-]?)(\d+)(\.\d+)$") - CURRENCY_RE = re.compile("^[A-Z][A-Z][A-Z]$") + AMOUNT_RE = re.compile(r"^([+|-]?)(\d+)(\.\d+)$") + CURRENCY_RE = re.compile(r"^[A-Z][A-Z][A-Z]$") @classmethod def _parse(cls, s: str) -> Optional[Tuple[Decimal, str]]: @@ -220,7 +209,7 @@ class Money(object): return None @classmethod - def parse(cls, s: str) -> T: + def parse(cls, s: str) -> 'Money': chunks = Money._parse(s) if chunks is not None: return Money(chunks[0], chunks[1])