5.6.1 Quick-start Tutorial

##
5.6.1 Quick-start Tutorial

The usual start to using decimals is importing the module, viewing the current context with `getcontext()` and, if necessary, setting new values for precision, rounding, or enabled traps:

    >>> from decimal import *
    >>> getcontext()
    Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
            capitals=1, flags=[], traps=[Overflow, InvalidOperation,
            DivisionByZero])

    >>> getcontext().prec = 7       # Set a new precision

Decimal instances can be constructed from integers, strings or tuples. To create a Decimal from a `float`, first convert it to a string. This serves as an explicit reminder of the details of the conversion (including representation error). Decimal numbers include special values such as `NaN` which stands for ``Not a number'', positive and negative `Infinity`, and `-0`.

    >>> Decimal(10)
    Decimal("10")
    >>> Decimal("3.14")
    Decimal("3.14")
    >>> Decimal((0, (3, 1, 4), -2))
    Decimal("3.14")
    >>> Decimal(str(2.0 ** 0.5))
    Decimal("1.41421356237")
    >>> Decimal("NaN")
    Decimal("NaN")
    >>> Decimal("-Infinity")
    Decimal("-Infinity")

The significance of a new Decimal is determined solely by the number of digits input. Context precision and rounding only come into play during arithmetic operations.

    >>> getcontext().prec = 6
    >>> Decimal('3.0')
    Decimal("3.0")
    >>> Decimal('3.1415926535')
    Decimal("3.1415926535")
    >>> Decimal('3.1415926535') + Decimal('2.7182818285')
    Decimal("5.85987")
    >>> getcontext().rounding = ROUND_UP
    >>> Decimal('3.1415926535') + Decimal('2.7182818285')
    Decimal("5.85988")

Decimals interact well with much of the rest of python. Here is a small decimal floating point flying circus:

    >>> data = map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split())
    >>> max(data)
    Decimal("9.25")
    >>> min(data)
    Decimal("0.03")
    >>> sorted(data)
    [Decimal("0.03"), Decimal("1.00"), Decimal("1.34"), Decimal("1.87"),
     Decimal("2.35"), Decimal("3.45"), Decimal("9.25")]
    >>> sum(data)
    Decimal("19.29")
    >>> a,b,c = data[:3]
    >>> str(a)
    '1.34'
    >>> float(a)
    1.3400000000000001
    >>> round(a, 1)     # round() first converts to binary floating point
    1.3
    >>> int(a)
    1
    >>> a * 5
    Decimal("6.70")
    >>> a * b
    Decimal("2.5058")
    >>> c % a
    Decimal("0.77")

The `quantize()` method rounds a number to a fixed exponent. This method is useful for monetary applications that often round results to a fixed number of places:

    >>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
    Decimal("7.32")
    >>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)
    Decimal("8")

As shown above, the `getcontext()` function accesses the current context and allows the settings to be changed. This approach meets the needs of most applications.

For more advanced work, it may be useful to create alternate contexts using the Context() constructor. To make an alternate active, use the `setcontext()` function.

In accordance with the standard, the `Decimal` module provides two ready to use standard contexts, `BasicContext` and `ExtendedContext`. The former is especially useful for debugging because many of the traps are enabled:

    >>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)
    >>> setcontext(myothercontext)
    >>> Decimal(1) / Decimal(7)
    Decimal("0.142857142857142857142857142857142857142857142857142857142857")

    >>> ExtendedContext
    Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
            capitals=1, flags=[], traps=[])
    >>> setcontext(ExtendedContext)
    >>> Decimal(1) / Decimal(7)
    Decimal("0.142857143")
    >>> Decimal(42) / Decimal(0)
    Decimal("Infinity")

    >>> setcontext(BasicContext)
    >>> Decimal(42) / Decimal(0)
    Traceback (most recent call last):
      File "<pyshell#143>", line 1, in -toplevel-
        Decimal(42) / Decimal(0)
    DivisionByZero: x / 0

Contexts also have signal flags for monitoring exceptional conditions encountered during computations. The flags remain set until explicitly cleared, so it is best to clear the flags before each set of monitored computations by using the `clear_flags()` method.

    >>> setcontext(ExtendedContext)
    >>> getcontext().clear_flags()
    >>> Decimal(355) / Decimal(113)
    Decimal("3.14159292")
    >>> getcontext()
    Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
            capitals=1, flags=[Inexact, Rounded], traps=[])

The flags entry shows that the rational approximation to `Pi` was rounded (digits beyond the context precision were thrown away) and that the result is inexact (some of the discarded digits were non-zero).

Individual traps are set using the dictionary in the `traps` field of a context:

    >>> Decimal(1) / Decimal(0)
    Decimal("Infinity")
    >>> getcontext().traps[DivisionByZero] = 1
    >>> Decimal(1) / Decimal(0)
    Traceback (most recent call last):
      File "<pyshell#112>", line 1, in -toplevel-
        Decimal(1) / Decimal(0)
    DivisionByZero: x / 0

Most programs adjust the current context only once, at the beginning of the program. And, in many applications, data is converted to `Decimal` with a single cast inside a loop. With context set and decimals created, the bulk of the program manipulates the data no differently than with other Python numeric types.