I try to print only the selected number of Pi, it returns with the error "Decimal has no attribute: __getitem__

def pi():
    prompt=">>> "
    print "\nWARNING: Pi may take some time to be calculated and may not always be correct beyond 100 digits."
    print "\nShow Pi to what digit?"
    n=raw_input(prompt)
    from decimal import Decimal, localcontext
    with localcontext() as ctx:
        ctx.prec = 10000
        pi = Decimal(0) 
        for k in range(350): 
            pi += (Decimal(4)/(Decimal(8)*k+1) - Decimal(2)/(Decimal(8)*k+4) - Decimal(1)/(Decimal(8)*k+5) - Decimal(1)/(Decimal(8)*k+6)) / Decimal(16)**k
    print pi[:int(n)]
pi()




Traceback (most recent call last):
  File "/Users/patrickcook/Documents/Pi", line 13, in <module>
    pi()
  File "/Users/patrickcook/Documents/Pi", line 12, in pi
    print pi[:int(n)]
TypeError: 'Decimal' object has no attribute '__getitem__'
-3
source share
4 answers

You are trying to treat it pias an array when it is Decimal. I think what you are looking for quantize: https://docs.python.org/2/library/decimal.html

+2
source

I was bored how long the process it took (this 350 iteration loop is a killer), but the answer seems simple. The object is Decimalnot indexable as you have it.

You probably want to wrap it first in a string and then process it to get the numbers:

print str(pi)[:int(n)+1]   # ignore decimal point in digit count.

, , . , PI :

3.141592653589

( , ), 3.1415, 3.1416.

+1

pi, . ""; mpmath , "" pi e. , Decimal , .

#!/usr/bin/env python

''' The Salamin / Brent / Gauss Arithmetic-Geometric Mean pi formula.

    Let A[0] = 1, B[0] = 1/Sqrt(2)

    Then iterate from 1 to 'n'.
    A[n] = (A[n-1] + B[n-1])/2
    B[n] = Sqrt(A[n-1]*B[n-1])
    C[n] = (A[n-1]-B[n-1])/2

    PI[n] = 4A[n+1]^2 / (1-(Sum (for j=1 to n; 2^(j+1))*C[j]^2))

    Written by PM 2Ring 2008.10.19
    Converted to use Decimal 2014.10.21
'''

import sys
from decimal import Decimal, getcontext, ROUND_DOWN


def AGM_pi(m):
    a, b = Decimal(1), Decimal(2).sqrt() / 2
    s, k = Decimal(0), Decimal(4)

    for i in xrange(m):
        c = (a - b) / 2
        a, b = (a + b) / 2, (a * b).sqrt()

        s += k * c * c

        #In case we want to see intermediate results
        if False:
            pi = 4 * a * a / (1 - s)
            print "%2d:\n%s\n" % (i, pi)
        k *= 2
    return 4 * a * a / (1 - s)


def main():
    prec = len(sys.argv) > 1 and int(sys.argv[1]) or 50

    #Add 1 for the digit before the decimal point,
    #plus a few more to compensate for rounding errors.
    #delta == 7 handles the Feynman point, which has six 9s followed by an 8
    delta = 3
    prec += 1 + delta

    ctx = getcontext()
    ctx.prec = prec 

    #Calculate how many loops are required. 
    #The precision of the AGM value doubles on every loop.
    i, m = prec, 0
    while i>0:
        i >>= 1; m += 1

    pi = AGM_pi(m)

    #Round down so all printed digits are (usually) correct
    ctx.rounding = ROUND_DOWN
    ctx.prec -= delta
    pi = +pi

    print "pi ~=\n%s" % pi


if __name__ == '__main__':
    main()
+1
source
An object

A Decimalcannot be cut to obtain single digits. However, a string can, so first convert it to a string.

print str(pi)[:int(n)]

You may need to adjust nfor the decimal point and the desired range of digits.

0
source

All Articles