diff --git a/src/sakia/money/__init__.py b/src/sakia/money/__init__.py index 05a4b506a6ff4f03c503992f6cae11774a6a4ab1..15787674543d94c189a52e24fbc08ec0c1a09eb1 100644 --- a/src/sakia/money/__init__.py +++ b/src/sakia/money/__init__.py @@ -2,5 +2,12 @@ from .quantitative import Quantitative from .relative import Relative from .quant_zerosum import QuantitativeZSum from .relative_zerosum import RelativeZSum +from .percent_of_average import PercentOfAverage -Referentials = (Quantitative, Relative, QuantitativeZSum, RelativeZSum) +Referentials = ( + Quantitative, + Relative, + PercentOfAverage, + QuantitativeZSum, + RelativeZSum, +) diff --git a/src/sakia/money/base_referential.py b/src/sakia/money/base_referential.py index e990857429a2251cc84ed02413bdb9cf54a5412b..641803434a8eed287da508be744d235a1f453268 100644 --- a/src/sakia/money/base_referential.py +++ b/src/sakia/money/base_referential.py @@ -1,15 +1,21 @@ +from typing import Optional + + class BaseReferential: """ Interface to all referentials """ - def __init__(self, amount, currency, app, block_number=None): + def __init__( + self, amount: float, currency: str, app, block_number: Optional[int] = None + ): """ + Init base referential instance - :param int amount: - :param str currency: - :param sakia.app.Application app: - :param int block_number: + :param amount: Amount to transform + :param currency: Name of currency + :param app: Application instance + :param block_number: Block number """ self.amount = amount self.app = app diff --git a/src/sakia/money/percent_of_average.py b/src/sakia/money/percent_of_average.py new file mode 100644 index 0000000000000000000000000000000000000000..2f33c43ceb193ac777b44648d0097abf1454d947 --- /dev/null +++ b/src/sakia/money/percent_of_average.py @@ -0,0 +1,131 @@ +from typing import Optional + +from .base_referential import BaseReferential +from ..data.processors import BlockchainProcessor + +from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QLocale + + +class PercentOfAverage(BaseReferential): + _NAME_STR_ = QT_TRANSLATE_NOOP("PercentOfAverage", "PoA") + _REF_STR_ = QT_TRANSLATE_NOOP("PercentOfAverage", "{0} {1}{2}") + _UNITS_STR_ = QT_TRANSLATE_NOOP("PercentOfAverage", "PoA") + _FORMULA_STR_ = QT_TRANSLATE_NOOP( + "PercentOfAverage", + """PoA = (Q / ( M(t-1) / N)) / 100 + <br > + <table> + <tr><td>PoA</td><td>Percent of Average value</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>M</td><td>Monetary mass</td></tr> + <tr><td>N</td><td>Members count</td></tr> + </table>""", + ) + _DESCRIPTION_STR_ = QT_TRANSLATE_NOOP( + "PercentOfAverage", + """Percent of Average referential of the money.<br /> + Percent of Average value PoA is calculated by dividing the quantitative value Q by the average<br /> + then multiply by one hundred.<br /> + This referential is relative and more reliable to display prices and accounts, when UD is two low.<br /> + No money creation or destruction is apparent here and every account tend to<br /> + the average. + """, + ) + + def __init__(self, amount, currency, app, block_number=None): + super().__init__(amount, currency, app, block_number) + self._blockchain_processor = BlockchainProcessor.instanciate(self.app) + + @classmethod + def instance( + cls, amount: float, currency: str, app, block_number: Optional[int] = None + ): + """ + Init PercentOfAverage referential instance + + :param amount: Amount to transform + :param currency: Name of currency + :param app: Application instance + :param block_number: Block number + :return: + """ + return cls(amount, currency, app, block_number) + + @classmethod + def translated_name(cls): + return QCoreApplication.translate( + "PercentOfAverage", PercentOfAverage._NAME_STR_ + ) + + @property + def units(self): + return QCoreApplication.translate( + "PercentOfAverage", PercentOfAverage._UNITS_STR_ + ) + + @property + def formula(self): + return QCoreApplication.translate( + "PercentOfAverage", PercentOfAverage._FORMULA_STR_ + ) + + @property + def description(self): + return QCoreApplication.translate( + "PercentOfAverage", PercentOfAverage._DESCRIPTION_STR_ + ) + + @property + def diff_units(self): + return self.units + + @staticmethod + def base_str(base): + return "" + + def value(self): + """ + Return relative value of amount + + value = amount / UD(t) + + :param int amount: Value + :param sakia.core.community.Community community: Community instance + :return: float + """ + mass = self._blockchain_processor.last_mass(self.currency) + members = self._blockchain_processor.last_members_count(self.currency) + average = mass / members + if average > 0: + return self.amount / average * 100 + else: + return self.amount + + def differential(self): + return self.value() + + def localized(self, units=False, show_base=False): + value = self.value() + localized_value = QLocale().toString( + float(value), "f", self.app.parameters.digits_after_comma + ) + + if units: + return QCoreApplication.translate( + "PercentOfAverage", PercentOfAverage._REF_STR_ + ).format(localized_value, "", (self.units if units else "")) + else: + return localized_value + + def diff_localized(self, units=False, show_base=False): + value = self.differential() + localized_value = QLocale().toString( + float(value), "f", self.app.parameters.digits_after_comma + ) + + if units: + return QCoreApplication.translate( + "PercentOfAverage", PercentOfAverage._REF_STR_ + ).format(localized_value, "", (self.diff_units if units else "")) + else: + return localized_value