예제 #1
0
class Bill(models.Model):
    bill_number = models.CharField(max_length=30)
    bill_time = models.DateTimeField(null=True)
    total_amount = models.DecimalField(max_digits=10, decimal_places=2, null=True)

    def __str__(self):
        return '{0} (Total Rs. {1})'.format(self.bill_number, self.total_amount)

    def save(self, *args, **kwargs):
        super(Bill, self).save(*args, **kwargs)
        self.total_amount = Decimal(0.0)
        for bill_item in self.items():
            self.total_amount += bill_item.medicine.unit_cost * bill_item.number
        super(Bill, self).save(*args, **kwargs)

    def items(self):
        return BillItem.objects.filter(bill=self.pk)

    def time(self):
        return self.bill_time.strftime('%H:%M:%S')

    def date(self):
        return self.bill_time.strftime('%d:%m:%Y')

    def grand_total(self):
        return '{0}0'.format(self.total_amount.__round__(1))

    def round_off(self):
        return (self.total_amount - self.total_amount.__round__(1)).__round__(2)
예제 #2
0
 def _convert_price_from_oz_to_other_unit(oz_price, unit_to):
     value = None
     try:
         if unit_to == 'oz':
             value = Decimal(oz_price).__round__(2)
         if unit_to == 'kg':
             val = Decimal(oz_price) * Decimal(32.15)
             value = val.__round__(2)
         if unit_to == 'g':
             val = Decimal(oz_price) / Decimal(31.1)
             value = val.__round__(2)
     except TypeError:
         return value
     return str(value)
예제 #3
0
 def _collect_crypto_record(self, crypto_resource_obj=None):
     records = []
     if crypto_resource_obj:
         val = Decimal(crypto_resource_obj.price)
         value = str(val.__round__(2))
         records.append({
             'name': crypto_resource_obj.ticker_from.lower(),
             'currency': 'USD',
             'value': value
         })
         if self.usdchf:
             val = Decimal(crypto_resource_obj.price) * Decimal(
                 self.usdchf.price)
             value = str(val.__round__(2))
             records.append({
                 'name': crypto_resource_obj.ticker_from.lower(),
                 'currency': 'CHF',
                 'value': value
             })
         if self.usdeur:
             val = Decimal(crypto_resource_obj.price) * Decimal(
                 self.usdeur.price)
             value = str(val.__round__(2))
             records.append({
                 'name': crypto_resource_obj.ticker_from.lower(),
                 'currency': 'EUR',
                 'value': value
             })
         if self.usdpln:
             val = Decimal(crypto_resource_obj.price) * Decimal(
                 self.usdpln.price)
             value = str(val.__round__(2))
             records.append({
                 'name': crypto_resource_obj.ticker_from.lower(),
                 'currency': 'PLN',
                 'value': value
             })
     for r in records:
         self._set_mongo_crypto_data(r)
예제 #4
0
class SigFig:
    """
    Follows the rules of significant figures
    1. All non zero numbers are significant
    2. Zeros located between non-zero digits are significant
    3. Trailing zeros are significant only if the number contains a decimal
    4. Zeros to left of the first nonzero digit are insignificant

    Exact Numbers:
    exact counts don't affect sigfigs in calculations
    and are said to have an infinite number of significant figures

    """
    _Inf = float("inf")

    def __new__(cls, value: Union[str, int, 'SigFig', Decimal], exact=False, precision=None, decimalplaces=None):
        self = object.__new__(cls)

        try:
            self.value = Decimal(value)
        except TypeError as e:
            if hasattr(value, "value"):
                self.value = Decimal(value.value)
            else:
                raise TypeError(f"cant convert from {value!r} to SigFig") from e

        if decimalplaces is None and precision is None:
            if '.' not in str(value):
                # no decimal . remove trailing zeroes
                self.value = self.value.normalize()
        else:
            if precision is not None:
                # if u are given a precision compute the best one given precision
                dp = precision - self.value.adjusted() - 1
                decimalplaces = dp if decimalplaces is None else min(dp, decimalplaces)

            self.value = self.value.__round__(decimalplaces)

        if exact:
            self.precision = SigFig._Inf
            self.decimal_places = SigFig._Inf
        else:
            self.precision = len(self.value.as_tuple().digits)
            self.decimal_places = self.precision - self.value.adjusted() - 1

        return self

    def __str__(self):
        if self.decimal_places == SigFig._Inf:
            return f"{self.value}"

        try:
            return f"{round(self.value, self.decimal_places)}"
        except decimal.InvalidOperation:
            return f"{self.value}"

    def __repr__(self):
        if self.precision == SigFig._Inf:
            return f"SigFig({str(self)!r},exact=True)"
        else:
            return f"SigFig({str(self)!r})"

    def __add__(self, other):
        """addition keeps the number of least precise decimal"""
        if not isinstance(other, self.__class__):
            other = self.__class__(other)
        return SigFig(self.value + other.value, decimalplaces=min(self.decimal_places, other.decimal_places))

    __radd__ = __add__

    def __sub__(self, other):
        """subtraction keeps the number of least precise decimal"""
        if not isinstance(other, self.__class__):
            other = self.__class__(other)
        return SigFig(self.value - other.value, decimalplaces=min(self.decimal_places, other.decimal_places))

    def __rsub__(self, other):
        if not isinstance(other, self.__class__):
            other = self.__class__(other)
        return other - self

    def __mul__(self, other):
        """multiplication keeps the precision of number with the least amount of sigfigs"""
        if not isinstance(other, self.__class__):
            other = self.__class__(other)
        return SigFig(self.value * other.value, precision=min(self.precision, other.precision))

    __rmul__ = __mul__

    def __truediv__(self, other):
        """division keeps the precision of number with the least amount of sigfigs"""
        if not isinstance(other, self.__class__):
            other = self.__class__(other)
        return SigFig(self.value / other.value, precision=min(self.precision, other.precision))

    def __rtruediv__(self, other):
        if not isinstance(other, self.__class__):
            other = self.__class__(other)
        return other / self

    def __neg__(self):
        return SigFig(-self.value, decimalplaces=self.decimalplaces, precision=self.precision)

    def __eq__(self, other):
        if hasattr(other, "value"):
            return self.value == other.value
        return self.value == Decimal(other)

    def __lt__(self, other):
        if hasattr(other, "value"):
            return self.value < other.value
        return self.value < Decimal(other)

    def __le__(self, other):
        if hasattr(other, "value"):
            return self.value <= other.value
        return self.value <= Decimal(other)
예제 #5
0
class ContractingDecimal:
    def _get_other(self, other):
        if type(other) == ContractingDecimal:
            return other._d
        elif type(other) == float or type(other) == int:
            o = str(other)
            return Decimal(neg_sci_not(o))
        return other

    def __init__(self, a):
        if type(a) == float or type(a) == int:
            o = str(a)
            self._d = Decimal(neg_sci_not(o))
        elif type(a) == Decimal:
            self._d = a
        elif type(a) == str:
            self._d = Decimal(neg_sci_not(a))
        else:
            self._d = Decimal(a)

    def __bool__(self):
        return self._d > 0

    def __eq__(self, other):
        return self._d.__eq__(self._get_other(other))

    def __lt__(self, other):
        return self._d.__lt__(self._get_other(other))

    def __le__(self, other):
        return self._d.__le__(self._get_other(other))

    def __gt__(self, other):
        return self._d.__gt__(self._get_other(other))

    def __ge__(self, other):
        return self._d.__ge__(self._get_other(other))

    def __str__(self):
        return self._d.__str__()

    def __neg__(self):
        return self._d.__neg__()

    def __pos__(self):
        return self._d.__pos__()

    def __abs__(self):
        return self._d.__abs__()

    def __add__(self, other):
        x = self._d.__add__(self._get_other(other))
        return fix_precision(x)

    def __radd__(self, other):
        return fix_precision(self._d.__radd__(self._get_other(other)))

    def __sub__(self, other):
        return fix_precision(self._d.__sub__(self._get_other(other)))

    def __rsub__(self, other):
        return fix_precision(self._d.__rsub__(self._get_other(other)))

    def __mul__(self, other):
        return fix_precision(self._d.__mul__(self._get_other(other)))

    def __rmul__(self, other):
        return fix_precision(self._d.__rmul__(self._get_other(other)))

    def __truediv__(self, other):
        return fix_precision(self._d.__truediv__(self._get_other(other)))

    def __rtruediv__(self, other):
        return fix_precision(self._d.__rtruediv__(self._get_other(other)))

    def __divmod__(self, other):
        return fix_precision(self._d.__divmod__(self._get_other(other)))

    def __rdivmod__(self, other):
        return fix_precision(self._d.__divmod__(self._get_other(other)))

    def __mod__(self, other):
        return fix_precision(self._d.__mod__(self._get_other(other)))

    def __rmod__(self, other):
        return fix_precision(self._d.__rmod__(self._get_other(other)))

    def __floordiv__(self, other):
        return fix_precision(self._d.__floordiv__(self._get_other(other)))

    def __rfloordiv__(self, other):
        return fix_precision(self._d.__rfloordiv__(self._get_other(other)))

    def __pow__(self, other):
        return fix_precision(self._d.__pow__(self._get_other(other)))

    def __rpow__(self, other):
        return fix_precision(self._d.__rpow__(self._get_other(other)))

    def __int__(self):
        return self._d.__int__()

    def __float__(self):
        return float(self._d)

    def __round__(self, n=None):
        return self._d.__round__(n)
예제 #6
0
 def base_round_zero(val, n):
     if val is not None:
         val = Decimal(val, getcontext())
     else:
         val = Decimal(0, getcontext())
     return val.__round__(n)
예제 #7
0
 def base_round(val, n):
     if val is not None:
         val = Decimal(val, getcontext())
         return val.__round__(n)
     return None
예제 #8
0
 def _convert_price_from_999_to_other(trial: str, price: str) -> str:
     if trial == "999":
         return price
     convert_price = Decimal(price) * (Decimal(trial) / 1000)
     return str(convert_price.__round__(2))