<commit_before># -*- coding: utf-8 -*-
from .asset import Asset
from .instance import AbstractBlockchainInstanceProvider


class Amount(dict, AbstractBlockchainInstanceProvider):
    """ This class deals with Amounts of any asset to simplify dealing with the tuple::

            (amount, asset)

        :param list args: Allows to deal with different representations of an amount
        :param float amount: Let's create an instance with a specific amount
        :param str asset: Let's you create an instance with a specific asset (symbol)
        :param instance blockchain_instance: instance to use when accesing a RPC
        :returns: All data required to represent an Amount/Asset
        :rtype: dict
        :raises ValueError: if the data provided is not recognized

        .. code-block:: python

            from peerplays.amount import Amount
            from peerplays.asset import Asset
            a = Amount("1 USD")
            b = Amount(1, "USD")
            c = Amount("20", self.asset_class("USD"))
            a + b
            a * 2
            a += b
            a /= 2.0

        Way to obtain a proper instance:

            * ``args`` can be a string, e.g.:  "1 USD"
            * ``args`` can be a dictionary containing ``amount`` and ``asset_id``
            * ``args`` can be a dictionary containing ``amount`` and ``asset``
            * ``args`` can be a list of a ``float`` and ``str`` (symbol)
            * ``args`` can be a list of a ``float`` and a :class:`.asset.Asset`
            * ``amount`` and ``asset`` are defined manually

        An instance is a dictionary and comes with the following keys:

            * ``amount`` (float)
            * ``symbol`` (str)
            * ``asset`` (instance of :class:`.asset.Asset`)

        Instances of this class can be used in regular mathematical expressions
        (``+-*/%``) such as:

        .. code-block:: python

            Amount("1 USD") * 2
            Amount("15 GOLD") + Amount("0.5 GOLD")
    """

    def __init__(self, *args, **kwargs):
        self.define_classes()
        assert self.asset_class
        assert self.price_class

        self["asset"] = {}

        amount = kwargs.get("amount", None)
        asset = kwargs.get("asset", None)

        if len(args) == 1 and isinstance(args[0], Amount):
            # Copy Asset object
            self["amount"] = args[0]["amount"]
            self["symbol"] = args[0]["symbol"]
            self["asset"] = args[0]["asset"]

        elif len(args) == 1 and isinstance(args[0], str):
            self["amount"], self["symbol"] = args[0].split(" ")
            self["asset"] = self.asset_class(
                self["symbol"], blockchain_instance=self.blockchain
            )

        elif (
            len(args) == 1
            and isinstance(args[0], dict)
            and "amount" in args[0]
            and "asset_id" in args[0]
        ):
            self["asset"] = self.asset_class(
                args[0]["asset_id"], blockchain_instance=self.blockchain
            )
            self["symbol"] = self["asset"]["symbol"]
            self["amount"] = int(args[0]["amount"]) / 10 ** self["asset"]["precision"]

        elif (
            len(args) == 1
            and isinstance(args[0], dict)
            and "amount" in args[0]
            and "asset" in args[0]
        ):
            self["asset"] = self.asset_class(
                args[0]["asset"], blockchain_instance=self.blockchain
            )
            self["symbol"] = self["asset"]["symbol"]
            self["amount"] = int(args[0]["amount"]) / 10 ** self["asset"]["precision"]

        elif len(args) == 2 and isinstance(args[1], Asset):
            self["amount"] = args[0]
            self["symbol"] = args[1]["symbol"]
            self["asset"] = args[1]

        elif len(args) == 2 and isinstance(args[1], str):
            self["amount"] = args[0]
            self["asset"] = self.asset_class(
                args[1], blockchain_instance=self.blockchain
            )
            self["symbol"] = self["asset"]["symbol"]

        elif isinstance(amount, (int, float)) and asset and isinstance(asset, Asset):
            self["amount"] = amount
            self["asset"] = asset
            self["symbol"] = self["asset"]["symbol"]

        elif isinstance(amount, (int, float)) and asset and isinstance(asset, dict):
            self["amount"] = amount
            self["asset"] = asset
            self["symbol"] = self["asset"]["symbol"]

        elif isinstance(amount, (int, float)) and asset and isinstance(asset, str):
            self["amount"] = amount
            self["asset"] = self.asset_class(asset, blockchain_instance=self.blockchain)
            self["symbol"] = asset

        else:
            raise ValueError

        # make sure amount is a float
        self["amount"] = float(self.get("amount", 0.0))

    def copy(self):
        """ Copy the instance and make sure not to use a reference
        """
        return self.__class__(
            amount=self["amount"],
            asset=self["asset"].copy(),
            blockchain_instance=self.blockchain,
        )

    @property
    def amount(self):
        """ Returns the amount as float
        """
        return self["amount"]

    @property
    def symbol(self):
        """ Returns the symbol of the asset
        """
        return self["symbol"]

    def tuple(self):
        return float(self), self.symbol

    @property
    def asset(self):
        """ Returns the asset as instance of :class:`.asset.Asset`
        """
        if not self["asset"]:
            self["asset"] = self.asset_class(
                self["symbol"], blockchain_instance=self.blockchain
            )
        return self["asset"]

    def json(self):
        return {"amount": int(self), "asset_id": self["asset"]["id"]}

    def __str__(self):
        return "{:,.{prec}f} {}".format(
            self["amount"], self["symbol"], prec=self["asset"]["precision"]
        )

    def __float__(self):
        return float(self["amount"])

    def __int__(self):
        return int(self["amount"] * 10 ** self["asset"]["precision"])

    def __neg__(self):
        a = self.copy()
        a["amount"] = -float(a)
        return a
<commit_msg>amount.__int__ needs rounding<commit_after># -*- coding: utf-8 -*-
from .asset import Asset
from .instance import AbstractBlockchainInstanceProvider


class Amount(dict, AbstractBlockchainInstanceProvider):
    """ This class deals with Amounts of any asset to simplify dealing with the tuple::

            (amount, asset)

        :param list args: Allows to deal with different representations of an amount
        :param float amount: Let's create an instance with a specific amount
        :param str asset: Let's you create an instance with a specific asset (symbol)
        :param instance blockchain_instance: instance to use when accesing a RPC
        :returns: All data required to represent an Amount/Asset
        :rtype: dict
        :raises ValueError: if the data provided is not recognized

        .. code-block:: python

            from peerplays.amount import Amount
            from peerplays.asset import Asset
            a = Amount("1 USD")
            b = Amount(1, "USD")
            c = Amount("20", self.asset_class("USD"))
            a + b
            a * 2
            a += b
            a /= 2.0

        Way to obtain a proper instance:

            * ``args`` can be a string, e.g.:  "1 USD"
            * ``args`` can be a dictionary containing ``amount`` and ``asset_id``
            * ``args`` can be a dictionary containing ``amount`` and ``asset``
            * ``args`` can be a list of a ``float`` and ``str`` (symbol)
            * ``args`` can be a list of a ``float`` and a :class:`.asset.Asset`
            * ``amount`` and ``asset`` are defined manually

        An instance is a dictionary and comes with the following keys:

            * ``amount`` (float)
            * ``symbol`` (str)
            * ``asset`` (instance of :class:`.asset.Asset`)

        Instances of this class can be used in regular mathematical expressions
        (``+-*/%``) such as:

        .. code-block:: python

            Amount("1 USD") * 2
            Amount("15 GOLD") + Amount("0.5 GOLD")
    """

    def __init__(self, *args, **kwargs):
        self.define_classes()
        assert self.asset_class
        assert self.price_class

        self["asset"] = {}

        amount = kwargs.get("amount", None)
        asset = kwargs.get("asset", None)

        if len(args) == 1 and isinstance(args[0], Amount):
            # Copy Asset object
            self["amount"] = args[0]["amount"]
            self["symbol"] = args[0]["symbol"]
            self["asset"] = args[0]["asset"]

        elif len(args) == 1 and isinstance(args[0], str):
            self["amount"], self["symbol"] = args[0].split(" ")
            self["asset"] = self.asset_class(
                self["symbol"], blockchain_instance=self.blockchain
            )

        elif (
            len(args) == 1
            and isinstance(args[0], dict)
            and "amount" in args[0]
            and "asset_id" in args[0]
        ):
            self["asset"] = self.asset_class(
                args[0]["asset_id"], blockchain_instance=self.blockchain
            )
            self["symbol"] = self["asset"]["symbol"]
            self["amount"] = int(args[0]["amount"]) / 10 ** self["asset"]["precision"]

        elif (
            len(args) == 1
            and isinstance(args[0], dict)
            and "amount" in args[0]
            and "asset" in args[0]
        ):
            self["asset"] = self.asset_class(
                args[0]["asset"], blockchain_instance=self.blockchain
            )
            self["symbol"] = self["asset"]["symbol"]
            self["amount"] = int(args[0]["amount"]) / 10 ** self["asset"]["precision"]

        elif len(args) == 2 and isinstance(args[1], Asset):
            self["amount"] = args[0]
            self["symbol"] = args[1]["symbol"]
            self["asset"] = args[1]

        elif len(args) == 2 and isinstance(args[1], str):
            self["amount"] = args[0]
            self["asset"] = self.asset_class(
                args[1], blockchain_instance=self.blockchain
            )
            self["symbol"] = self["asset"]["symbol"]

        elif isinstance(amount, (int, float)) and asset and isinstance(asset, Asset):
            self["amount"] = amount
            self["asset"] = asset
            self["symbol"] = self["asset"]["symbol"]

        elif isinstance(amount, (int, float)) and asset and isinstance(asset, dict):
            self["amount"] = amount
            self["asset"] = asset
            self["symbol"] = self["asset"]["symbol"]

        elif isinstance(amount, (int, float)) and asset and isinstance(asset, str):
            self["amount"] = amount
            self["asset"] = self.asset_class(asset, blockchain_instance=self.blockchain)
            self["symbol"] = asset

        else:
            raise ValueError

        # make sure amount is a float
        self["amount"] = float(self.get("amount", 0.0))

    def copy(self):
        """ Copy the instance and make sure not to use a reference
        """
        return self.__class__(
            amount=self["amount"],
            asset=self["asset"].copy(),
            blockchain_instance=self.blockchain,
        )

    @property
    def amount(self):
        """ Returns the amount as float
        """
        return self["amount"]

    @property
    def symbol(self):
        """ Returns the symbol of the asset
        """
        return self["symbol"]

    def tuple(self):
        return float(self), self.symbol

    @property
    def asset(self):
        """ Returns the asset as instance of :class:`.asset.Asset`
        """
        if not self["asset"]:
            self["asset"] = self.asset_class(
                self["symbol"], blockchain_instance=self.blockchain
            )
        return self["asset"]

    def json(self):
        return {"amount": int(self), "asset_id": self["asset"]["id"]}

    def __str__(self):
        return "{:,.{prec}f} {}".format(
            self["amount"], self["symbol"], prec=self["asset"]["precision"]
        )

    def __float__(self):
        return float(self["amount"])

    def __int__(self):
        # this needs rounding, e.g. 5.1 * 10 ** 5 == 509999.99999999994
        return int(round(self["amount"] * 10 ** self["asset"]["precision"]))

    def __neg__(self):
        a = self.copy()
        a["amount"] = -float(a)
        return a

{'fraction_non_alphanumeric': 0.14196109567288606, 'fraction_numerical': 0.01000396982929734, 'mean_word_length': 2.0047709923664123, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3794145', 'n_tokens_mistral': 3509, 'n_tokens_neox': 3368, 'n_words': 1000}