gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-survey] branch master updated: forgotten piece


From: gnunet
Subject: [GNUnet-SVN] [taler-survey] branch master updated: forgotten piece
Date: Thu, 23 Nov 2017 16:22:48 +0100

This is an automated email from the git hooks/post-receive script.

marcello pushed a commit to branch master
in repository survey.

The following commit(s) were added to refs/heads/master by this push:
     new 2303e4f  forgotten piece
2303e4f is described below

commit 2303e4f4d8e700a098a52dd9a1408476ef120944
Author: Marcello Stanisci <address@hidden>
AuthorDate: Thu Nov 23 16:22:33 2017 +0100

    forgotten piece
---
 talersurvey/survey/amount.py | 131 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 131 insertions(+)

diff --git a/talersurvey/survey/amount.py b/talersurvey/survey/amount.py
new file mode 100644
index 0000000..9a6318a
--- /dev/null
+++ b/talersurvey/survey/amount.py
@@ -0,0 +1,131 @@
+#  This file is part of TALER
+#  (C) 2017 TALER SYSTEMS
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License, or (at your option) any later version.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  
USA
+#
+#  @author Marcello Stanisci
+#  @version 0.1
+#  @repository https://git.taler.net/copylib.git/
+#  This code is "copylib", it is versioned under the Git repository
+#  mentioned above, and it is meant to be manually copied into any project
+#  which might need it.
+
+class CurrencyMismatch(Exception):
+    pass
+
+class BadFormatAmount(Exception):
+    def __init__(self, faulty_str):
+        self.faulty_str = 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():
+        return 10 ** 8
+
+    @staticmethod
+    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)
+        self.value = value
+        self.fraction = fraction
+        self.currency = currency
+        self.__normalize()
+        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()
+
+    # 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*$'
+        import re
+        parsed = re.search(exp, amount_str)
+        if not parsed:
+            raise BadFormatAmount(amount_str)
+        value = int(parsed.group(2))
+        fraction = 0
+        for i, digit in enumerate(parsed.group(3)):
+            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
+    @staticmethod
+    def cmp(a, b):
+        if a.currency != b.currency:
+            raise CurrencyMismatch()
+        if a.value == b.value:
+            if a.fraction < b.fraction:
+                return -1
+            if a.fraction > b.fraction:
+                return 1
+            return 0
+        if a.value < b.value:
+            return -1
+        return 1
+
+    def set(self, currency, value=0, fraction=0):
+        self.currency = currency
+        self.value = value
+        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
+        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()
+            self.value -= 1
+        if self.value < a.value:
+            raise ValueError('self is lesser than amount to be subtracted')
+        self.value -= a.value
+        self.fraction -= a.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())
+        return ret
+
+    # Dump the Taler-compliant 'dict' amount
+    def dump(self):
+        return dict(value=self.value,
+                    fraction=self.fraction,
+                    currency=self.currency)

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]