コード例 #1
0
ファイル: upsert.py プロジェクト: spookyowl/witchcraft
def extract_number(number_str, decimal=None):
    #TODO: handle decimal=False/True
    #TODO: regexp \s*[-+]?\s*[€$%]?[0-9,\.]\+
    separators = []   
    groups = ['']
    groups_index = 0
    sign = None

    for c in number_str:

        if c in ['.', ',']:
            separators.append(c)
            groups.append('')
            groups_index += 1

        elif c in [' ', '€', '$', '%']:
            continue

        elif c in ['+', '-'] and sign is None:
            sign = c

        elif c in '1234567890':
            groups[groups_index] += c
            
            if sign is None:
                sign = '+'
        else:
            return None

    if len(groups) == 0:
        return None

    elif len(groups[0]) == 0:

        if len(''.join(groups)) == 0:
            return None

        number = Decimal('%s0.%s' % (sign, ''.join(groups)))
        precision = len(number.as_tuple().digits)
        scale = - number.as_tuple().exponent
        input_type = InputType('numeric', dict(precision=precision, scale=scale))
        return number, input_type

    elif len(groups) == 1:
        return int(groups[0]), InputType('int')

    elif len(groups) > 1:
        number = Decimal('%s%s.%s' % (sign,''.join(groups[0:-1]), groups[-1]))
        precision = len(number.as_tuple().digits)
        scale = - number.as_tuple().exponent
        input_type = InputType('numeric', dict(precision=precision, scale=scale))
        return number, input_type

    else:
        return None
コード例 #2
0
ファイル: validators.py プロジェクト: alecthomas/voluptuous
    def _get_precision_scale(self, number):
        """
        :param number:
        :return: tuple(precision, scale, decimal_number)
        """
        try:
            decimal_num = Decimal(number)
        except InvalidOperation:
            raise Invalid(self.msg or 'Value must be a number enclosed with string')

        return (len(decimal_num.as_tuple().digits), -(decimal_num.as_tuple().exponent), decimal_num)
コード例 #3
0
ファイル: _common.py プロジェクト: sdementen/piecash
    def fset(self, d):
        if d is None:
            num, denom = None, None
        else:
            if isinstance(d, tuple):
                d = Decimal(d[0]) / d[1]
            elif isinstance(d, (int, int, str)):
                d = Decimal(d)
            elif isinstance(d, float):
                raise TypeError(("Received a floating-point number {} where a decimal is expected. " +
                                 "Use a Decimal, str, or int instead").format(d))
            elif not isinstance(d, Decimal):
                raise TypeError(("Received an unknown type {} where a decimal is expected. " +
                                 "Use a Decimal, str, or int instead").format(type(d).__name__))

            sign, digits, exp = d.as_tuple()
            denom = 10 ** max(-exp, 0)

            denom_basis = getattr(self, "{}_basis".format(denom_name), None)
            if denom_basis is not None:
                denom = denom_basis

            num = int(d * denom)
            if not ((-MAX_NUMBER < num < MAX_NUMBER) and (-MAX_NUMBER < denom < MAX_NUMBER)):
                raise ValueError(("The amount '{}' cannot be represented in GnuCash. " +
                                  "Either it is too large or it has too many decimals").format(d))

        setattr(self, num_name, num)
        setattr(self, denom_name, denom)
コード例 #4
0
ファイル: models.py プロジェクト: PeterXu/django-bmf
    def calc_tax(self, amount, price, related=False):
        # TODO add currency for calculation of taxes
        if not isinstance(amount, Decimal):
            amount = Decimal(str(amount))
        if isinstance(price, BaseCurrency):
            price = price.value
        elif not isinstance(price, Decimal):
            price = Decimal(str(price))

        if price.as_tuple().exponent > -2:
            price = price.quantize(Decimal('0.01'))

        taxes = self.product_tax.select_related('tax')

        tax_inc_sum = Decimal(1)
        for tax in taxes:
            if tax.included:
                tax_inc_sum += tax.tax.get_rate()

        # net price of one unit
        unit_exact = (price / tax_inc_sum).quantize(price)

        used_taxes = []
        net = (amount * unit_exact).quantize(Decimal('0.01'))
        gross = (amount * unit_exact).quantize(Decimal('0.01'))

        for tax in taxes:
            tax_value = (net * tax.tax.get_rate()).quantize(Decimal('0.01'))
            gross += tax_value
            if related:
                used_taxes.append((tax.tax, tax_value, tax))
            else:
                used_taxes.append((tax.tax, tax_value))
        return unit_exact, net, gross, used_taxes
コード例 #5
0
def decimal_places(arg):
    """
    Returns the number of decimal places in the given number

    Parameters
    ----------
    arg: Numeric or string
        A number to determine the number of decimal places

    Returns
    -------
    Number of decimal places found.

    Raises
    ------
    IllegalArgumentException if argument is not numeric.
    """

    if not is_number(str(arg)):
        raise IllegalArgumentException("[{0}] is not a number".format(arg))

    dec = Decimal(str(arg))
    exp = dec.as_tuple().exponent
    result = -exp

    return result
コード例 #6
0
    def latex(self):
        d = Decimal('%.2e' % self.val)
        m = d.as_tuple()
        dig = m[1]
        exponent = m[2] + 2
        s = "-" if m[0] == 1 else ""
        if (exponent < -3 or exponent > 4):
            s += (str(dig[0]) + "." + str(dig[1]) + str(dig[2]) +
                        ' \times ' + '10^{' + str(exponent) + '}')
            return s

        if exponent >= 2:
            s += str(dig[0]) + str(dig[1]) + str(dig[2])
            for num in range(exponent - 2, 0, -1):
                s += "0"
            return s

        if exponent <= -1:
            s += "0."
            for i in range(0, exponent + 1, -1):
                s += "0"
            s += str(dig[0]) + str(dig[1]) + str(dig[2])
            return s

        for i in range(3):
            s += str(dig[i])
            if i == exponent:
                s += "."

        return s
コード例 #7
0
ファイル: pdict.py プロジェクト: kannon92/psi4
 def __setitem__(self, key, value):
     try:
         key = key.upper()
     except AttributeError:
         raise AttributeError('Keys stored as upper-case strings: %s unsuitable' % (key))
     value = Decimal(value)
     if key in self.keys() and not 'CURRENT' in key:
         # Validate choosing more detailed value for variable
         existing_exp = self[key].as_tuple().exponent  # 0.1111 --> -4
         candidate_exp = value.as_tuple().exponent
         if existing_exp > candidate_exp:  # candidate has more digits
             places = Decimal(10) ** (existing_exp + 1)  # exp+1 permits slack in rounding
             best_value = value
         else:                             # existing has more digits
             places = Decimal(10) ** (candidate_exp + 1)
             best_value = self[key]
         # Validate values are the same
         places = max(places, Decimal('1E-11'))  # for computed psivars
         #print('FLOOR: ', self[key].quantize(places, rounding=ROUND_FLOOR) - value.quantize(places, rounding=ROUND_FLOOR))
         #print('CEIL:  ', self[key].quantize(places, rounding=ROUND_CEILING) - value.quantize(places, rounding=ROUND_CEILING))
         if (self[key].quantize(places, rounding=ROUND_CEILING).compare(value.quantize(places, rounding=ROUND_CEILING)) != 0) and \
            (self[key].quantize(places, rounding=ROUND_FLOOR).compare(value.quantize(places, rounding=ROUND_FLOOR)) != 0):
             raise ParsingValidationError(
                 """Output file yielded both %s and %s as values for quantity %s.""" %
                 (self[key].to_eng_string(), value.to_eng_string(), key))
         #print 'Resetting variable %s to %s' % (key, best_value.to_eng_string())
     else:
         best_value = value
         #print 'Setting   variable %s to %s' % (key, best_value.to_eng_string())
     super(PreservingDict, self).__setitem__(key, best_value)
コード例 #8
0
ファイル: fraction.py プロジェクト: visipuki/2tasks
def get_int_exp(str_n):
    # makes int from fractional by multiplying by 10
    # as much time as needed to get int
    n = Decimal(str_n)
    sign, digits, exp = n.as_tuple()
    int_n = int(n*10**(-exp))
    return (abs(int_n), exp)
コード例 #9
0
ファイル: rounding.py プロジェクト: timlinux/inasafe
def html_scientific_notation_rate(rate):
    """Helper for convert decimal rate using scientific notation.

    For example we want to show the very detail value of fatality rate
    because it might be a very small number.

    :param rate: Rate value
    :type rate: float

    :return: Rate value with html tag to show the exponent
    :rtype: str
    """
    precision = '%.3f'
    if rate * 100 > 0:
        decimal_rate = Decimal(precision % (rate * 100))
        if decimal_rate == Decimal((precision % 0)):
            decimal_rate = Decimal(str(rate * 100))
    else:
        decimal_rate = Decimal(str(rate * 100))
    if decimal_rate.as_tuple().exponent >= -3:
        rate_percentage = str(decimal_rate)
    else:
        rate = '%.2E' % decimal_rate
        html_rate = rate.split('E')
        # we use html tag to show exponent
        html_rate[1] = '10<sup>{exponent}</sup>'.format(
            exponent=html_rate[1])
        html_rate.insert(1, 'x')
        rate_percentage = ''.join(html_rate)
    return rate_percentage
コード例 #10
0
ファイル: registro.py プロジェクト: proge/cnab240
    def valor(self, valor):
        if self.formato == 'alfa':
            if not isinstance(valor, unicode):
                try:
                    valor = valor and unicode(valor) or u''
                except:
                    raise errors.TipoError(self, valor)
            if len(valor) > self.digitos:
                raise errors.NumDigitosExcedidoError(self, valor)

        elif self.decimais:
            if not isinstance(valor, Decimal):
                try:
                    valor = Decimal(valor)
                except:
                    raise errors.TipoError(self, valor)

            valor = valor.quantize(Decimal('.' + (self.decimais * '0')))

            num_decimais = valor.as_tuple().exponent * -1
            if num_decimais != self.decimais:
                raise errors.NumDecimaisError(self, valor)
            
            if len(str(valor).replace('.', '')) > self.digitos:
                raise errors.NumDigitosExcedidoError(self, valor)

        else:
            if not isinstance(valor, (int, long)):
                raise errors.TipoError(self, valor)
            if len(str(valor)) > self.digitos:
                raise errors.NumDigitosExcedidoError(self, valor)

        self._valor = valor
コード例 #11
0
def format_num(num, decplaces=10):
    "Converts a number into a more a readable string-version."
    try:
        dec = Decimal(num)
        # Cut the decimal off at "precision" decimal places.
        if decplaces < 1:
            dec = dec.quantize(Decimal("0"))
        else:
            # Set our precision to at least 28 or twice our precision, lest
            # Decimal.quantize complains about "result has too many digits".
            getcontext().prec = max(28, int(decplaces * 2))
            dec = dec.quantize(Decimal(".{}".format("0" * decplaces)))
    except:
        return "bad"
    # Split the decimal into sign, digits and exponent.
    tup = dec.as_tuple()
    delta = len(tup.digits) + tup.exponent
    digits = "".join(str(d) for d in tup.digits)
    # Put the number back together considering the delta.
    if delta <= 0:
        zeros = abs(tup.exponent) - len(tup.digits)
        val = "0." + ("0" * zeros) + digits
    else:
        val = digits[:delta] + ("0" * tup.exponent) + '.' + digits[delta:]
    # Strip trailing 0s and/or trailing dot:
    val = val.rstrip("0")
    if val[-1] == ".":
        val = val[:-1]

    if tup.sign:
        return "-" + val
    return val
コード例 #12
0
ファイル: decimal.py プロジェクト: zzzsochi/yadm
 def to_mongo(self, document: BaseDocument,
              value: Decimal) -> dict:
     sign, digits, exp = value.as_tuple()
     integer = self._integer_from_digits(digits)
     return {
         'i': -integer if sign else integer,
         'e': exp
     }
コード例 #13
0
ファイル: euler80.py プロジェクト: seizethedave/Euler
def Calc():
   for i in range(2, 100):
      sqrt = Decimal(i).sqrt()
      digits = sqrt.as_tuple().digits
      if len(digits) > 5:
         # Irrational(ish).
         digitalSum = sum(digits[:100])
         yield digitalSum
コード例 #14
0
ファイル: problem_080.py プロジェクト: adharris/euler
def sum_of_sqrt_digits(value, digits):
    
    if int(sqrt(value))**2 == value:
        return 0

    precision = digits + 2
    root = Decimal(value).sqrt(Context(precision))
    return sum(root.as_tuple().digits[:digits])
コード例 #15
0
def scientificformat(text):
    """
    Displays a float in scientific notation.

    If the input float is infinity or NaN, the (platform-dependent) string
    representation of that value will be displayed.

    This is based on the floatformat function in django/template/defaultfilters.py
    """

    try:
        input_val = force_unicode(text)
        d = Decimal(input_val)
    except UnicodeEncodeError:
        return u''
    except InvalidOperation:
        if input_val in special_floats:
            return input_val
        try:
            d = Decimal(force_unicode(float(text)))
        except (ValueError, InvalidOperation, TypeError, UnicodeEncodeError):
            return u''

    try:
        m = int(d) - d
    except (ValueError, OverflowError, InvalidOperation):
        return input_val

    try:
        # for 'normal' sized numbers
        if d.is_zero():
            number = u'0'
        elif ( (d > Decimal('-100') and d < Decimal('-0.1')) or ( d > Decimal('0.1') and d < Decimal('100')) ) :
            # this is what the original floatformat() function does
            sign, digits, exponent = d.quantize(Decimal('.01'), ROUND_HALF_UP).as_tuple()
            digits = [unicode(digit) for digit in reversed(digits)]
            while len(digits) <= abs(exponent):
                digits.append(u'0')
            digits.insert(-exponent, u'.')
            if sign:
                digits.append(u'-')
            number = u''.join(reversed(digits))
        else: 
            # for very small and very large numbers
            sign, digits, exponent = d.as_tuple()
            exponent = d.adjusted()
            digits = [unicode(digit) for digit in digits][:3] # limit to 2 decimal places
            while len(digits) < 3:
                digits.append(u'0')
            digits.insert(1, u'.')
            if sign:
                digits.insert(0, u'-')
            number = u''.join(digits)
            number += u'e' + u'%i' % exponent

        return mark_safe(formats.number_format(number))
    except InvalidOperation:
        return input_val
コード例 #16
0
class IssuedAmount:
    MIN_MANTISSA = 10**15
    MAX_MANTISSA = 10**16 - 1
    MIN_EXP = -96
    MAX_EXP = 80
    def __init__(self, strnum):
        self.context = getcontext()
        self.context.prec = 15
        self.context.Emin = self.MIN_EXP
        self.context.Emax = self.MAX_EXP

        self.dec = Decimal(strnum)

    def to_bytes(self):
        if self.dec.is_zero():
            return self.canonical_zero_serial()

        # Convert components to integers ---------------------------------------
        sign, digits, exp = self.dec.as_tuple()
        mantissa = int("".join([str(d) for d in digits]))

        # Canonicalize to expected range ---------------------------------------
        while mantissa < self.MIN_MANTISSA and exp > self.MIN_EXP:
            mantissa *= 10
            exp -= 1

        while mantissa > self.MAX_MANTISSA:
            if exp >= self.MAX_EXP:
                raise ValueError("amount overflow")
            mantissa //= 10
            exp += 1

        if exp < self.MIN_EXP or mantissa < self.MIN_MANTISSA:
            # Round to zero
            return self.canonical_zero_serial()

        if exp > self.MAX_EXP or mantissa > self.MAX_MANTISSA:
            raise ValueError("amount overflow")

        # Convert to bytes -----------------------------------------------------
        serial = 0x8000000000000000 # "Not XRP" bit set
        if sign == 0:
            serial |= 0x4000000000000000 # "Is positive" bit set
        serial |= ((exp+97) << 54) # next 8 bits are exponent
        serial |= mantissa # last 54 bits are mantissa

        return serial.to_bytes(8, byteorder="big", signed=False)


    def canonical_zero_serial(self):
        """
        Returns canonical format for zero (a special case):
        - "Not XRP" bit = 1
        - Everything else is zeroes
        - Arguably this means it's canonically written as "negative zero"
          because the encoding usually uses 1 for positive.
        """
        return (0x8000000000000000).to_bytes(8, byteorder="big", signed=False)
コード例 #17
0
    def verify_ogr_field(self, ogr_field, model_field):
        """
        Verifies if the OGR Field contents are acceptable to the Django
        model field.  If they are, the verified value is returned,
        otherwise the proper exception is raised.
        """
        if isinstance(ogr_field, OFTString) and isinstance(model_field, (models.CharField, models.TextField)):
            if self.encoding:
                # The encoding for OGR data sources may be specified here
                # (e.g., 'cp437' for Census Bureau boundary files).
                val = force_text(ogr_field.value, self.encoding)
            else:
                val = ogr_field.value
            if model_field.max_length and len(val) > model_field.max_length:
                raise InvalidString(
                    "%s model field maximum string length is %s, given %s characters."
                    % (model_field.name, model_field.max_length, len(val))
                )
        elif isinstance(ogr_field, OFTReal) and isinstance(model_field, models.DecimalField):
            try:
                # Creating an instance of the Decimal value to use.
                d = Decimal(str(ogr_field.value))
            except DecimalInvalidOperation:
                raise InvalidDecimal("Could not construct decimal from: %s" % ogr_field.value)

            # Getting the decimal value as a tuple.
            dtup = d.as_tuple()
            digits = dtup[1]
            d_idx = dtup[2]  # index where the decimal is

            # Maximum amount of precision, or digits to the left of the decimal.
            max_prec = model_field.max_digits - model_field.decimal_places

            # Getting the digits to the left of the decimal place for the
            # given decimal.
            if d_idx < 0:
                n_prec = len(digits[:d_idx])
            else:
                n_prec = len(digits) + d_idx

            # If we have more than the maximum digits allowed, then throw an
            # InvalidDecimal exception.
            if n_prec > max_prec:
                raise InvalidDecimal(
                    "A DecimalField with max_digits %d, decimal_places %d must "
                    "round to an absolute value less than 10^%d."
                    % (model_field.max_digits, model_field.decimal_places, max_prec)
                )
            val = d
        elif isinstance(ogr_field, (OFTReal, OFTString)) and isinstance(model_field, models.IntegerField):
            # Attempt to convert any OFTReal and OFTString value to an OFTInteger.
            try:
                val = int(ogr_field.value)
            except ValueError:
                raise InvalidInteger("Could not construct integer from: %s" % ogr_field.value)
        else:
            val = ogr_field.value
        return val
コード例 #18
0
def test_decimal():
    """Test a false positive with decimal.Decimal.as_tuple

    See astroid https://bitbucket.org/logilab/astroid/issues/92/
    """
    from decimal import Decimal
    dec = Decimal(2)
    first, second, third = dec.as_tuple()
    return first, second, third
コード例 #19
0
ファイル: models.py プロジェクト: vbutrim/anytask
def normalize_decimal(number):
    new_number = Decimal(str(number))
    new_number = new_number.normalize()
    exponent = new_number.as_tuple()[2]
    if exponent > 10:
        new_number = Decimal(0)
    elif exponent > 0:
        new_number = new_number.quantize(1)

    return new_number
コード例 #20
0
ファイル: scaleDivision.py プロジェクト: MihailJP/friture
    def minorTicks(self):
        # subdivide the major ticks intervals, in 5
        majorTicks = self.majorTicks()

        if len(majorTicks) < 2:
            return []

        trueMin = min(self.scale_min, self.scale_max)
        trueMax = max(self.scale_min, self.scale_max)

        if self.log:
            ticks = []

            standardLogTicks = [2, 4, 6, 8]

            for a in standardLogTicks:
                if a * majorTicks[0] / 10. >= trueMin:
                    ticks.append(a * majorTicks[0] / 10.)

            ticks += [a * x for a in standardLogTicks for x in majorTicks]

            for a in standardLogTicks:
                if a * majorTicks[-1] <= trueMax:
                    ticks.append(a * majorTicks[-1])
        else:
            majorTickInterval = self.majorTickInterval

            majorTickIntervalDecimal = Decimal(majorTickInterval)

            mainDigit = majorTickIntervalDecimal.as_tuple().digits[0]

            if mainDigit == 1:
                minorTickDiv = 5
            elif mainDigit == 2:
                minorTickDiv = 4  # could be 2 with another tick subdivision
            elif mainDigit == 5:
                minorTickDiv = 5
            else:
                minorTickDiv = 5

            minorTickInterval = abs(majorTickInterval / minorTickDiv)

            # find lowest bound
            x = majorTicks[0]
            while x >= trueMin:
                x -= minorTickInterval
            x += minorTickInterval

            # fill up to the max
            ticks = []
            while x <= trueMax:
                ticks.append(x)
                x += minorTickInterval

        return ticks
コード例 #21
0
ファイル: coda.py プロジェクト: taylor-ahn/tossi
def pick_coda_from_decimal(decimal):
    """Picks only a coda from a decimal."""
    decimal = Decimal(decimal)
    __, digits, exp = decimal.as_tuple()
    if exp < 0:
        return DIGIT_CODAS[digits[-1]]
    __, digits, exp = decimal.normalize().as_tuple()
    index = bisect_right(EXP_INDICES, exp) - 1
    if index < 0:
        return DIGIT_CODAS[digits[-1]]
    else:
        return EXP_CODAS[EXP_INDICES[index]]
コード例 #22
0
ファイル: tx.py プロジェクト: etherume/mmgen
def normalize_btc_amt(amt):
	# amt must be a string!

	from decimal import Decimal
	try:
		ret = Decimal(amt)
	except:
		msg("%s: Invalid amount" % amt)
		return False

	dmsg("Decimal(amt): %s\nAs tuple: %s" % (amt,repr(ret.as_tuple())))

	if ret.as_tuple()[-1] < -8:
		msg("%s: Too many decimal places in amount" % amt)
		return False

	if ret == 0:
		msg("Requested zero BTC amount")
		return False

	return trim_exponent(ret)
コード例 #23
0
ファイル: 104.py プロジェクト: jannekai/project-euler
def isPandigitFirst9(n):
    print(n)
    s = Decimal(5).sqrt()
    p = Decimal((1 + s) / 2)
    v = Decimal(((p**n) - ((1-p)**n)) / s)
    sign, digits, exp = v.as_tuple()
      
    r = set(digits[:9])
    r.discard(0)
    if len(r) == 9:
        print(n, r)
        return True    
    return False
コード例 #24
0
ファイル: field.py プロジェクト: coopengo/tryton
 def get_client(self, record, factor=1):
     value = record.value.get(self.name)
     if value is not None:
         digits = self.digits(record, factor=factor)
         if digits:
             p = digits[1]
         else:
             d = value * factor
             if not isinstance(d, Decimal):
                 d = Decimal(repr(d))
             p = -int(d.as_tuple().exponent)
         return locale.format('%.*f', (p, value * factor), True)
     else:
         return ''
コード例 #25
0
    def convert(match):
        match_item = match.group(match_index)
        value_item = match.group(value_index)
        if match_item and value_item:
            if ')' in match_item and '(' not in match_item:
                # clear any trailing parenthesis
                match_item = re.sub('[)]', '', 'match_item')

            from_value = Decimal(re.sub(r'[^\d.]', '', value_item))
            precision = abs(from_value.as_tuple().exponent)
            to_value = rate * from_value
            converted_value = to_currency(to_value, places=precision, curr=currency)
            diff.setdefault(match_item, format_output(match_item, converted_value))
            return diff[match_item]
コード例 #26
0
def number_of_decimal_places(n):
    """
    Compute the number of decimal places in a number.

    Examples
    --------
    >>> number_of_decimal_places(1)
    0
    >>> number_of_decimal_places(3.14)
    2
    >>> number_of_decimal_places('3.14')
    2
    """
    decimal = Decimal(str(n))
    return -decimal.as_tuple().exponent
コード例 #27
0
 def from_decimal(cls, dec):
     from decimal import Decimal
     if isinstance(dec, numbers.Integral):
         dec = Decimal(int(dec))
     elif not isinstance(dec, Decimal):
         raise TypeError('%s.from_decimal() only takes Decimals, not %r (%s)' % (cls.__name__, dec, type(dec).__name__))
     if not dec.is_finite():
         raise TypeError('Cannot convert %s to %s.' % (dec, cls.__name__))
     (sign, digits, exp) = dec.as_tuple()
     digits = int(''.join(map(str, digits)))
     if sign:
         digits = -digits
     if exp >= 0:
         return cls(digits*10**exp)
     return cls(digits, 10**(-exp))
コード例 #28
0
def gen_raw_decimal(val) :
    from decimal import Decimal
    assert isinstance(val, (str, int, long, Decimal))
    if isinstance(val, (str, int, long)) :
        val = Decimal(val)
    sign, digits, exponent = val.as_tuple()
    mantissa = 0L
    for digit in digits :
        mantissa *= 10
        mantissa += digit
    if sign == 1 :
        mantissa = -mantissa
    print mantissa, exponent
    raw_mantissa = raw_int(mantissa)
    raw_exponent = var_int(exponent)
    return raw_exponent + raw_mantissa
コード例 #29
0
ファイル: cuaderno57.py プロジェクト: gisce/bankbarcode
    def _check_amount(self, amount):
        """
        Check the amount (Importe)

        :param amount: the amount (Importe)
        :return: True if it have the expected length, otherwise False
        """
        name = 'amount'
        decimal = Decimal(amount)
        if decimal.as_tuple().exponent < -2:
            raise ValueError('{} have more than 2 decimals'.format(name))
        if decimal > 99999999.99:
            raise ValueError('{} is too big'.format(name))
        value = unicode(int(decimal * 100)).zfill(10)
        expected_length = 10
        description = 'amount lenth should be 10'
        return self._check_length(name, value, expected_length, description)
コード例 #30
0
ファイル: serialize.py プロジェクト: johansten/stellar-py
def parse_non_native_amount(string):

	amount	 = Decimal(string).normalize()
	parts	 = amount.as_tuple()
	exponent = parts.exponent

	value = ''.join(map(str, parts.digits))
	exponent += len(value)

	value = value.ljust(16, '0')
	exponent -= 16

	value = int(value)
	if value == 0:
		exponent = -99

	return parts.sign, value, exponent
コード例 #31
0
def parse_non_native_amount(string):
    """
    """
    amount = Decimal(string)
    # This will remove trailing zeros
    amount = amount.normalize()

    parts = amount.as_tuple()
    offset = parts.exponent

    # Shift everything such that '10' because '1000000....'
    value = ''.join(map(str, parts.digits))
    full_value = value.ljust(len('9999999999999999'), '0')
    offset -= len(full_value) - len(value)
    full_value = int(full_value)

    # This is special cased
    if full_value == 0:
        offset = -100

    return parts.sign, full_value, offset
コード例 #32
0
ファイル: petites.py プロジェクト: soliverit/blockBIM
def automagicallyRound(val):
    # Attempts to fix the rounding issue
    # Convert to string
    if type(val) != str:
        val_str = str(val)
    else:
        val_str = val

    # Try and match
    m = REGEX.match(val_str)
    if m:
        m_dec = Decimal(m[0])
        numDecPlaces = m_dec.as_tuple().exponent
        m_rounded = round(m_dec, abs(numDecPlaces) - 1)
        val_str = str(m_rounded)

    # Only removing trailing zeroes if there are numbers after the decimal point (to prevent truncating 1000 etc)
    if REGEX_FLOAT.match(val_str):
        val_str = str(REGEX_TRAILING.sub('', val_str))

    return val_str
コード例 #33
0
 def value(self, value):
     if value is None:
         self._value = None
         return
     if isinstance(value, Currency):
         self._value = value.value
         return
     if isinstance(value, (int, str, Decimal)):
         if isinstance(value, str):
             value = value.upper().strip()
             if len(value) >= 4 and value[-3:] == "TFT":
                 value = value[:-3].rstrip()
         d = Decimal(value)
         sign, _, exp = d.as_tuple()
         if exp < -9:
             raise Exception("CurrencyPrecisionOverflow")
         if sign != 0:
             raise Exception("Negative currency")
         self._value = d
         return
     raise Exception("cannot set value of type {} as Currency (invalid type)".format(type(value)))
コード例 #34
0
ファイル: number.py プロジェクト: redstreet/beancount
def auto_quantize(number: Decimal, threshold: float) -> Decimal:
    """Automatically quantize the number at a given threshold.

    For example, with a threshold of 0.01, this will convert:

      20.899999618530273 20.9
      20.290000000000000000000000000000 20.29
      110.90 110.9
      11.0600004196167 11.06
      10.539999961853027 10.54
      134.3300018310547 134.33
      253.920200000000000000000000000000 253.9202

    """
    exponent = auto_quantized_exponent(number, threshold)
    if exponent != number.as_tuple().exponent:
        quant = TEN**exponent
        qnumber = number.quantize(quant).normalize()
        return qnumber
    else:
        return number
コード例 #35
0
 def measureINCH():
     inch = vin("Inch measurement", 0.1969, units="in")
     if (inch == 'q'):
         return
     if (inch == 'c'):
         measureMM()
     else:
         try:
             d = Decimal(inch)
         except:
             num, denom = inch.split('/')
             inch = float(num)/float(denom)
             d = Decimal(inch)
         inch = float(inch)
         mm = inch*25.4
         if (d.as_tuple().exponent <= -4):
             digits = 4
         else:
             digits = 3
         print('{0} in = {1} in = {2} mm'.format(inch, tofrac(inch), round(mm,digits)))
         measureINCH()
コード例 #36
0
ファイル: _common.py プロジェクト: rerobins/piecash
    def fset(self, d):
        if d is None:
            num, denom = None, None
        else:
            if isinstance(d, tuple):
                d = Decimal(d[0]) / d[1]
            elif isinstance(d, (float, int, long, str)):
                d = Decimal(d)
            assert isinstance(d, Decimal)

            sign, digits, exp = d.as_tuple()
            denom = 10 ** max(-exp, 0)

            denom_basis = getattr(self, "{}_basis".format(denom_name), None)
            if denom_basis is not None:
                denom = denom_basis

            num = int(d * denom)

        setattr(self, num_name, num)
        setattr(self, denom_name, denom)
コード例 #37
0
ファイル: types.py プロジェクト: gitter-badger/pydantic
    def validate(cls, value: Decimal) -> Decimal:
        digit_tuple, exponent = value.as_tuple()[1:]
        if exponent in {'F', 'n', 'N'}:
            raise ValueError(f'value is not a valid decimal, got {value}')

        if exponent >= 0:
            # A positive exponent adds that many trailing zeros.
            digits = len(digit_tuple) + exponent
            decimals = 0
        else:
            # If the absolute value of the negative exponent is larger than the
            # number of digits, then it's the same as the number of digits,
            # because it'll consume all of the digits in digit_tuple and then
            # add abs(exponent) - len(digit_tuple) leading zeros after the
            # decimal point.
            if abs(exponent) > len(digit_tuple):
                digits = decimals = abs(exponent)
            else:
                digits = len(digit_tuple)
                decimals = abs(exponent)
        whole_digits = digits - decimals

        if cls.max_digits is not None and digits > cls.max_digits:
            raise ValueError(
                f'ensure that there are no more than {cls.max_digits} digits in total'
            )

        if cls.decimal_places is not None and decimals > cls.decimal_places:
            raise ValueError(
                f'ensure that there are no more than {cls.decimal_places} decimal places'
            )

        if cls.max_digits is not None and cls.decimal_places is not None:
            expected = cls.max_digits - cls.decimal_places
            if whole_digits > expected:
                raise ValueError(
                    f'ensure that there are no more than {expected} digits before the decimal point'
                )

        return value
コード例 #38
0
ファイル: numeric.py プロジェクト: mattsta/mutil
def fmtPricePad(n, padding=10, decimals=4):
    """Format price with padding as:
    - two decimal precision if <= 2 decimals
        - i.e. print 120 as 120.00
               print 120.3 as 120.30
    - up to 4 decimal places if more than 2 (as formatted by 'g')

    Rounding is done by round() and Decimal() then printed via .f or .g

    Also has a check to ignore very small values taking up wide space."""

    # python formatting doesn't allow 0 padding
    padding = max(padding, 1)

    # don't show tiny tiny values, and use 'abs' because sometimes
    # we're printing full negative percentages like -20.3242343289%, which is
    # les sthan 0.005, but we want to still print them nicely.
    # also guard against 'n' being None for some reason.
    if (not n) or abs(n) < 0.005:
        if n:
            return f"{n:>{padding},.2f}"

        return f"{' ':>{padding}}"

    # print at most 4 digits, not ending in zeroes...
    dn = Decimal(str(round(n, decimals)))
    sign, digits, exponent = dn.as_tuple()

    # skip formatting nan
    if exponent == "n":
        return f"{dn:>{padding}}"

    # if less than 3 decimals, always use two places.
    if abs(exponent) < 3:
        return f"{dn:>{padding},.2f}"

    # this long G is okay because we already truncated
    # the float value to 4 decimals at most using the triple conversion
    # above of Decimal(str(round(x, 4)))
    return f"{dn:>{padding},.20g}"
コード例 #39
0
ファイル: literals.py プロジェクト: rdsr/li-iceberg-rdsr
    def to(self, type_var):  # noqa: C901
        import dateutil.parser
        if type_var.type_id == TypeID.DATE:
            return DateLiteral(
                (dateutil.parser.parse(self.value) - Literals.EPOCH).days)
        elif type_var.type_id == TypeID.TIME:
            return TimeLiteral(
                int((dateutil.parser.parse(
                    Literals.EPOCH.strftime("%Y-%m-%d ") + self.value) -
                     Literals.EPOCH).total_seconds() * 1000000))
        elif type_var.type_id == TypeID.TIMESTAMP:
            timestamp = dateutil.parser.parse(self.value)
            EPOCH = Literals.EPOCH
            if bool(timestamp.tzinfo) != bool(type_var.adjust_to_utc):
                raise RuntimeError("Cannot convert to %s when string is: %s" %
                                   (type_var, self.value))

            if timestamp.tzinfo is not None:
                EPOCH = EPOCH.replace(tzinfo=pytz.UTC)

            return TimestampLiteral(
                int((timestamp - EPOCH).total_seconds() * 1000000))
        elif type_var.type_id == TypeID.STRING:
            return self
        elif type_var.type_id == TypeID.UUID:
            return UUIDLiteral(uuid.UUID(self.value))
        elif type_var.type_id == TypeID.DECIMAL:
            dec_val = Decimal(str(self.value))
            if abs(dec_val.as_tuple().exponent) == type_var.scale:
                if type_var.scale == 0:
                    return DecimalLiteral(
                        Decimal(str(self.value)).quantize(
                            Decimal('1.'), rounding=ROUND_HALF_UP))
                else:
                    return DecimalLiteral(
                        Decimal(str(self.value)).quantize(
                            Decimal("." + "".join(
                                ["0"
                                 for i in range(1, type_var.scale)]) + "1"),
                            rounding=ROUND_HALF_UP))
コード例 #40
0
ファイル: fields.py プロジェクト: wangscript/intensityengine
    def clean(self, value):
        """
        Validates that the input is a decimal number. Returns a Decimal
        instance. Returns None for empty values. Ensures that there are no more
        than max_digits in the number, and no more than decimal_places digits
        after the decimal point.
        """
        super(DecimalField, self).clean(value)
        if not self.required and value in EMPTY_VALUES:
            return None
        value = smart_str(value).strip()
        try:
            value = Decimal(value)
        except DecimalException:
            raise ValidationError(self.error_messages['invalid'])

        sign, digittuple, exponent = value.as_tuple()
        decimals = abs(exponent)
        # digittuple doesn't include any leading zeros.
        digits = len(digittuple)
        if decimals > digits:
            # We have leading zeros up to or past the decimal point.  Count
            # everything past the decimal point as a digit.  We do not count
            # 0 before the decimal point as a digit since that would mean
            # we would not allow max_digits = decimal_places.
            digits = decimals
        whole_digits = digits - decimals

        if self.max_value is not None and value > self.max_value:
            raise ValidationError(self.error_messages['max_value'] % self.max_value)
        if self.min_value is not None and value < self.min_value:
            raise ValidationError(self.error_messages['min_value'] % self.min_value)
        if self.max_digits is not None and digits > self.max_digits:
            raise ValidationError(self.error_messages['max_digits'] % self.max_digits)
        if self.decimal_places is not None and decimals > self.decimal_places:
            raise ValidationError(self.error_messages['max_decimal_places'] % self.decimal_places)
        if self.max_digits is not None and self.decimal_places is not None and whole_digits > (self.max_digits - self.decimal_places):
            raise ValidationError(self.error_messages['max_whole_digits'] % (self.max_digits - self.decimal_places))
        return value
コード例 #41
0
ファイル: parser_utils.py プロジェクト: benjyz/vyper
def get_number_as_fraction(expr, context):
    literal = Decimal(expr.value)
    sign, digits, exponent = literal.as_tuple()

    if exponent < -10:
        raise InvalidLiteral(
            f"`decimal` literal cannot have more than 10 decimal places: {literal}",
            expr)

    sign = -1 if sign == 1 else 1  # Positive Decimal has `sign` of 0, negative `sign` of 1
    # Decimal `digits` is a tuple of each digit, so convert to a regular integer
    top = int(Decimal((0, digits, 0)))
    top = sign * top * 10**(exponent if exponent > 0 else 0
                            )  # Convert to a fixed point integer
    bottom = 1 if exponent > 0 else 10**abs(
        exponent)  # Make denominator a power of 10
    assert Decimal(top) / Decimal(bottom) == literal  # Sanity check

    # TODO: Would be best to raise >10 decimal place exception here
    #       (unless Decimal is used more widely)

    return expr.node_source_code, top, bottom
コード例 #42
0
 def from_decimal(cls, dec):
     """Converts a finite Decimal instance to a rational number, exactly."""
     from decimal import Decimal
     if isinstance(dec, numbers.Integral):
         dec = Decimal(int(dec))
     elif not isinstance(dec, Decimal):
         raise TypeError(
             "%s.from_decimal() only takes Decimals, not %r (%s)" %
             (cls.__name__, dec, type(dec).__name__))
     if dec.is_infinite():
         raise OverflowError(
             "Cannot convert %s to %s." % (dec, cls.__name__))
     if dec.is_nan():
         raise ValueError("Cannot convert %s to %s." % (dec, cls.__name__))
     sign, digits, exp = dec.as_tuple()
     digits = int(''.join(map(str, digits)))
     if sign:
         digits = -digits
     if exp >= 0:
         return cls(digits * 10 ** exp)
     else:
         return cls(digits, 10 ** -exp)
コード例 #43
0
def validate_NUMPLACES(in_value, restriction):
    """
        the value parameter must be either a single value or a 1-dimensional list.
        All the values in this list must satisfy the condition
    """
    #Sometimes restriction values can accidentally be put in the template <item>100</items>,
    #Making them a list, not a number. Rather than blowing up, just get value 1 from the list.
    if type(restriction) is list:
        restriction = restriction[0]

    value = _get_val(in_value)
    if type(value) is list:
        for subval in value:
            if type(subval) is tuple:
                subval = subval[1]
            validate_NUMPLACES(subval, restriction)
    else:
        restriction = int(restriction) # Just in case..
        dec_val = Decimal(str(value))
        num_places = dec_val.as_tuple().exponent * -1 #exponent returns a negative num
        if restriction != num_places:
            raise ValidationError("NUMPLACES: %s"%(restriction))
コード例 #44
0
    def convert(match):
        match_item = match.group(match_index)
        value_item = match.group(value_index)
        suffix_item = match.group(suffix_index)
        if match_item and value_item:
            if ')' in match_item and '(' not in match_item:
                # clear any trailing parenthesis
                match_item = re.sub('[)]', '', match_item)

            from_value = Decimal(re.sub(r'[^\d.]', '', value_item))
            precision = abs(from_value.as_tuple().exponent)
            to_value = rate * from_value
            to_value, suffix_item, precision = update_suffix(
                to_value, suffix_item, precision)
            converted_value = to_currency(to_value,
                                          places=precision,
                                          curr=currency)
            diff.setdefault(
                match_item,
                format_output(match_item, converted_value, suffix_item,
                              src_currency))
            return diff[match_item]
コード例 #45
0
def _pseudonymise_DS(value):
    """
    Keep sign and exponent, but hash the digits and then convert the
    same number of digits from the hash back in to the decimal digits

    Parameters
    ----------
    value : decimal string
        A decimal string meeting the spec from DICOM

    Returns
    -------
    str
        a decimal string of the same sign and exponent.

    """
    my_decimal = Decimal(value)
    as_tuple = my_decimal.as_tuple()
    digits = as_tuple.digits
    count_digits = len(digits)
    my_hash_func = hashlib.new("sha3_256")
    encoded_value = digits.encode("ASCII")
    my_hash_func.update(encoded_value)
    # my_digest = my_hash_func.digest()
    my_hex_digest = my_hash_func.hex_digest()
    sliced_digest = my_hex_digest[0:count_digits]
    my_integer = int(sliced_digest, 16)
    my_integer_string = str(my_integer)
    # string_count = len(my_integer_string)
    new_digits = list()
    for i in range(0, count_digits):
        new_digits.append(my_integer_string[i : i + 1])

    new_decimal_tuple = DecimalTuple(
        as_tuple.sign, tuple(new_digits), as_tuple.exponent
    )
    new_decimal = Decimal(new_decimal_tuple)
    return str(new_decimal)
コード例 #46
0
    def complement_from_employment(self, employee_obj, **kwargs):
        """ Update Employee object, get data from employee.employment
        :param employee_obj: Employee model instance
        :param kwargs: data params
        :return:
        """
        obj = employee_obj
        try:
            salary = Decimal(kwargs['salary'].replace(',', '')) \
                if kwargs['salary'] else Decimal(0)
            if len(salary.as_tuple().digits) > 10:
                # if count of digits more 10 - don't save in db
                salary = Decimal(0)
            obj.monthlysalary = salary
        except InvalidOperation:
            pass

        obj.extra['title'] = kwargs['position'] or '---'
        if 'documents' not in obj.extra:
            obj.extra['documents'] = {}
        obj.extra['documents'].update({
            'visa': {
                'number': kwargs['visa_number'],
                'expiry_date': kwargs['visa_expiry_date'],
                'image_url': kwargs['visa_document'],
            },
            'work_contract': {
                'start_date': kwargs['contract_start_date'],
                'end_date': kwargs['contract_end_date'],
            },
        })
        extra_legacy = self.get_extra_legacy(kwargs, 'employment')
        obj.extra['legacy'].update({'employment': extra_legacy})

        obj.extra = self.clean_and_validate_extra(obj.extra)
        obj.save(metadata=Metadata.empty())

        return obj
コード例 #47
0
def decimal_to_string(value: decimal.Decimal) -> str:
    """
    Convert a Decimal value to a string representation
    that not includes exponent and with its decimals.
    """
    sign, digits, exponent = value.as_tuple()

    if not exponent:
        result = ''.join(str(x) for x in digits)
    elif exponent > 0:
        result = ''.join(str(x) for x in digits) + '0' * exponent
    else:
        result = ''.join(str(x) for x in digits[:exponent])
        if not result:
            result = '0'
        result += '.'
        if len(digits) >= -exponent:
            result += ''.join(str(x) for x in digits[exponent:])
        else:
            result += '0' * (-exponent - len(digits))
            result += ''.join(str(x) for x in digits)

    return '-' + result if sign else result
コード例 #48
0
 def value(self, value):
     if value is None:
         self._value = None
         return
     if isinstance(value, Currency):
         self._value = value.value
         return
     if isinstance(value, (int, str, Decimal)):
         if isinstance(value, str):
             value = value.upper().strip()
             if len(value) >= 4 and value[-3:] == "TFT":
                 value = value[:-3].rstrip()
         d = Decimal(value)
         sign, _, exp = d.as_tuple()
         if exp < -9:
             raise j.clients.tfchain.errors.CurrencyPrecisionOverflow(d)
         if sign != 0:
             raise j.clients.tfchain.errors.CurrencyNegativeValue(d)
         self._value = d
         return
     raise TypeError(
         "cannot set value of type {} as Currency (invalid type)".format(
             type(value)))
コード例 #49
0
ファイル: comtopvt.py プロジェクト: SeunAdelekan/PVT-ML
    def _key_validate(self,char,index,current,proposed,action,**kwargs):
        valid=True
        min_val=self.cget('from')
        max_val=self.cget('to')
        no_negative=min_val>=0
        no_decimal=self.precision >= 0
        if action =='0':
            return True
        #First, filter out obviously invalid keystrokes
        if any([(char not in('-12345678.')),(char =='-' and (no_negative or index!='0')),(char=='.' and (no_decimal or '.' in current))]):
            return False

        #At this point, proposed is either '-','.','-.', or a valid Decimal String
        if proposed in '-.':
            return True
        #Proposed is a valid Decimal String convert to Decimal and Check more:
        proposed = Decimal(proposed)
        proposed_precision=proposed.as_tuple().exponent

        if any([(proposed>max_val),(proposed_precision<self.precision)]):
            return False

        return valid
コード例 #50
0
def fmt_prob(prob, prec=4):
    """
    Format a float as a string in a style suitable for displaying 
    probabilities.
    This is not a particularly quick procedure. If you need to format 
    lots of probabilities, it's probably best to do something cruder.
    
    """
    from decimal import Decimal
    # Quantize the value to the correct precision
    prob = Decimal(str(prob))  #.as_tuple()
    quant = Decimal((0, [
        1,
    ], prob.adjusted() - prec + 1))
    prob = prob.quantize(quant)
    # Format it yourself, because Decimal's to_sci_string is crap
    tup = prob.as_tuple()
    sci_str = "%s%d.%se%d" % ("-" if prob.is_signed() else "", tup.digits[0],
                              "".join(["%d" % dig for dig in tup.digits[1:]
                                       ]), prob.adjusted())
    # Add more spacing for higher precisions
    #fmt_str = " >%ds" % (prec+3)
    return sci_str  #format(sci_str, fmt_str)
コード例 #51
0
ファイル: format.py プロジェクト: nickalaskreynolds/nkrpy
def general_format(x,
                   precision: int = 2,
                   pad: int = 10,
                   left: bool = False,
                   fmt: str = 'D') -> str:
    """General formatter.

    Parameters
    ----------
    x: str
        The number (string castable) to be formatted
    precision: int
        The precision of the formatter. In sig figs
    pad: int
        The amount to pad the string to
    left_pad: bool
        If False will right pad the string,
    fmt: str
        The delimiting string between the # and the exp
    Returns
    -------
    str
        The formatted number as a string

    """
    x = Decimal(str(x))
    tup = x.as_tuple()
    digits = list(tup.digits[:precision + 1])
    sign = '-' if tup.sign else '+'
    dec = ''.join(map(str, digits[1:]))
    exp = x.adjusted()
    ret = f'{sign}{digits[0]}.{dec}{fmt}{exp}'
    if not pad:
        return ret
    if not left:
        return ret.rjust(pad)
    return ret.ljust(pad)
コード例 #52
0
def format_number(num):
    """
        https://stackoverflow.com/a/5808014/827526
    """
    try:
        dec = Decimal(num)
    except decimal.DecimalException as ex:
        print(str(ex))
        # return f'Bad number. Not a decimal: {num}'
        return "nan"
    tup = dec.as_tuple()
    delta = len(tup.digits) + tup.exponent
    digits = ''.join(str(d) for d in tup.digits)
    if delta <= 0:
        zeros = abs(tup.exponent) - len(tup.digits)
        val = '0.' + ('0' * zeros) + digits
    else:
        val = digits[:delta] + ('0' * tup.exponent) + '.' + digits[delta:]
    val = val.rstrip('0')
    if val[-1] == '.':
        val = val[:-1]
    if tup.sign:
        return '-' + val
    return val
コード例 #53
0
ファイル: base.py プロジェクト: lycantropos/orient
def to_digits_count(number: float,
                    *,
                    max_digits_count: int = FLOATING_POINT_PRECISION) -> float:
    decimal = Decimal(number).normalize()
    _, significant_digits, exponent = decimal.as_tuple()
    significant_digits_count = len(significant_digits)
    if exponent < 0:
        fixed_digits_count = (1 -
                              exponent if exponent <= -significant_digits_count
                              else significant_digits_count)
    else:
        fixed_digits_count = exponent + significant_digits_count
    if fixed_digits_count <= max_digits_count:
        return number
    whole_digits_count = max(significant_digits_count + exponent, 0)
    if whole_digits_count:
        whole_digits_offset = max(whole_digits_count - max_digits_count, 0)
        decimal /= 10**whole_digits_offset
        whole_digits_count -= whole_digits_offset
    else:
        decimal *= 10**(-exponent - significant_digits_count)
        whole_digits_count = 1
    decimal = round(decimal, max(max_digits_count - whole_digits_count, 0))
    return float(str(decimal))
コード例 #54
0
def format_satoshis(x,
                    is_diff=False,
                    num_zeros=0,
                    decimal_point=8,
                    whitespaces=False):
    from decimal import Decimal
    s = Decimal(x)
    sign, digits, exp = s.as_tuple()
    digits = map(str, digits)
    while len(digits) < decimal_point + 1:
        digits.insert(0, '0')
    digits.insert(-decimal_point, '.')
    s = ''.join(digits).rstrip('0')
    if sign:
        s = '-' + s
    elif is_diff:
        s = "+" + s

    p = s.find('.')
    s += "0" * (1 + num_zeros - (len(s) - p))
    if whitespaces:
        s += " " * (1 + decimal_point - (len(s) - p))
        s = " " * (13 - decimal_point - (p)) + s
    return s
コード例 #55
0
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
# SOFTWARE.

from fractions import Fraction
from decimal import Decimal
from math import factorial, ceil

f = 39.9
print(f)
print("{0:.2f}".format(f))

i = 3990
print(i)

f = Fraction("3.1415926535897932").limit_denominator(1000)
print(f)

d = Decimal(12345.6789)
print(d.as_tuple())
print(round(d, 2))
print(ceil(d))

f = factorial(5)
print(f)

print(2 ** 3)
print(8 // 3)

コード例 #56
0
def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='',
           force_grouping=False, use_l10n=None):
    """
    Get a number (as a number or string), and return it as a string,
    using formats defined as arguments:

    * decimal_sep: Decimal separator symbol (for example ".")
    * decimal_pos: Number of decimal positions
    * grouping: Number of digits in every group limited by thousand separator.
        For non-uniform digit grouping, it can be a sequence with the number
        of digit group sizes following the format used by the Python locale
        module in locale.localeconv() LC_NUMERIC grouping (e.g. (3, 2, 0)).
    * thousand_sep: Thousand separator symbol (for example ",")
    """
    use_grouping = (use_l10n or (use_l10n is None and settings.USE_L10N)) and settings.USE_THOUSAND_SEPARATOR
    use_grouping = use_grouping or force_grouping
    use_grouping = use_grouping and grouping != 0
    # Make the common case fast
    if isinstance(number, int) and not use_grouping and not decimal_pos:
        return mark_safe(number)
    # sign
    sign = ''
    if isinstance(number, Decimal):

        if decimal_pos is not None:
            # If the provided number is too small to affect any of the visible
            # decimal places, consider it equal to '0'.
            cutoff = Decimal('0.' + '1'.rjust(decimal_pos, '0'))
            if abs(number) < cutoff:
                number = Decimal('0')

        # Format values with more than 200 digits (an arbitrary cutoff) using
        # scientific notation to avoid high memory usage in {:f}'.format().
        _, digits, exponent = number.as_tuple()
        if abs(exponent) + len(digits) > 200:
            number = '{:e}'.format(number)
            coefficient, exponent = number.split('e')
            # Format the coefficient.
            coefficient = format(
                coefficient, decimal_sep, decimal_pos, grouping,
                thousand_sep, force_grouping, use_l10n,
            )
            return '{}e{}'.format(coefficient, exponent)
        else:
            str_number = '{:f}'.format(number)
    else:
        str_number = str(number)
    if str_number[0] == '-':
        sign = '-'
        str_number = str_number[1:]
    # decimal part
    if '.' in str_number:
        int_part, dec_part = str_number.split('.')
        if decimal_pos is not None:
            dec_part = dec_part[:decimal_pos]
    else:
        int_part, dec_part = str_number, ''
    if decimal_pos is not None:
        dec_part = dec_part + ('0' * (decimal_pos - len(dec_part)))
    dec_part = dec_part and decimal_sep + dec_part
    # grouping
    if use_grouping:
        try:
            # if grouping is a sequence
            intervals = list(grouping)
        except TypeError:
            # grouping is a single value
            intervals = [grouping, 0]
        active_interval = intervals.pop(0)
        int_part_gd = ''
        cnt = 0
        for digit in int_part[::-1]:
            if cnt and cnt == active_interval:
                if intervals:
                    active_interval = intervals.pop(0) or active_interval
                int_part_gd += thousand_sep[::-1]
                cnt = 0
            int_part_gd += digit
            cnt += 1
        int_part = int_part_gd[::-1]
    return sign + int_part + dec_part
コード例 #57
0
    def verify_ogr_field(self, ogr_field, model_field):
        """
        Verifies if the OGR Field contents are acceptable to the Django
        model field.  If they are, the verified value is returned,
        otherwise the proper exception is raised.
        """
        if (isinstance(ogr_field, OFTString)
                and isinstance(model_field,
                               (models.CharField, models.TextField))):
            if self.encoding:
                # The encoding for OGR data sources may be specified here
                # (e.g., 'cp437' for Census Bureau boundary files).
                val = force_text(ogr_field.value, self.encoding)
            else:
                val = ogr_field.value
                if model_field.max_length and len(
                        val) > model_field.max_length:
                    raise InvalidString(
                        '%s model field maximum string length is %s, given %s characters.'
                        % (model_field.name, model_field.max_length, len(val)))
        elif isinstance(ogr_field, OFTReal) and isinstance(
                model_field, models.DecimalField):
            try:
                # Creating an instance of the Decimal value to use.
                d = Decimal(str(ogr_field.value))
            except:
                raise InvalidDecimal('Could not construct decimal from: %s' %
                                     ogr_field.value)

            # Getting the decimal value as a tuple.
            dtup = d.as_tuple()
            digits = dtup[1]
            d_idx = dtup[2]  # index where the decimal is

            # Maximum amount of precision, or digits to the left of the decimal.
            max_prec = model_field.max_digits - model_field.decimal_places

            # Getting the digits to the left of the decimal place for the
            # given decimal.
            if d_idx < 0:
                n_prec = len(digits[:d_idx])
            else:
                n_prec = len(digits) + d_idx

            # If we have more than the maximum digits allowed, then throw an
            # InvalidDecimal exception.
            if n_prec > max_prec:
                raise InvalidDecimal(
                    'A DecimalField with max_digits %d, decimal_places %d must round to an absolute value less than 10^%d.'
                    % (model_field.max_digits, model_field.decimal_places,
                       max_prec))
            val = d
        elif isinstance(ogr_field, (OFTReal, OFTString)) and isinstance(
                model_field, models.IntegerField):
            # Attempt to convert any OFTReal and OFTString value to an OFTInteger.
            try:
                val = int(ogr_field.value)
            except:
                raise InvalidInteger('Could not construct integer from: %s' %
                                     ogr_field.value)
        else:
            val = ogr_field.value
        return val
コード例 #58
0
def floatformat(text, arg=-1):
    """
    Displays a float to a specified number of decimal places.

    If called without an argument, it displays the floating point number with
    one decimal place -- but only if there's a decimal place to be displayed:

    * num1 = 34.23234
    * num2 = 34.00000
    * num3 = 34.26000
    * {{ num1|floatformat }} displays "34.2"
    * {{ num2|floatformat }} displays "34"
    * {{ num3|floatformat }} displays "34.3"

    If arg is positive, it will always display exactly arg number of decimal
    places:

    * {{ num1|floatformat:3 }} displays "34.232"
    * {{ num2|floatformat:3 }} displays "34.000"
    * {{ num3|floatformat:3 }} displays "34.260"

    If arg is negative, it will display arg number of decimal places -- but
    only if there are places to be displayed:

    * {{ num1|floatformat:"-3" }} displays "34.232"
    * {{ num2|floatformat:"-3" }} displays "34"
    * {{ num3|floatformat:"-3" }} displays "34.260"

    If the input float is infinity or NaN, the (platform-dependent) string
    representation of that value will be displayed.
    """

    try:
        input_val = repr(text)
        d = Decimal(input_val)
    except InvalidOperation:
        try:
            d = Decimal(str(float(text)))
        except (ValueError, InvalidOperation, TypeError):
            return ''
    try:
        p = int(arg)
    except ValueError:
        return input_val

    try:
        m = int(d) - d
    except (ValueError, OverflowError, InvalidOperation):
        return input_val

    if not m and p < 0:
        return mark_safe(formats.number_format('%d' % (int(d)), 0))

    if p == 0:
        exp = Decimal(1)
    else:
        exp = Decimal('1.0') / (Decimal(10)**abs(p))
    # Set the precision high enough to avoid an exception (#15789).
    tupl = d.as_tuple()
    units = len(tupl[1])
    units += -tupl[2] if m else tupl[2]
    prec = abs(p) + units + 1

    # Avoid conversion to scientific notation by accessing `sign`, `digits`,
    # and `exponent` from Decimal.as_tuple() directly.
    sign, digits, exponent = d.quantize(exp, ROUND_HALF_UP,
                                        Context(prec=prec)).as_tuple()
    digits = [str(digit) for digit in reversed(digits)]
    while len(digits) <= abs(exponent):
        digits.append('0')
    digits.insert(-exponent, '.')
    if sign:
        digits.append('-')
    number = ''.join(reversed(digits))
    return mark_safe(formats.number_format(number, abs(p)))
コード例 #59
0
class Manager:
    model: Linear
    precision: Optional[Decimal] = None
    storage: str
    errors: List[Decimal]

    def __init__(self, storage: str, learning_rate: Optional[Decimal] = None):
        """
        :param storage: file for coefficients
        :param learning_rate: coefficient for training
        """
        try:
            self.model = Linear(learning_rate)
        except base_reg.InvalidRegression as ex:
            raise InvalidModel(str(ex))
        self.storage = storage
        if not os.path.isfile(self.storage):
            self._reset_file()
        self.errors = []

    def load(self):
        """
        load coefficients from file
        :return:
        """
        coeffs = dict()
        with open(self.storage, 'r') as storage:
            line = storage.readline()
        try:
            coeffs = json.loads(line)
        except json.decoder.JSONDecodeError:
            self._reset_file()
        if 'coefficients' not in coeffs:
            raise InvalidModel(
                'Coefficients aren`t set, you should train your model'
            )

        try:
            self.model.set_thetas([Decimal(x) for x in coeffs['coefficients']])
            if 'precision' in coeffs:
                self.precision = Decimal(coeffs['precision'])
        except (InvalidOperation, base_reg.InvalidRegression):
            raise InvalidData('Coefficients aren`t valid')

    def predict(self, x_value: Decimal) -> Prediction:
        """
        :param x_value: request for prediction
        :return: predicted result by precision of request value;
                precision
        """
        x_prec = -x_value.as_tuple().exponent
        row_result = self.model.func(x_value)
        y_prec = self._get_round_factor()
        return Prediction(
            x=x_value,
            y=round(row_result, x_prec),
            y_with_precision=round(row_result, y_prec) if y_prec else None,
            precision=round(self.precision, y_prec) if y_prec else None,
        )

    def plot_errors(self):
        plt.title('RMS errors')
        plt.xlabel('training iterations')
        plt.ylabel('log(errors)')
        plt.plot(range(len(self.errors)),
                 [math.log(er) for er in self.errors], color='r')

    def plot_function(self, data: Data):
        """
        :param data: plot function by trained coefficients
        """
        plt.xlabel(data.x_alias)
        plt.ylabel(data.y_alias)
        plt.plot(
            data.x_boarders,
            [
                self.model.func(data.x_boarders[0]),
                self.model.func(data.x_boarders[1]),
            ],
            color='k',
        )

    def train(self, data: Data, iterations: int):
        """
        Dump calculated coefficients to storage
        :param data: preloaded Data for training
        :param iterations: number of training iterations
        """
        xs = data.normalize_xs()
        for i in range(iterations):
            self.model.one_round(xs, data.points_y)
            errors = [
                self.model.loss(x, y) for x, y in zip(xs, data.points_y)
            ]
            self.errors.append(Decimal(math.sqrt(sum(errors) / len(xs))))

        self.model.rescale_thetas(data.x_norm_coeff, data.x_boarders[0])
        if not self.errors:
            raise InvalidModel('Too few training iterations')
        self.precision = self.errors[-1]
        self._dump()

    def _get_round_factor(self) -> Optional[int]:
        if not self.precision:
            return None
        prec = self.precision.as_tuple()
        return -len(prec.digits) - prec.exponent + 1

    def _dump(self):
        f = open(self.storage, 'w')
        coefficients = {
            'coefficients': [str(x) for x in self.model.thetas],
            'precision': str(self.precision),
        }
        f.write(json.dumps(coefficients))

    def _reset_file(self):
        with open(self.storage, 'w') as storage:
            storage.write('{}')
        print(f'-> Reset file "{self.storage}"')
コード例 #60
0
ファイル: defaultfilters.py プロジェクト: 03do-new30/example
def floatformat(text, arg=-1):
    """
    Display a float to a specified number of decimal places.

    If called without an argument, display the floating point number with one
    decimal place -- but only if there's a decimal place to be displayed:

    * num1 = 34.23234
    * num2 = 34.00000
    * num3 = 34.26000
    * {{ num1|floatformat }} displays "34.2"
    * {{ num2|floatformat }} displays "34"
    * {{ num3|floatformat }} displays "34.3"

    If arg is positive, always display exactly arg number of decimal places:

    * {{ num1|floatformat:3 }} displays "34.232"
    * {{ num2|floatformat:3 }} displays "34.000"
    * {{ num3|floatformat:3 }} displays "34.260"

    If arg is negative, display arg number of decimal places -- but only if
    there are places to be displayed:

    * {{ num1|floatformat:"-3" }} displays "34.232"
    * {{ num2|floatformat:"-3" }} displays "34"
    * {{ num3|floatformat:"-3" }} displays "34.260"

    If arg has the 'g' suffix, force the result to be grouped by the
    THOUSAND_SEPARATOR for the active locale. When the active locale is
    en (English):

    * {{ 6666.6666|floatformat:"2g" }} displays "6,666.67"
    * {{ 10000|floatformat:"g" }} displays "10,000"

    If the input float is infinity or NaN, display the string representation
    of that value.
    """
    force_grouping = False
    if isinstance(arg, str) and arg.endswith('g'):
        force_grouping = True
        arg = arg[:-1] or -1
    try:
        input_val = repr(text)
        d = Decimal(input_val)
    except InvalidOperation:
        try:
            d = Decimal(str(float(text)))
        except (ValueError, InvalidOperation, TypeError):
            return ''
    try:
        p = int(arg)
    except ValueError:
        return input_val

    try:
        m = int(d) - d
    except (ValueError, OverflowError, InvalidOperation):
        return input_val

    if not m and p < 0:
        return mark_safe(
            formats.number_format('%d' % (int(d)),
                                  0,
                                  force_grouping=force_grouping), )

    exp = Decimal(1).scaleb(-abs(p))
    # Set the precision high enough to avoid an exception (#15789).
    tupl = d.as_tuple()
    units = len(tupl[1])
    units += -tupl[2] if m else tupl[2]
    prec = abs(p) + units + 1

    # Avoid conversion to scientific notation by accessing `sign`, `digits`,
    # and `exponent` from Decimal.as_tuple() directly.
    rounded_d = d.quantize(exp, ROUND_HALF_UP, Context(prec=prec))
    sign, digits, exponent = rounded_d.as_tuple()
    digits = [str(digit) for digit in reversed(digits)]
    while len(digits) <= abs(exponent):
        digits.append('0')
    digits.insert(-exponent, '.')
    if sign and rounded_d:
        digits.append('-')
    number = ''.join(reversed(digits))
    return mark_safe(
        formats.number_format(number, abs(p), force_grouping=force_grouping), )