[Tutor] on the way to find pi

Orri Ganel singingxduck at gmail.com
Sun Jan 23 19:59:38 CET 2005


Ali Polatel wrote:

> dear friends ,
> I found a code which calculates pi with an interesting algorithm the 
> programme code is below:
> from sys import stdout
> def f((q,r,t,k)):
>     n = (3*q+r) / t
>     if (4*q+r) / t == n:
>         return (10*q,10*(r-n*t),t,k,n)
>     else:
>         return (q*k, q*(4*k+2)+r*(2*k+1),t*(2*k+1),k+1)
> # Call pi(20) for first 20 digits, or pi() for all digits
> def pi(n=-1):
>     printed_decimal = False
>     r = f((1,0,1,1))
>     while n != 0:
>         if len(r) == 5:
>             stdout.write(str(r[4]))
>             if not printed_decimal:
>                 stdout.write('.')
>                 printed_decimal = True
>             n -= 1
>         r = f(r[:4])
>     #stdout.write('\n')
> if __name__ == '__main__':
>     from sys import argv
>     try:
>         digit_count = long(argv[1])
>     except:
>         digit_count=int(raw_input('How many digits? :'))
>         pi(digit_count)
>        
> This code gives the number in an unusual format like "3.1415'None'" it 
> has a number part and a string part . I want to seperate these from 
> easc other but I couldn't manage. I mean when I try to turn it into 
> string format then try to use things like [:4] or like that they don't 
> work.Any idea how to seperate this 'None' from the number and make it 
> a real normal number on which I can do operations like +1 -1 or like 
> that :)
> Regards
>
> ------------------------------------------------------------------------
> Do you Yahoo!?
> The all-new My Yahoo! <http://my.yahoo.com> - What will yours do?
>
>------------------------------------------------------------------------
>
>_______________________________________________
>Tutor maillist  -  Tutor at python.org
>http://mail.python.org/mailman/listinfo/tutor
>  
>
The reason for this is that pi() doesn't return anything (hence None). 
What it does do is print the result (stdout.write).  So you can either 
use it w/o print (just pi(5)) or modify the code so it returns pi all at 
once instead of printing it as it goes (this will make it seem like it 
is taking more time since it will have to calculate the whole thing 
before printing anything, instead of printing the digits one and 4 at a 
time (I've bolded the changes):

def pi(*n=1000*): *# if you set n to -1, nothing will ever be printed 
because #the loops waits for pi to be calculated before printing anything*
    *from decimal import setcontext, getcontext, Decimal, ExtendedContext*
    *setcontext(ExtendedContext) # No DvisionByZero Error
    getcontext().prec = n+1 # always just enough, and this way you can
# still perform operations on the results (if you set the precision to
# Infinity, it gives you an OverflowError to perform operations)
    pil = []*
    printed_decimal = False
    r = f((1,0,1,1))
    while n != 0:
        if len(r) == 5:
            *pil.append*(str(r[4]))
            if not printed_decimal:
                *pil.append*(('.'))
                printed_decimal = True
            n -= 1
        r = f(r[:4])
    *return Decimal(''.join(pil))

*With Decimal(), you get an accurate string representation of floating 
point numbers which treats the strings as floating point numbers:

 >>> pi(20)-3
Decimal("0.1415926535897932384")

The only reason the original pi(...) didn't have to deal with this is 
that it wrote directly to stdout, without formatting the text as string, 
float, etc.


-- 
Email: singingxduck AT gmail DOT com
AIM: singingxduck
Programming Python for the fun of it.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/tutor/attachments/20050123/d1de8329/attachment.html


More information about the Tutor mailing list