Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grerory-Leibnitz's series function on python - ex. 8.3 from The Coder's Apprentice

Tags:

python

I have arrived at a solution to the exercise 8.3 of "The Coder's Apprentice Learning Programming with Python 3" that is slightly differente form the author's solution. I wanted to ask here if it could be right.

The exercise's text is the follwing: The Grerory-Leibnitz series approximates pi as 4 ∗ ( 1/1 − 1/3 + 1/5 −1/7 + 1/9... ) . Write a function that returns the approximation of pi according to this series. The function gets one parameter, namely an integer that indicates how many of the terms between the parentheses must be calculated.

def leibnitz(n):
tot = 0
i=1
c=1
for x in range(0,n): 
    if c % 2 != 0: 
        tot = tot + (+1.0/i)
        i=i+2
        c=c+1
    elif c % 2 == 0:
        tot = tot + (-1.0/i)
        i=i+2
        c=c+1
return tot*4
        

print(leibnitz(98))

#by fixing a counter "c", we can manage to establish if the next fraction of the series will be a positive or a negative fraction. the first fraction in the series (1/1) is positive, so we start with a counter of "c" = 1 that is odd. then whenever a counter will be even, we consider a negative fraction and so on.

Is this solution right?


I had made an error with in the last version and updated it now.

like image 952
PwNzDust Avatar asked Mar 06 '26 06:03

PwNzDust


2 Answers

Yup, this method works perfectly. One way you can improve this is by getting rid of the variable c and replacing it with x+1.

Also, just for fun, if you import math, you can use the constant math.pi to get the error involved:

import math
def leibnitz(n):
  tot = 0
  i=1
  for x in range(0,n): 
      if (x+1) % 2 != 0: 
          tot = tot + (+1.0/i)
          i=i+2
      elif (x+1) % 2 == 0:
          tot = tot + (-1.0/i)
          i=i+2
  return tot*4
        
print(math.pi - leibnitz(98))
like image 91
Aniketh Malyala Avatar answered Mar 08 '26 18:03

Aniketh Malyala


this is a possible solution

def GL(n):
    series = []
    k=0
    for j in range(1,n,2):
        series +=[1/(j*(-1)**k)]
        k+=1
    return 4*sum(series)

but the most straight forward and pythonic solution i can found is:

4*sum([ 1/((2*i+1)*(-1)**i) for i in range(n)])

just a mathematical tip, if you want to change signal at each integer iteration, just make:

(-1)**(n)

if n is odd, it will be negative, if n is even, it will be positive.

Eg:

[(-1)**n for n in range(10)]

will return:

[1, -1, 1, -1, 1, -1, 1, -1, 1, -1]

if you want only odd numbers, you can make:

[(2*n+1) for n in range(10)]

which will return:

[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

and you can combine both to get:

[(2*n+1)*(-1)**n for n in range(10)]

[1, -3, 5, -7, 9, -11, 13, -15, 17, -19]

and putting it all together:

def GL(n):
    return 4*sum([ 1/((2*k+1)*(-1)**k) for k in range(n)])

your solution if fine, as well as in math, there are plenty of ways of making things, some are more hard and complicated, some are more simple, but at the end, what matters is to make a valid solution and your one is right.

like image 40
Guinther Kovalski Avatar answered Mar 08 '26 20:03

Guinther Kovalski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!