summaryrefslogtreecommitdiff
path: root/taler
diff options
context:
space:
mode:
authorng0 <ng0@n0.is>2019-09-25 12:39:40 +0000
committerng0 <ng0@n0.is>2019-09-25 12:39:40 +0000
commit27f60dc812b3d4d05fd11b107cab6c905c57b0d8 (patch)
treee968593286f450cd21638e989813e8e87dda7fcf /taler
parent56aca5d9367815ff4a4e690eea2347f256e6743c (diff)
downloadtaler-util-27f60dc812b3d4d05fd11b107cab6c905c57b0d8.tar.gz
taler-util-27f60dc812b3d4d05fd11b107cab6c905c57b0d8.tar.bz2
taler-util-27f60dc812b3d4d05fd11b107cab6c905c57b0d8.zip
taler.util.amount: Add changes from bank.git
Diffstat (limited to 'taler')
-rw-r--r--taler/util/amount.py113
1 files changed, 90 insertions, 23 deletions
diff --git a/taler/util/amount.py b/taler/util/amount.py
index f17de37..5434cf2 100644
--- a/taler/util/amount.py
+++ b/taler/util/amount.py
@@ -24,42 +24,79 @@
# mentioned above, and it is meant to be manually copied into
# any project which might need it.
+
+##
+# Exception class to raise when an operation between two
+# amounts of different currency is being attempted.
class CurrencyMismatch(Exception):
hint = "Internal logic error (currency mismatch)"
http_status_code = 500
+
+ ##
+ # Init constructor.
+ #
+ # @param self the object itself.
+ # @param curr1 first currency involved in the operation.
+ # @param curr2 second currency involved in the operation.
def __init__(self, curr1, curr2) -> None:
- super(CurrencyMismatch, self).__init__(
- "%s vs %s" % (curr1, curr2))
+ super(CurrencyMismatch, self).__init__("%s vs %s" % (curr1, curr2))
+
+##
+# Exception class to raise when a amount string is not valid.
class BadFormatAmount(Exception):
+
hint = "Malformed amount string"
+
+ ##
+ # Init constructor.
+ #
+ # @param self the object itself.
+ # @param faulty_str the invalid amount string.
def __init__(self, faulty_str) -> None:
- super(BadFormatAmount, self).__init__(
- "Bad format amount: " + faulty_str)
+ super(BadFormatAmount,
+ self).__init__("Bad format amount: " + faulty_str)
+
+##
+# Main Amount class.
class NumberTooBig(Exception):
hint = "Number given is too big"
+
def __init__(self) -> None:
- super(NumberTooBig, self).__init__(
- "Number given is too big")
+ super(NumberTooBig, self).__init__("Number given is too big")
+
class NegativeNumber(Exception):
hint = "Negative number given as value and/or fraction"
+
def __init__(self) -> None:
- super(NegativeNumber, self).__init__(
- "Negative number given as value and/or fraction")
+ super(NegativeNumber,
+ self).__init__("Negative number given as value and/or fraction")
+
class Amount:
+ ##
# How many "fraction" units make one "value" unit of currency
# (Taler requires 10^8). Do not change this 'constant'.
@staticmethod
def _fraction() -> int:
- return 10 ** 8
+ return 10**8
+ ##
+ # Max value admitted: 2^53 - 1. This constant is dictated
+ # by the wallet: JavaScript does not go beyond this value.
@staticmethod
def _max_value() -> int:
- return (2 ** 53) - 1
+ return (2**53) - 1
+ ##
+ # Init constructor.
+ #
+ # @param self the object itself.
+ # @param currency the amount's currency.
+ # @param value integer part the amount
+ # @param fraction fractional part of the amount
def __init__(self, currency, value=0, fraction=0) -> None:
if value < 0 or fraction < 0:
raise NegativeNumber()
@@ -70,14 +107,21 @@ class Amount:
if self.value > Amount._max_value():
raise NumberTooBig()
- # Normalize amount
+ ##
+ # Normalize amount. It means it makes sure that the
+ # fractional part is less than one unit, and transfers
+ # the overhead to the integer part.
def __normalize(self) -> None:
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"
+ ##
+ # Parse a string matching the format "A:B.C",
# instantiating an amount object.
+ #
+ # @param cls unused.
+ # @param amount_str the stringified amount to parse.
@classmethod
def parse(cls, amount_str: str):
exp = r'^\s*([-_*A-Za-z0-9]+):([0-9]+)\.?([0-9]+)?\s*$'
@@ -88,13 +132,17 @@ class Amount:
value = int(parsed.group(2))
fraction = 0
for i, digit in enumerate(parsed.group(3) or "0"):
- 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:
- # -1 if a < b
- # 0 if a == b
- # 1 if a > b
+ ##
+ # Compare two amounts.
+ #
+ # @param am1 first amount to compare.
+ # @param am2 second amount to compare.
+ # @return -1 if a < b
+ # 0 if a == b
+ # 1 if a > b
@staticmethod
def cmp(am1, am2) -> int:
if am1.currency != am2.currency:
@@ -109,12 +157,23 @@ class Amount:
return -1
return 1
+ ##
+ # Setter method for the current object.
+ #
+ # @param self the object itself.
+ # @param currency the currency to set.
+ # @param value the value to set.
+ # @param fraction the fraction to set.
def set(self, currency: str, value=0, fraction=0) -> None:
self.currency = currency
self.value = value
self.fraction = fraction
- # Add the given amount to this one
+ ##
+ # Add the given amount to this one.
+ #
+ # @param self the object itself.
+ # @param amount the amount to add to this one.
def add(self, amount) -> None:
if self.currency != amount.currency:
raise CurrencyMismatch(self.currency, amount.currency)
@@ -122,7 +181,11 @@ class Amount:
self.fraction += amount.fraction
self.__normalize()
- # Subtract passed amount from this one
+ ##
+ # Subtract amount from this one.
+ #
+ # @param self this object.
+ # @param amount the amount to subtract to this one.
def subtract(self, amount) -> None:
if self.currency != amount.currency:
raise CurrencyMismatch(self.currency, amount.currency)
@@ -149,8 +212,12 @@ class Amount:
return "%s:%d.%s" % (self.currency, self.value, fraction_str)
return "%d.%s %s" % (self.value, fraction_str, self.currency)
- # Dump the Taler-compliant 'dict' amount
+ ##
+ # Dump the Taler-compliant 'dict' amount from
+ # this object.
+ #
+ # @param self this object.
def dump(self) -> dict:
- return dict(value=self.value,
- fraction=self.fraction,
- currency=self.currency)
+ return dict(
+ value=self.value, fraction=self.fraction, currency=self.currency
+ )