Skip to content

Commit

Permalink
Add support for dividing money by money
Browse files Browse the repository at this point in the history
It was an oversight to not include it initially
  • Loading branch information
nickyr committed Apr 10, 2017
1 parent 576fb3e commit db8493c
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 33 deletions.
59 changes: 36 additions & 23 deletions money/money.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Class representing a monetary amount"""

from typing import Union
from decimal import Decimal, ROUND_HALF_UP
from babel.numbers import format_currency
from money.currency import Currency
Expand Down Expand Up @@ -108,32 +109,44 @@ def __rmul__(self, other: float) -> 'Money':
def __div__(self, other: float) -> 'Money':
return self.__truediv__(other)

def __truediv__(self, other: float) -> 'Money':
def __truediv__(self, other: Union['Money', float]) -> Union['Money', float]:
if isinstance(other, Money):
raise InvalidOperandError
elif other == 0:
raise ZeroDivisionError

amount = self._round(self._amount / Decimal(other), self._currency)
return self.__class__(str(amount), self._currency)

def __floordiv__(self, other: float) -> 'Money':
self._assert_same_currency(other)
if other.amount == Decimal('0'):
raise ZeroDivisionError
return float(self.amount / other.amount)

else:
if other == 0:
raise ZeroDivisionError
amount = self._round(self._amount / Decimal(other), self._currency)
return self.__class__(str(amount), self._currency)

def __floordiv__(self, other: Union['Money', float]) -> Union['Money', float]:
if isinstance(other, Money):
raise InvalidOperandError
elif other == 0:
raise ZeroDivisionError

amount = self._round(self._amount // Decimal(other), self._currency)
return self.__class__(str(amount), self._currency)

def __mod__(self, other: int) -> 'Money':
self._assert_same_currency(other)
if other.amount == Decimal('0'):
raise ZeroDivisionError
return float(self.amount // other.amount)

else:
if other == 0:
raise ZeroDivisionError
amount = self._round(self._amount // Decimal(other), self._currency)
return self.__class__(str(amount), self._currency)

def __mod__(self, other: Union['Money', float]) -> Union['Money', float]:
if isinstance(other, Money):
raise InvalidOperandError
elif other == 0:
raise ZeroDivisionError

amount = self._round(self._amount % Decimal(other), self._currency)
return self.__class__(str(amount), self._currency)
self._assert_same_currency(other)
if other.amount == Decimal('0'):
raise ZeroDivisionError
return float(self.amount % other.amount)

else:
if other == 0:
raise ZeroDivisionError
amount = self._round(self._amount % Decimal(other), self._currency)
return self.__class__(str(amount), self._currency)

def __neg__(self) -> 'Money':
return self.__class__(str(-self._amount), self._currency)
Expand Down
33 changes: 24 additions & 9 deletions money/tests/test_money.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,7 @@ def test_divide(self):
assert Money('3.3') / 3 == Money('1.1')
assert Money('9.95') / 0.24 == Money('41.46')
assert Money('3', Currency.JPY) / 1.6 == Money('2', Currency.JPY)

with pytest.raises(InvalidOperandError):
Money('5.5') / Money('1.2')
assert Money('3.6') / Money('2.5') == 1.44

with pytest.raises(TypeError):
3 / Money('5.5')
Expand All @@ -173,33 +171,50 @@ def test_divide(self):
with pytest.raises(ZeroDivisionError):
Money('3.3') / 0.0

with pytest.raises(ZeroDivisionError):
Money('3.3') / Money('0')

with pytest.raises(CurrencyMismatchError):
Money('3.5', Currency.EUR) / Money('1.8', Currency.GBP)

def test_floor_divide(self):
assert Money('3.3') // 3 == Money('1')
assert Money('9.95') // 0.24 == Money('41')
assert Money('3', Currency.JPY) // 1.6 == Money('1', Currency.JPY)

with pytest.raises(InvalidOperandError):
Money('5.5') // Money('1.2')
assert Money('3.6') // Money('2.5') == 1

with pytest.raises(TypeError):
3 // Money('5.5')

with pytest.raises(ZeroDivisionError):
Money('3') // 0

with pytest.raises(ZeroDivisionError):
Money('3.3') // 0.0

with pytest.raises(ZeroDivisionError):
Money('3.3') // Money('0')

with pytest.raises(CurrencyMismatchError):
Money('3.5', Currency.EUR) // Money('1.8', Currency.GBP)

def test_mod(self):
assert Money('3.3') % 3 == Money('0.3')
assert Money('3', Currency.JPY) % 2 == Money('1', Currency.JPY)

with pytest.raises(InvalidOperandError):
Money('5.5') % Money('1.2')
assert Money('3') % Money('2') == 1

with pytest.raises(TypeError):
3 % Money('5.5')

with pytest.raises(ZeroDivisionError):
Money('3.3') % 0

with pytest.raises(ZeroDivisionError):
Money('3.3') % 0.0

with pytest.raises(CurrencyMismatchError):
Money('3.5', Currency.EUR) % Money('1.8', Currency.GBP)

def test_neg(self):
assert -Money('5.23') == Money('-5.23')
assert -Money('-1.35') == Money('1.35')
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
packages=[
'money'
],
version='0.1.1',
version='0.2.0',
description='Money module for python',
long_description=long_description,
url='https://github.com/vimeo/py-money',
Expand Down

0 comments on commit db8493c

Please sign in to comment.