[Tutor] oops - resending as plain text

eryksun eryksun at gmail.com
Wed Apr 17 00:45:41 CEST 2013


On Tue, Apr 16, 2013 at 6:09 PM, Dave Angel <davea at davea.name> wrote:
> If the conversion itself will catch the errors, then you can just use
> try/catch to make such errors more polite to your users. That's the case if
> they enter  "charlie" when you're asking for a salary value.  But if they
> were to put  7.500 when the value is supposed to be in dollars and cents,
> then by the time it's turned into a float or decimal, the extra zero is long
> gone.

With Decimal it's not really 'long gone'. It affects the number of
significant digits retained in arithmetic operations:

    >>> from decimal import Decimal
    >>> context = decimal.getcontext()

    >>> Decimal('7.500') + Decimal('0.50')
    Decimal('8.000')

You could look specifically at the _exp attribute, or quantize with a
trap for inexact rounding:

    >>> Decimal('7.500')._exp
    -3

    def round_money(value):
        with decimal.localcontext() as ctx:
            ctx.traps[decimal.Inexact] = 1
            return Decimal(value).quantize(Decimal('1.00'))

    >>> try: round_money('7.500')
    ... except decimal.Inexact: print 'ack!'
    ...
    Decimal('7.50')

    >>> try: round_money('7.501')
    ... except decimal.Inexact: print 'ack!'
    ...
    ack!

    >>> try: round_money('charlie')
    ... except decimal.InvalidOperation as e: print 'ack!'
    ...
    ack!

Please don't print a useless error message like 'ack'; it was just a
silly example. Handle the error within the logical context of your
application.


More information about the Tutor mailing list