Reputation: 29
Write a program to compute the sum of the terms of the series: 4 - 8 + 12 - 16 + 20 - 24 + 28 - 32 + .... +/- n, where n is an input. Consider that n is always valid (which means it follows the series pattern).
n = int(input("Enter n: "))
sum = 0
for i in range(4,n+4,4):
sum += i - (i+2)
print("The sum of %s first terms is: %s"%(n,sum))
Can't seem to find the issues that Ihave
Upvotes: 2
Views: 5593
Reputation: 44495
Python can be used to easily compute mathematical sequences and series.
We find the sum of all values computed up to and including n
Given
the following mathematical components:
A
)B
)C
)We now implement two approaches A
and C
verified by B
.
Code
import itertools as it
n = 8
Generating Function, A
seq = [(-1)**(i + 1)*(4 * i) for i in range(1, n + 1)]
sum(seq)
# -16
Summation Equation, C
def f(n):
if n == 1:
return 1
elif n % 2 == 0:
return -n // 2
else:
return (n + 1) // 2
4*f(n)
# -16
Details
Generating Function
This first approach simply sums an arithmetic sequence generated by a list comprehension. The signs of values alternate by the expression (-1)**(i + 1)
:
seq
# [4, -8, 12, -16, 20, -24, 28, -32]
Similarly, an infinite sequence can be made using a generator expression and itertools.count
:
inf_seq = ((-1)**(i + 1)*(4 * i) for i in it.count(1))
sum(it.islice(inf_seq, n))
# -16
Here the sum is returned for a slice of n
values. Note, we can use the take
itertools recipe and itertools.accumulate
to compute some arbitrary number of summations, e.g. 10 sums (see also itertools.takewhile
).
def take(n, iterable):
"Return first n items of the iterable as a list"
return list(it.islice(iterable, n))
inf_seq = ((-1)**(i + 1)*(4 * i) for i in it.count(1))
list(take(10, it.accumulate(inf_seq)))
# [4, -4, 8, -8, 12, -12, 16, -16, 20, -20]
Summation Equation
The second approach comes from inspection, where a pattern is determined from the outputs of a sample sequence:
n 4n f(n) 4f(n)
--- ---- ---- -----
1 4 1 -> 4
2 -8 -1 -> -4
3 12 2 -> 8
4 -16 -2 -> -8
5 20 3 -> 12
6 -24 -3 -> -12
7 28 4 -> 16
8 -32 -4 -> -16
9 36 5 -> 20
10 -40 -5 -> -20
For an arbitrary final value n
, a value of the sequence is generated (4n
). When multiplied with some unknown function, f(n)
, a resultant sum is computed (4f(n)
). We determine a pattern for f(n)
by deducing the relationship between the sequence values and expected sums. Once determined, we directly implement a function that computes our desired sums.
Highlights
sum()
, operator.mul()
, etc. applied to sequences.Upvotes: 0
Reputation: 22314
First of all, know that your series sum has a closed form.
def series_sum(n):
sign = 1 if n % 2 else -1
value = (n - 1) // 2 * 4 + 4
return sign * value
series_sum(1) # 4
series_sum(2) # -4
series_sum(3) # 8
But in general, infinite series are a good usecase for generators.
def series():
value = 0
sign = -1
while True:
value += 4
sign *= -1
yield sign * value
s = series()
next(s) # 4
next(s) # -8
next(s) # 12
Thus for getting the sum you can do this.
s = series()
def sum_series(n, s):
return sum(next(s) for _ in range(n))
sum_series(5, s) # 12
An interesting question asked in the comment is also, given some value, how can we recover the sum up until that value is reached in the series. The generator approach is well suited for these kind of problems.
from itertools import takewhile
def sum_until(val):
return sum(x for x in takewhile(lambda x: -val <= x <= val, series()))
sum_until(12) # 8
Upvotes: 1
Reputation: 10729
As @John Coleman pointed out, sum += i - (i+2)
produces one result not as you expected.
Below is my solution:
Using if else
to determinate the sign, then sum up. at last, put it into another loop to create the series you'd like.
n = 9
print('N='+str(n), [sum([index*4 if index%2 else index*-4 for index in range(1, num+1)]) for num in range(1, n+1)])
n = 8
print('N='+str(n), [sum([index*4 if index%2 else index*-4 for index in range(1, num+1)]) for num in range(1, n+1)])
Output:
N=9 [4, -4, 8, -8, 12, -12, 16, -16, 20]
N=8 [4, -4, 8, -8, 12, -12, 16, -16]
[Finished in 0.178s]
Upvotes: -1
Reputation: 44918
How about an explicit formula?
def sumSeries(n):
if n / 4 % 2 == 0:
return - n / 2
else:
return (n + 4) / 2
The series doesn't do anything too interesting, it just keeps adding +4
every two steps, and flips the sign in even steps:
4 = 4
4 - 8 = -4
4 - 8 + 12 = 8
4 - 8 + 12 - 16 = -8
...
Some examples:
for n in range(4, 100, 4):
print("%d -> %d" % (n, sumSeries(n)))
Output:
4 -> 4
8 -> -4
12 -> 8
16 -> -8
20 -> 12
24 -> -12
28 -> 16
32 -> -16
36 -> 20
40 -> -20
44 -> 24
48 -> -24
52 -> 28
56 -> -28
60 -> 32
64 -> -32
Upvotes: 1