开发者

Decimal zero padding

I need to output decimal numbers in a price forma开发者_如何学编程t,

i.e.

10 = 10.00 11.1 = 11.10

How can I achieve this using decimal.Decimal class ?

pad_zero(Decimal('10.0'))
>>>Decimal('10.00')

*EDIT:*format method does not fit my need because I need to pass it on as decimal, I understand though, that i can convert it back to afterwards, but such to-and-fro seems somewhat unpythonic.


try this :

Decimal('10.0').quantize(Decimal('1.00'))


For currency calculations, I prefer this.

>>> penny=Decimal('0.01')
>>> Decimal('10').quantize(penny)
Decimal('10.00')

It's wordy but explicit.

For currency formatting, I use format().


There's a good example of how to format Decimal objects as a "money formatted string" in the Python documentation for the decimal module.

I'm a little surprised at how awkward it is -- usually formatting in Python is fairly straightforward.


I would follow the moneyfmt recipe in the Python Decimal documentation Recipes section.

This recipe creates a function that takes a decimal value and returns a string formatted as a currency.

>>> d = Decimal('10.0')
>>> moneyfmt(d, curr='$')
'$10.00'

Below is the actual code, copied sans examples from the Decimal Recipe documentation:

def moneyfmt(value, places=2, curr='', sep=',', dp='.',
             pos='', neg='-', trailneg=''):
    """Convert Decimal to a money formatted string.

    places:  required number of places after the decimal point
    curr:    optional currency symbol before the sign (may be blank)
    sep:     optional grouping separator (comma, period, space, or blank)
    dp:      decimal point indicator (comma or period)
             only specify as blank when places is zero
    pos:     optional sign for positive numbers: '+', space or blank
    neg:     optional sign for negative numbers: '-', '(', space or blank
    trailneg:optional trailing minus indicator:  '-', ')', space or blank

    """
    q = Decimal(10) ** -places      # 2 places --> '0.01'
    sign, digits, exp = value.quantize(q).as_tuple()
    result = []
    digits = map(str, digits)
    build, next = result.append, digits.pop
    if sign:
        build(trailneg)
    for i in range(places):
        build(next() if digits else '0')
    build(dp)
    if not digits:
        build('0')
    i = 0
    while digits:
        build(next())
        i += 1
        if i == 3 and digits:
            i = 0
            build(sep)
    build(curr)
    build(neg if sign else pos)
    return ''.join(reversed(result))


It should be quite simple like this (if you don't use decimal.Decimal class as suggested by S. Lott) :

    >>> decimal_fmt = "{:.2f}"   
    >>> x = 10
    >>> print(decimal_fmt.format(x))
    10.00
    >>> x = 11.1
    >>> print(decimal_fmt.format(x))
    11.10


Set the precision for your context before you create your instance:

>>> getcontext().prec = 2


Use locale currency. It works flawlessly with the Decimal class.

import locale
locale.setlocale(locale.LC_ALL, '') # this sets locale to the current Operating System value
print(locale.currency(Decimal('1346896.67544'), grouping=True, symbol=True))

will output in my Windows 10 configured to Brazilian Portuguese:

R$ 1.346.896,68

It is somewhat verbose, so if you will use it a lot, maybe it is better to predefine some parameters and have a shorter name and use it inside a f-string:

fmt = lambda x: locale.currency(x, grouping=True, symbol=True)
print(f"Value: {fmt(1346896.67444)}"

It works with Decimal and float. You can configure to symbol to False if it isn't necessary.


Instead of using Decimal('10.0') you could use float('10.0') which will produce the effect you require.

Edit: Realised that you were looking to represent it with 2 decimal places. In this case, there's a good example in the Python docs for converting a Decimal() object to money: http://docs.python.org/library/decimal.html#recipes

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜