summaryrefslogtreecommitdiff
path: root/talersurvey/survey/amount.py
diff options
context:
space:
mode:
Diffstat (limited to 'talersurvey/survey/amount.py')
-rw-r--r--talersurvey/survey/amount.py74
1 files changed, 39 insertions, 35 deletions
diff --git a/talersurvey/survey/amount.py b/talersurvey/survey/amount.py
index 9a6318a..46e3446 100644
--- a/talersurvey/survey/amount.py
+++ b/talersurvey/survey/amount.py
@@ -23,43 +23,46 @@
# which might need it.
class CurrencyMismatch(Exception):
- pass
+ def __init__(self, curr1, curr2):
+ super(CurrencyMismatch, self).__init__(
+ "%s vs %s" % (curr1, curr2))
class BadFormatAmount(Exception):
def __init__(self, faulty_str):
- self.faulty_str = faulty_str
+ super(BadFormatAmount, self).__init__(
+ "Bad format amount: " + faulty_str)
class Amount:
# How many "fraction" units make one "value" unit of currency
# (Taler requires 10^8). Do not change this 'constant'.
@staticmethod
- def FRACTION():
+ def _fraction():
return 10 ** 8
@staticmethod
- def MAX_VALUE():
+ def _max_value():
return (2 ** 53) - 1
def __init__(self, currency, value=0, fraction=0):
# type: (str, int, int) -> Amount
- assert(value >= 0 and fraction >= 0)
+ assert value >= 0 and fraction >= 0
self.value = value
self.fraction = fraction
self.currency = currency
self.__normalize()
- assert(self.value <= Amount.MAX_VALUE())
+ assert self.value <= Amount._max_value()
# Normalize amount
def __normalize(self):
- if self.fraction >= Amount.FRACTION():
- self.value += int(self.fraction / Amount.FRACTION())
- self.fraction = self.fraction % Amount.FRACTION()
+ if self.fraction >= Amount._fraction():
+ self.value += int(self.fraction / Amount._fraction())
+ self.fraction = self.fraction % Amount._fraction()
# Parse a string matching the format "A:B.C"
# instantiating an amount object.
@classmethod
def parse(cls, amount_str):
- exp = '^\s*([-_*A-Za-z0-9]+):([0-9]+)\.([0-9]+)\s*$'
+ exp = r'^\s*([-_*A-Za-z0-9]+):([0-9]+)\.([0-9]+)\s*$'
import re
parsed = re.search(exp, amount_str)
if not parsed:
@@ -67,7 +70,7 @@ class Amount:
value = int(parsed.group(2))
fraction = 0
for i, digit in enumerate(parsed.group(3)):
- fraction += int(int(digit) * (Amount.FRACTION() / 10 ** (i+1)))
+ fraction += int(int(digit) * (Amount._fraction() / 10 ** (i+1)))
return cls(parsed.group(1), value, fraction)
# Comare two amounts, return:
@@ -75,16 +78,16 @@ class Amount:
# 0 if a == b
# 1 if a > b
@staticmethod
- def cmp(a, b):
- if a.currency != b.currency:
- raise CurrencyMismatch()
- if a.value == b.value:
- if a.fraction < b.fraction:
+ def cmp(am1, am2):
+ if am1.currency != am2.currency:
+ raise CurrencyMismatch(am1.currency, am2.currency)
+ if am1.value == am2.value:
+ if am1.fraction < am2.fraction:
return -1
- if a.fraction > b.fraction:
+ if am1.fraction > am2.fraction:
return 1
return 0
- if a.value < b.value:
+ if am1.value < am2.value:
return -1
return 1
@@ -94,34 +97,35 @@ class Amount:
self.fraction = fraction
# Add the given amount to this one
- def add(self, a):
- if self.currency != a.currency:
- raise CurrencyMismatch()
- self.value += a.value
- self.fraction += a.fraction
+ def add(self, amount):
+ if self.currency != amount.currency:
+ raise CurrencyMismatch(self.currency, amount.currency)
+ self.value += amount.value
+ self.fraction += amount.fraction
self.__normalize()
# Subtract passed amount from this one
- def subtract(self, a):
- if self.currency != a.currency:
- raise CurrencyMismatch()
- if self.fraction < a.fraction:
- self.fraction += Amount.FRACTION()
+ def subtract(self, amount):
+ if self.currency != amount.currency:
+ raise CurrencyMismatch(self.currency, amount.currency)
+ if self.fraction < amount.fraction:
+ self.fraction += Amount._fraction()
self.value -= 1
- if self.value < a.value:
+ if self.value < amount.value:
raise ValueError('self is lesser than amount to be subtracted')
- self.value -= a.value
- self.fraction -= a.fraction
+ self.value -= amount.value
+ self.fraction -= amount.fraction
# Dump string from this amount, will put 'ndigits' numbers
# after the dot.
def stringify(self, ndigits):
assert ndigits > 0
ret = '%s:%s.' % (self.currency, str(self.value))
- f = self.fraction
- for i in range(0, ndigits):
- ret += str(int(f / (Amount.FRACTION() / 10)))
- f = (f * 10) % (Amount.FRACTION())
+ fraction = self.fraction
+ while ndigits > 0:
+ ret += str(int(fraction / (Amount._fraction() / 10)))
+ fraction = (fraction * 10) % (Amount._fraction())
+ ndigits -= 1
return ret
# Dump the Taler-compliant 'dict' amount