--- /dev/null
+import decimal
+
+class money(object):
+ def __init__(self, amount="0"):
+ try:
+ self.amount = decimal.Decimal(amount)
+ except decimal.InvalidOperation:
+ raise ValueError("amount value could not be converted to "
+ "Decimal(): '{}'".format(amount))
+
+ @property
+ def amount(self):
+ return self.amount
+
+ def __hash__(self):
+ return hash(self._amount)
+
+ def __repr__(self):
+ return "{}".format(self._amount)
+
+ def __str__(self):
+ return self.__unicode__().encode('utf-8')
+
+ def __unicode__(self):
+ return u"${:,.2f}".format(self._amount)
+
+ def __lt__(self, other):
+ if not isinstance(other, money):
+ raise InvalidOperandType(other, '<')
+ return self.amount < other.amount
+
+ def __le__(self, other):
+ if not isinstance(other, money):
+ raise InvalidOperandType(other, '<=')
+ return self._amount <= other.amount
+
+ def __eq__(self, other):
+ if isinstance(other, money):
+ return self._amount == other.amount
+ return False
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __gt__(self, other):
+ if not isinstance(other, money):
+ raise InvalidOperandType(other, '>')
+ return self._amount > other.amount
+
+ def __ge__(self, other):
+ if not isinstance(other, money):
+ raise InvalidOperandType(other, '>=')
+ return self._amount >= other.amount
+
+ def __add__(self, other):
+ if not isinstance(other, money):
+ raise InvalidOperandType(other, '+')
+ other = other.amount
+ amount = self.amount + other
+ return self.__class__(amount)
+
+ def __radd__(self, other):
+ return self.__add__(other)
+
+ def __sub__(self, other):
+ if not isinstance(other, money):
+ raise InvalidOperandType(other, '-')
+ other = other.amount
+ amount = self._amount - other
+ return self.__class__(amount)
+
+ def __rsub__(self, other):
+ return (-self).__add__(other)
+
+ def __mul__(self, other):
+ if isinstance(other, money):
+ raise TypeError("multiplication is unsupported between "
+ "two money objects")
+ amount = self._amount * other
+ return self.__class__(amount)
+
+ def __rmul__(self, other):
+ return self.__mul__(other)
+
+ def __div__(self, other):
+ return self.__truediv__(other)
+
+ def __truediv__(self, other):
+ if isinstance(other, money):
+ if other.amount == 0:
+ raise ZeroDivisionError()
+ return self.amount / other.amount
+ else:
+ if other == 0:
+ raise ZeroDivisionError()
+ amount = self.amount / other
+ return self.__class__(amount)
+
+ def __floordiv__(self, other):
+ if isinstance(other, money):
+ if other.amount == 0:
+ raise ZeroDivisionError()
+ return self._amount // other.amount
+ else:
+ if other == 0:
+ raise ZeroDivisionError()
+ amount = self.amount // other
+ return self.__class__(amount)
+
+ def __mod__(self, other):
+ if isinstance(other, money):
+ raise TypeError("modulo is unsupported between two '{}' "
+ "objects".format(self.__class__.__name__))
+ if other == 0:
+ raise ZeroDivisionError()
+ amount = self.amount % other
+ return self.__class__(amount)
+
+ def __divmod__(self, other):
+ if isinstance(other, money):
+ if other.amount == 0:
+ raise ZeroDivisionError()
+ return divmod(self._amount, other.amount)
+ else:
+ if other == 0:
+ raise ZeroDivisionError()
+ whole, remainder = divmod(self._amount, other)
+ return (self.__class__(whole),
+ self.__class__(remainder))
+
+ def __pow__(self, other):
+ if isinstance(other, money):
+ raise TypeError("power operator is unsupported between two '{}' "
+ "objects".format(self.__class__.__name__))
+ amount = self.amount ** other
+ return self.__class__(amount)
+
+ def __neg__(self):
+ return self.__class__(-self.amount)
+
+ def __pos__(self):
+ return self.__class__(+self._amount)
+
+ def __abs__(self):
+ return self.__class__(abs(self.amount))
+
+ def __int__(self):
+ return int(self.amount)
+
+ def __float__(self):
+ return float(self.amount)
+
+ def __round__(self, ndigits=0):
+ return self.__class__(round(self.amount, ndigits))