Jump to content

Need help with python approximation of pi

Matsozetex

I am writing a program to approximate pi using different methods, I am on my first method, Basel problem which comes in the following notation:

 

pi2/6 = 1/1 + 1/4 + 1/9 + 1/16 + 1/25 

 

My code is a function:

 

import math


percision = float(input("Enter the percision for the calculation: "))

def basel(percision):
    basel_result = 0
    basel_total = math.sqrt(basel_result * 6)
    basel_term = 0
    for basel_term in range(1, basel_term):
        if math.sqrt(6* basel_result) < math.pi(percision): #loop keeps adding until the result is within the accuracy value of pi
            basel_term = basel_term + 1
            basel_result = basel_result + 1/basel_term**2
    return(basel_total, basel_term)

print(basel(percision))

 

However, every time I enter the percision value (say 0.1) it returns the output (0.0, 0).

 

What am I doing wrong?

Link to comment
Share on other sites

Link to post
Share on other sites

A few things

  • This is printing the result of the function basel, which is a tuple.
  • The first item in the tuple, basel_total, is 0, because what sets it is the square root of 0 * 6. The 0 comes from basel_result which was defined to be 0. basel_total is not used anywhere else.
  • The for loop never runs because the way it's set up is "Starting from 1, while the step counter is less than 0, do the thing and increase the step counter by 1". Since the step counter is never less than 0, it ends immediately.
Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, Mira Yurizaki said:

A few things

  • This is printing the result of the function basel, which is a tuple.
  • The first item in the tuple, basel_total, is 0, because what sets it is the square root of 0 * 6. The 0 comes from basel_result which was defined to be 0. basel_total is not used anywhere else.
  • The for loop never runs because the way it's set up is "Starting from 1, while the step counter is less than 0, do the thing and increase the step counter by 1". Since the step counter is never less than 0, it ends immediately.

Would it be a wise move to use a "while" loop with the conditions of the "if" statement instead of the for loop. As the output of the function has to be the number of terms to approximate pi. For example, if the input is the precision of (0.1) then it should output (approximation to such precision, basel_terms).

 

Link to comment
Share on other sites

Link to post
Share on other sites

import math

pi = float(math.pi)
percision = float(input("Enter the percision for the calculation: "))
base_list = []


def basel(percision):
    basel_result = 0
    basel_term = 0
    basel_total = 0
    while basel_total <= (math.pi - percision):
        basel_term = basel_term + 1
        basel_result = (1/(basel_term**2))
        base_list.append(basel_result)
        basel_total = math.sqrt((sum(base_list)) * 6)
    return(basel_total, basel_term)
print(basel(percision))

This is what I have made, and it works, flawlessly.

If it looks good then good, if my code looks like spaghetti is there any tips/conventions that you can offer me.

 

Also I will insert comments after I finish my other 3 approximations (internal sadface).

Link to comment
Share on other sites

Link to post
Share on other sites

19 hours ago, Matsozetex said:

import math

pi = float(math.pi)
percision = float(input("Enter the percision for the calculation: "))
base_list = []


def basel(percision):
    basel_result = 0
    basel_term = 0
    basel_total = 0
    while basel_total <= (math.pi - percision):
        basel_term = basel_term + 1
        basel_result = (1/(basel_term**2))
        base_list.append(basel_result)
        basel_total = math.sqrt((sum(base_list)) * 6)
    return(basel_total, basel_term)
print(basel(percision))

This is what I have made, and it works, flawlessly.

If it looks good then good, if my code looks like spaghetti is there any tips/conventions that you can offer me.

 

Also I will insert comments after I finish my other 3 approximations (internal sadface).

Your code isn't spaghetti and follows PEP8 style guidelines pretty well. The only thing I can think of is to add a little bit of error catching for invalid input to avoid run time errors in your program...but that's pretty darn nit picky especially since this is probably just something you're using for yourself...anyways that's the only change I made, I didn't change your function at all.

 

import math

if __name__ == "__main__":

    def basel(percision):
        basel_result = 0
        basel_term = 0
        basel_total = 0
        while basel_total <= (math.pi - percision):
            basel_term = basel_term + 1
            basel_result = 1/(basel_term**2)
            base_list.append(basel_result)
            basel_total = math.sqrt((sum(base_list)) * 6)
        return(basel_total, basel_term)

    try:
        percision = float(input("Enter the percision for the calculation: "))
        pi = float(math.pi)
        base_list = []
    except ValueError as error:
        # Something not convertable to float was entered, like a string for example
        print(error)
    else:
        print(basel(percision))

 

Current PC build: [CPU: Intel i7 8700k] [GPU: GTX 1070 Asus ROG Strix] [Ram: Corsair LPX 32GB 3000MHz] [Mobo: Asus Prime Z370-A] [SSD: Samsung 970 EVO 500GB primary + Samsung 860 Evo 1TB secondary] [PSU: EVGA SuperNova G2 750w 80plus] [Monitors: Dual Dell Ultrasharp U2718Qs, 4k IPS] [Case: Fractal Design R5]

Link to comment
Share on other sites

Link to post
Share on other sites

On 3/16/2019 at 6:59 AM, Spev said:

-snip-

 

Oh, I already know about the code for input validation. But as you said, since I know there is no input validation, and I will be the one using it, there is no need. Heck, if it doesn't run I'll exactly know why, because my stupid self had fat finger syndrome.

 

Update:

 

I got all four things working:

from math import pi
from math import sqrt


percision = float(input("Enter the percision for the calculation: "))


def basel(percision):
    basel_result = 0
    basel_term = 0
    basel_total = 0
    base_list = []
    while basel_total <= (pi - percision):
        basel_term = basel_term + 1
        basel_result = (1/(basel_term**2))
        base_list.append(basel_result)
        basel_total = sqrt((sum(base_list)) * 6)
    return(basel_total, basel_term)
print(basel(percision))


def wallis(percision):
    wallis_result = 1
    wallis_total = 0
    wallis_term = 0
    while wallis_total <= (pi - percision):
        wallis_term = wallis_term + 1
        wallis_result = wallis_result  *((2 * wallis_term) * (2 * wallis_term)) / ((2 * wallis_term - 1) * (2 * wallis_term + 1))
        wallis_total = wallis_result * 2
    return (wallis_total, wallis_term)
#print(wallis(percision))


def taylor(percision):
    taylor_result = 0
    taylor_total = 0
    taylor_term = 0
    if taylor_total * 4 != (pi-percision):
        while True:
            taylor_term += 1
            print(taylor_term)
            taylor_result = taylor_result + ((-1)**(taylor_term + 1)) * (1/(2*taylor_term-1))
            print(taylor_result)
            taylor_total = taylor_result * 4
            if taylor_term != 1 and round(pi - taylor_total, (len(str(percision).replace('.',''))) -1) == -1 * percision: #take the length of str(percision), remove the decimal point and -1 to remove counting the 0
                break #required as the first erm of taylor algorithim total would be 4 and would instantly end the function
    return(taylor_total,taylor_term)
#print(taylor(percision))


def spigot(percision):
    spigot_result = 0
    spigot_total = 0
    spigot_term = 0
    spigot_past = 1
    spig_count = 1
    nat_list = []
    fib_list = [1, 1]
    result_list = []
    while spigot_total * 2 <= (pi - percision):
        nat_list.append(spigot_term+1) #creates list of natural numbers, including 0
        fib_list.append(fib_list[spigot_term]+fib_list[spigot_term+1]) #creates list of fibonnaci squence
        spigot_result = spigot_past * (fib_list[spigot_term]) / ((nat_list[spigot_term]* 2 -1))
        result_list.append(spigot_result)
        spigot_term +=1
        spigot_past = spigot_result
        spigot_total = sum(result_list)
        if round(pi - spigot_total *2, (len(str(percision).replace('.',''))) - 1) == -1 * percision:
            break
    return(spigot_total * 2, spigot_term + 1)
#print(spigot(percision))

The last one was a PITA, the numerator is a Fibonacci sequence and the denominator is a list of natural numbers.

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×