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.
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))
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With