Printing every 10th result in an alternating $ pm $ series
up vote
11
down vote
favorite
Problem:
In the following expression $$ 1 - 2 + 3 cdots + 99 - 100 $$ print result every 10th (10, 20, 30, ...) calculation.
My code:
result = 0
operand = 1
counter = 0
for i in range(1, 101):
result = result + (i * operand)
counter = counter + 1
operand = operand * -1 #Convert between positive and negative number
if counter >= 10:
counter = 0
print(result)
My problem:
I think this code has not good readability. For example, I used $ * -1 $ for changing positive and negative number. But it requires math skill(multiplying a negative number) to understand code.
And I don't sure variable name 'counter' and 'operand' is appropriate for this context.
Is there any suggestion?
python python-3.x
add a comment |
up vote
11
down vote
favorite
Problem:
In the following expression $$ 1 - 2 + 3 cdots + 99 - 100 $$ print result every 10th (10, 20, 30, ...) calculation.
My code:
result = 0
operand = 1
counter = 0
for i in range(1, 101):
result = result + (i * operand)
counter = counter + 1
operand = operand * -1 #Convert between positive and negative number
if counter >= 10:
counter = 0
print(result)
My problem:
I think this code has not good readability. For example, I used $ * -1 $ for changing positive and negative number. But it requires math skill(multiplying a negative number) to understand code.
And I don't sure variable name 'counter' and 'operand' is appropriate for this context.
Is there any suggestion?
python python-3.x
Do you need the finalresult
of the whole sum and just want to report progress as the summing is going on, or do you want the sum of only every 10th element and also print progress?
– Graipher
12 hours ago
Maybe I'm missing something, but isn't the alternating sum you want $$-sum_{n=1}^{m} n (-1)^n equiv -frac{1}{4}-frac{1}{4}(-1)^m (2m+1)$$ And then you can substitute m = 10n or whatever value you need. Far faster than looping.
– esote
2 hours ago
@Graipher I want to report progress as the summing is going on. but original question is not clear. So i think it should be interpreted like this.
– jun
2 hours ago
add a comment |
up vote
11
down vote
favorite
up vote
11
down vote
favorite
Problem:
In the following expression $$ 1 - 2 + 3 cdots + 99 - 100 $$ print result every 10th (10, 20, 30, ...) calculation.
My code:
result = 0
operand = 1
counter = 0
for i in range(1, 101):
result = result + (i * operand)
counter = counter + 1
operand = operand * -1 #Convert between positive and negative number
if counter >= 10:
counter = 0
print(result)
My problem:
I think this code has not good readability. For example, I used $ * -1 $ for changing positive and negative number. But it requires math skill(multiplying a negative number) to understand code.
And I don't sure variable name 'counter' and 'operand' is appropriate for this context.
Is there any suggestion?
python python-3.x
Problem:
In the following expression $$ 1 - 2 + 3 cdots + 99 - 100 $$ print result every 10th (10, 20, 30, ...) calculation.
My code:
result = 0
operand = 1
counter = 0
for i in range(1, 101):
result = result + (i * operand)
counter = counter + 1
operand = operand * -1 #Convert between positive and negative number
if counter >= 10:
counter = 0
print(result)
My problem:
I think this code has not good readability. For example, I used $ * -1 $ for changing positive and negative number. But it requires math skill(multiplying a negative number) to understand code.
And I don't sure variable name 'counter' and 'operand' is appropriate for this context.
Is there any suggestion?
python python-3.x
python python-3.x
edited 1 hour ago
hjpotter92
5,11111539
5,11111539
asked 13 hours ago
jun
754
754
Do you need the finalresult
of the whole sum and just want to report progress as the summing is going on, or do you want the sum of only every 10th element and also print progress?
– Graipher
12 hours ago
Maybe I'm missing something, but isn't the alternating sum you want $$-sum_{n=1}^{m} n (-1)^n equiv -frac{1}{4}-frac{1}{4}(-1)^m (2m+1)$$ And then you can substitute m = 10n or whatever value you need. Far faster than looping.
– esote
2 hours ago
@Graipher I want to report progress as the summing is going on. but original question is not clear. So i think it should be interpreted like this.
– jun
2 hours ago
add a comment |
Do you need the finalresult
of the whole sum and just want to report progress as the summing is going on, or do you want the sum of only every 10th element and also print progress?
– Graipher
12 hours ago
Maybe I'm missing something, but isn't the alternating sum you want $$-sum_{n=1}^{m} n (-1)^n equiv -frac{1}{4}-frac{1}{4}(-1)^m (2m+1)$$ And then you can substitute m = 10n or whatever value you need. Far faster than looping.
– esote
2 hours ago
@Graipher I want to report progress as the summing is going on. but original question is not clear. So i think it should be interpreted like this.
– jun
2 hours ago
Do you need the final
result
of the whole sum and just want to report progress as the summing is going on, or do you want the sum of only every 10th element and also print progress?– Graipher
12 hours ago
Do you need the final
result
of the whole sum and just want to report progress as the summing is going on, or do you want the sum of only every 10th element and also print progress?– Graipher
12 hours ago
Maybe I'm missing something, but isn't the alternating sum you want $$-sum_{n=1}^{m} n (-1)^n equiv -frac{1}{4}-frac{1}{4}(-1)^m (2m+1)$$ And then you can substitute m = 10n or whatever value you need. Far faster than looping.
– esote
2 hours ago
Maybe I'm missing something, but isn't the alternating sum you want $$-sum_{n=1}^{m} n (-1)^n equiv -frac{1}{4}-frac{1}{4}(-1)^m (2m+1)$$ And then you can substitute m = 10n or whatever value you need. Far faster than looping.
– esote
2 hours ago
@Graipher I want to report progress as the summing is going on. but original question is not clear. So i think it should be interpreted like this.
– jun
2 hours ago
@Graipher I want to report progress as the summing is going on. but original question is not clear. So i think it should be interpreted like this.
– jun
2 hours ago
add a comment |
4 Answers
4
active
oldest
votes
up vote
8
down vote
accepted
The first thing you can do to make the sign change obvious is to use operand = -operand
, this way you avoid the need for the multiplication operator. Also changing the operand
name to sign can help.
You also don't need counter
as it will be equal to i
before the test. Just change the test to use the modulo (%
) operator instead of reseting counter
.
And using augmented assignment for result
can lead to a more readable line too:
result = 0
sign = 1
for i in range(1, 101):
result += sign * i
sign = -sign
if i % 10 == 0:
print(result)
Now, this probably need to be made more reusable, this means building a function out of this code and avoiding mixing computation and I/Os:
def alternating_sum(start=1, stop=100, step=10):
result = 0
sign = 1
for i in range(start, stop+1):
result += sign * i
sign = -sign
if i % step == 0:
yield result
Usage being:
for result in alternating_sum(1, 100, 10):
print(result)
Also, depending on the problem at hand, you can leverage the fact that every two numbers add-up to -1
. So every 10 numbers add-up to -5
. If you don't need much genericity, you can simplify the code down to:
def alternating_every_ten(end=100):
reports = end // 10
for i in range(1, reports + 1):
print('After', 10 * i, 'sums, result is', -5 * i)
I would recommend writing expressions with a sign variable assign * value
to match the standard method of writing numbers.
– Apollys
9 hours ago
@Apollys Right, fixed.
– Mathias Ettinger
7 hours ago
add a comment |
up vote
5
down vote
instead of doing the +-
by hand, you can use the fact that (-1) ** (i-1) * i for i in range(101)
alternates the values
Further on, you can use itertools.accumulate
and itertools.islice
to take the cumulative sum and select every 10th number
numbers = (int((-1) ** (i-1) * i) for i in range(101))
cum_sum = itertools.accumulate(numbers)
numbers_10 = itertools.islice(cum_sum, 10, None, 10)
for i in numbers_10:
print(i)
-5
-10
-15
-20
-25
-30
-35
-40
-45
-50
With this you do not get the final result, though. Maybe with aitertools.tee
of thenumbers
, which you can thensum
, but then it is no longer reporting on the progress...
– Graipher
12 hours ago
what do you mean with the final result? If needed, you need to docum_sum = list(itertools.accumulate(numbers))
ornumbers = [int((-1) ** (i-1) * i) for i in range(101)]
– Maarten Fabré
12 hours ago
I wonder why there is only 9 numbers in your output. -5 is missing, could it be because yourislice
is not starting at 0?
– Mathias Ettinger
7 hours ago
I like this. Personally, I'd write it ascum_sum = accumulate(sign * n for sign, n in zip(cycle((+1, -1)), count()))
to more elegantly express the idea of an infinite series, then extract just the relevant partial sums withfor n in islice(cum_sum, 9, 100, 10): print(n)
.
– 200_success
3 hours ago
add a comment |
up vote
4
down vote
You can get rid of your counter
and directly use i
by using modular arithmetic. i % 10 == 0
is true whenever i
is divisible by 10
.
You can get rid of your operand = operand * -1
by using itertools.cycle
.
from itertools import cycle
result = 0
for i, sign in zip(range(1, 101), cycle([1, -1])):
result += sign * i
if i % 10 == 0:
print(result)
The generation of result
itself would be a lot more concise with a generator comprehension, but this excludes the progress prints:
result = sum(sign * i for i, sign in zip(range(1, 101), cycle([1, -1])))
@MathiasEttinger: It seems like MaartenFabre is already going in that direction in their answer.
– Graipher
12 hours ago
Yep, saw that after the comment
– Mathias Ettinger
12 hours ago
add a comment |
up vote
0
down vote
I would convert the sign flip into a generator, created via a generator comprehension, recognizing that evens should be negative:
# Integers from 1-100, where evens are negative: 1, -2, 3, -4, 5...
sequence_gen = (i if i % 2 else -i for i in range(1,101))
Equivalent to:
def sequence_gen():
for i in range(1, 101):
if bool(i % 2): # For our purposes this is i % 2 == 1:
yield i
else:
yield -i
Then your code becomes:
result = 0
for index, number in enumerate(sequence_gen):
result += number
if index % 10 == 9: # Note the comparison change by starting at 0
print(result)
Note this is about half way to what Mathias proposed, and can be used in conjunction, the combination being:
def sequence_sums(start, stop, step):
result = 0
seq_gen = (i if i % 2 else -i for i in range(start, stop + 1))
for index, number in enumerate(seq_gen):
result += number
if index % step == step - 1:
yield result
You could even go one further step and make the sequence a parameter:
# iterates through a sequence, printing every step'th sum
def sequence_sums(sequence, step):
result = 0
for index, number in enumerate(sequence):
result += number
if index % step == step - 1:
yield result
Called via:
sequence = (i if i % 2 else -i for i in range(1, 101))
for sum in sequence_sums(sequence, 10):
print(sum)
add a comment |
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
8
down vote
accepted
The first thing you can do to make the sign change obvious is to use operand = -operand
, this way you avoid the need for the multiplication operator. Also changing the operand
name to sign can help.
You also don't need counter
as it will be equal to i
before the test. Just change the test to use the modulo (%
) operator instead of reseting counter
.
And using augmented assignment for result
can lead to a more readable line too:
result = 0
sign = 1
for i in range(1, 101):
result += sign * i
sign = -sign
if i % 10 == 0:
print(result)
Now, this probably need to be made more reusable, this means building a function out of this code and avoiding mixing computation and I/Os:
def alternating_sum(start=1, stop=100, step=10):
result = 0
sign = 1
for i in range(start, stop+1):
result += sign * i
sign = -sign
if i % step == 0:
yield result
Usage being:
for result in alternating_sum(1, 100, 10):
print(result)
Also, depending on the problem at hand, you can leverage the fact that every two numbers add-up to -1
. So every 10 numbers add-up to -5
. If you don't need much genericity, you can simplify the code down to:
def alternating_every_ten(end=100):
reports = end // 10
for i in range(1, reports + 1):
print('After', 10 * i, 'sums, result is', -5 * i)
I would recommend writing expressions with a sign variable assign * value
to match the standard method of writing numbers.
– Apollys
9 hours ago
@Apollys Right, fixed.
– Mathias Ettinger
7 hours ago
add a comment |
up vote
8
down vote
accepted
The first thing you can do to make the sign change obvious is to use operand = -operand
, this way you avoid the need for the multiplication operator. Also changing the operand
name to sign can help.
You also don't need counter
as it will be equal to i
before the test. Just change the test to use the modulo (%
) operator instead of reseting counter
.
And using augmented assignment for result
can lead to a more readable line too:
result = 0
sign = 1
for i in range(1, 101):
result += sign * i
sign = -sign
if i % 10 == 0:
print(result)
Now, this probably need to be made more reusable, this means building a function out of this code and avoiding mixing computation and I/Os:
def alternating_sum(start=1, stop=100, step=10):
result = 0
sign = 1
for i in range(start, stop+1):
result += sign * i
sign = -sign
if i % step == 0:
yield result
Usage being:
for result in alternating_sum(1, 100, 10):
print(result)
Also, depending on the problem at hand, you can leverage the fact that every two numbers add-up to -1
. So every 10 numbers add-up to -5
. If you don't need much genericity, you can simplify the code down to:
def alternating_every_ten(end=100):
reports = end // 10
for i in range(1, reports + 1):
print('After', 10 * i, 'sums, result is', -5 * i)
I would recommend writing expressions with a sign variable assign * value
to match the standard method of writing numbers.
– Apollys
9 hours ago
@Apollys Right, fixed.
– Mathias Ettinger
7 hours ago
add a comment |
up vote
8
down vote
accepted
up vote
8
down vote
accepted
The first thing you can do to make the sign change obvious is to use operand = -operand
, this way you avoid the need for the multiplication operator. Also changing the operand
name to sign can help.
You also don't need counter
as it will be equal to i
before the test. Just change the test to use the modulo (%
) operator instead of reseting counter
.
And using augmented assignment for result
can lead to a more readable line too:
result = 0
sign = 1
for i in range(1, 101):
result += sign * i
sign = -sign
if i % 10 == 0:
print(result)
Now, this probably need to be made more reusable, this means building a function out of this code and avoiding mixing computation and I/Os:
def alternating_sum(start=1, stop=100, step=10):
result = 0
sign = 1
for i in range(start, stop+1):
result += sign * i
sign = -sign
if i % step == 0:
yield result
Usage being:
for result in alternating_sum(1, 100, 10):
print(result)
Also, depending on the problem at hand, you can leverage the fact that every two numbers add-up to -1
. So every 10 numbers add-up to -5
. If you don't need much genericity, you can simplify the code down to:
def alternating_every_ten(end=100):
reports = end // 10
for i in range(1, reports + 1):
print('After', 10 * i, 'sums, result is', -5 * i)
The first thing you can do to make the sign change obvious is to use operand = -operand
, this way you avoid the need for the multiplication operator. Also changing the operand
name to sign can help.
You also don't need counter
as it will be equal to i
before the test. Just change the test to use the modulo (%
) operator instead of reseting counter
.
And using augmented assignment for result
can lead to a more readable line too:
result = 0
sign = 1
for i in range(1, 101):
result += sign * i
sign = -sign
if i % 10 == 0:
print(result)
Now, this probably need to be made more reusable, this means building a function out of this code and avoiding mixing computation and I/Os:
def alternating_sum(start=1, stop=100, step=10):
result = 0
sign = 1
for i in range(start, stop+1):
result += sign * i
sign = -sign
if i % step == 0:
yield result
Usage being:
for result in alternating_sum(1, 100, 10):
print(result)
Also, depending on the problem at hand, you can leverage the fact that every two numbers add-up to -1
. So every 10 numbers add-up to -5
. If you don't need much genericity, you can simplify the code down to:
def alternating_every_ten(end=100):
reports = end // 10
for i in range(1, reports + 1):
print('After', 10 * i, 'sums, result is', -5 * i)
edited 7 hours ago
answered 12 hours ago
Mathias Ettinger
23k33177
23k33177
I would recommend writing expressions with a sign variable assign * value
to match the standard method of writing numbers.
– Apollys
9 hours ago
@Apollys Right, fixed.
– Mathias Ettinger
7 hours ago
add a comment |
I would recommend writing expressions with a sign variable assign * value
to match the standard method of writing numbers.
– Apollys
9 hours ago
@Apollys Right, fixed.
– Mathias Ettinger
7 hours ago
I would recommend writing expressions with a sign variable as
sign * value
to match the standard method of writing numbers.– Apollys
9 hours ago
I would recommend writing expressions with a sign variable as
sign * value
to match the standard method of writing numbers.– Apollys
9 hours ago
@Apollys Right, fixed.
– Mathias Ettinger
7 hours ago
@Apollys Right, fixed.
– Mathias Ettinger
7 hours ago
add a comment |
up vote
5
down vote
instead of doing the +-
by hand, you can use the fact that (-1) ** (i-1) * i for i in range(101)
alternates the values
Further on, you can use itertools.accumulate
and itertools.islice
to take the cumulative sum and select every 10th number
numbers = (int((-1) ** (i-1) * i) for i in range(101))
cum_sum = itertools.accumulate(numbers)
numbers_10 = itertools.islice(cum_sum, 10, None, 10)
for i in numbers_10:
print(i)
-5
-10
-15
-20
-25
-30
-35
-40
-45
-50
With this you do not get the final result, though. Maybe with aitertools.tee
of thenumbers
, which you can thensum
, but then it is no longer reporting on the progress...
– Graipher
12 hours ago
what do you mean with the final result? If needed, you need to docum_sum = list(itertools.accumulate(numbers))
ornumbers = [int((-1) ** (i-1) * i) for i in range(101)]
– Maarten Fabré
12 hours ago
I wonder why there is only 9 numbers in your output. -5 is missing, could it be because yourislice
is not starting at 0?
– Mathias Ettinger
7 hours ago
I like this. Personally, I'd write it ascum_sum = accumulate(sign * n for sign, n in zip(cycle((+1, -1)), count()))
to more elegantly express the idea of an infinite series, then extract just the relevant partial sums withfor n in islice(cum_sum, 9, 100, 10): print(n)
.
– 200_success
3 hours ago
add a comment |
up vote
5
down vote
instead of doing the +-
by hand, you can use the fact that (-1) ** (i-1) * i for i in range(101)
alternates the values
Further on, you can use itertools.accumulate
and itertools.islice
to take the cumulative sum and select every 10th number
numbers = (int((-1) ** (i-1) * i) for i in range(101))
cum_sum = itertools.accumulate(numbers)
numbers_10 = itertools.islice(cum_sum, 10, None, 10)
for i in numbers_10:
print(i)
-5
-10
-15
-20
-25
-30
-35
-40
-45
-50
With this you do not get the final result, though. Maybe with aitertools.tee
of thenumbers
, which you can thensum
, but then it is no longer reporting on the progress...
– Graipher
12 hours ago
what do you mean with the final result? If needed, you need to docum_sum = list(itertools.accumulate(numbers))
ornumbers = [int((-1) ** (i-1) * i) for i in range(101)]
– Maarten Fabré
12 hours ago
I wonder why there is only 9 numbers in your output. -5 is missing, could it be because yourislice
is not starting at 0?
– Mathias Ettinger
7 hours ago
I like this. Personally, I'd write it ascum_sum = accumulate(sign * n for sign, n in zip(cycle((+1, -1)), count()))
to more elegantly express the idea of an infinite series, then extract just the relevant partial sums withfor n in islice(cum_sum, 9, 100, 10): print(n)
.
– 200_success
3 hours ago
add a comment |
up vote
5
down vote
up vote
5
down vote
instead of doing the +-
by hand, you can use the fact that (-1) ** (i-1) * i for i in range(101)
alternates the values
Further on, you can use itertools.accumulate
and itertools.islice
to take the cumulative sum and select every 10th number
numbers = (int((-1) ** (i-1) * i) for i in range(101))
cum_sum = itertools.accumulate(numbers)
numbers_10 = itertools.islice(cum_sum, 10, None, 10)
for i in numbers_10:
print(i)
-5
-10
-15
-20
-25
-30
-35
-40
-45
-50
instead of doing the +-
by hand, you can use the fact that (-1) ** (i-1) * i for i in range(101)
alternates the values
Further on, you can use itertools.accumulate
and itertools.islice
to take the cumulative sum and select every 10th number
numbers = (int((-1) ** (i-1) * i) for i in range(101))
cum_sum = itertools.accumulate(numbers)
numbers_10 = itertools.islice(cum_sum, 10, None, 10)
for i in numbers_10:
print(i)
-5
-10
-15
-20
-25
-30
-35
-40
-45
-50
edited 3 hours ago
200_success
127k15149412
127k15149412
answered 12 hours ago
Maarten Fabré
4,444417
4,444417
With this you do not get the final result, though. Maybe with aitertools.tee
of thenumbers
, which you can thensum
, but then it is no longer reporting on the progress...
– Graipher
12 hours ago
what do you mean with the final result? If needed, you need to docum_sum = list(itertools.accumulate(numbers))
ornumbers = [int((-1) ** (i-1) * i) for i in range(101)]
– Maarten Fabré
12 hours ago
I wonder why there is only 9 numbers in your output. -5 is missing, could it be because yourislice
is not starting at 0?
– Mathias Ettinger
7 hours ago
I like this. Personally, I'd write it ascum_sum = accumulate(sign * n for sign, n in zip(cycle((+1, -1)), count()))
to more elegantly express the idea of an infinite series, then extract just the relevant partial sums withfor n in islice(cum_sum, 9, 100, 10): print(n)
.
– 200_success
3 hours ago
add a comment |
With this you do not get the final result, though. Maybe with aitertools.tee
of thenumbers
, which you can thensum
, but then it is no longer reporting on the progress...
– Graipher
12 hours ago
what do you mean with the final result? If needed, you need to docum_sum = list(itertools.accumulate(numbers))
ornumbers = [int((-1) ** (i-1) * i) for i in range(101)]
– Maarten Fabré
12 hours ago
I wonder why there is only 9 numbers in your output. -5 is missing, could it be because yourislice
is not starting at 0?
– Mathias Ettinger
7 hours ago
I like this. Personally, I'd write it ascum_sum = accumulate(sign * n for sign, n in zip(cycle((+1, -1)), count()))
to more elegantly express the idea of an infinite series, then extract just the relevant partial sums withfor n in islice(cum_sum, 9, 100, 10): print(n)
.
– 200_success
3 hours ago
With this you do not get the final result, though. Maybe with a
itertools.tee
of the numbers
, which you can then sum
, but then it is no longer reporting on the progress...– Graipher
12 hours ago
With this you do not get the final result, though. Maybe with a
itertools.tee
of the numbers
, which you can then sum
, but then it is no longer reporting on the progress...– Graipher
12 hours ago
what do you mean with the final result? If needed, you need to do
cum_sum = list(itertools.accumulate(numbers))
or numbers = [int((-1) ** (i-1) * i) for i in range(101)]
– Maarten Fabré
12 hours ago
what do you mean with the final result? If needed, you need to do
cum_sum = list(itertools.accumulate(numbers))
or numbers = [int((-1) ** (i-1) * i) for i in range(101)]
– Maarten Fabré
12 hours ago
I wonder why there is only 9 numbers in your output. -5 is missing, could it be because your
islice
is not starting at 0?– Mathias Ettinger
7 hours ago
I wonder why there is only 9 numbers in your output. -5 is missing, could it be because your
islice
is not starting at 0?– Mathias Ettinger
7 hours ago
I like this. Personally, I'd write it as
cum_sum = accumulate(sign * n for sign, n in zip(cycle((+1, -1)), count()))
to more elegantly express the idea of an infinite series, then extract just the relevant partial sums with for n in islice(cum_sum, 9, 100, 10): print(n)
.– 200_success
3 hours ago
I like this. Personally, I'd write it as
cum_sum = accumulate(sign * n for sign, n in zip(cycle((+1, -1)), count()))
to more elegantly express the idea of an infinite series, then extract just the relevant partial sums with for n in islice(cum_sum, 9, 100, 10): print(n)
.– 200_success
3 hours ago
add a comment |
up vote
4
down vote
You can get rid of your counter
and directly use i
by using modular arithmetic. i % 10 == 0
is true whenever i
is divisible by 10
.
You can get rid of your operand = operand * -1
by using itertools.cycle
.
from itertools import cycle
result = 0
for i, sign in zip(range(1, 101), cycle([1, -1])):
result += sign * i
if i % 10 == 0:
print(result)
The generation of result
itself would be a lot more concise with a generator comprehension, but this excludes the progress prints:
result = sum(sign * i for i, sign in zip(range(1, 101), cycle([1, -1])))
@MathiasEttinger: It seems like MaartenFabre is already going in that direction in their answer.
– Graipher
12 hours ago
Yep, saw that after the comment
– Mathias Ettinger
12 hours ago
add a comment |
up vote
4
down vote
You can get rid of your counter
and directly use i
by using modular arithmetic. i % 10 == 0
is true whenever i
is divisible by 10
.
You can get rid of your operand = operand * -1
by using itertools.cycle
.
from itertools import cycle
result = 0
for i, sign in zip(range(1, 101), cycle([1, -1])):
result += sign * i
if i % 10 == 0:
print(result)
The generation of result
itself would be a lot more concise with a generator comprehension, but this excludes the progress prints:
result = sum(sign * i for i, sign in zip(range(1, 101), cycle([1, -1])))
@MathiasEttinger: It seems like MaartenFabre is already going in that direction in their answer.
– Graipher
12 hours ago
Yep, saw that after the comment
– Mathias Ettinger
12 hours ago
add a comment |
up vote
4
down vote
up vote
4
down vote
You can get rid of your counter
and directly use i
by using modular arithmetic. i % 10 == 0
is true whenever i
is divisible by 10
.
You can get rid of your operand = operand * -1
by using itertools.cycle
.
from itertools import cycle
result = 0
for i, sign in zip(range(1, 101), cycle([1, -1])):
result += sign * i
if i % 10 == 0:
print(result)
The generation of result
itself would be a lot more concise with a generator comprehension, but this excludes the progress prints:
result = sum(sign * i for i, sign in zip(range(1, 101), cycle([1, -1])))
You can get rid of your counter
and directly use i
by using modular arithmetic. i % 10 == 0
is true whenever i
is divisible by 10
.
You can get rid of your operand = operand * -1
by using itertools.cycle
.
from itertools import cycle
result = 0
for i, sign in zip(range(1, 101), cycle([1, -1])):
result += sign * i
if i % 10 == 0:
print(result)
The generation of result
itself would be a lot more concise with a generator comprehension, but this excludes the progress prints:
result = sum(sign * i for i, sign in zip(range(1, 101), cycle([1, -1])))
answered 12 hours ago
Graipher
23k53384
23k53384
@MathiasEttinger: It seems like MaartenFabre is already going in that direction in their answer.
– Graipher
12 hours ago
Yep, saw that after the comment
– Mathias Ettinger
12 hours ago
add a comment |
@MathiasEttinger: It seems like MaartenFabre is already going in that direction in their answer.
– Graipher
12 hours ago
Yep, saw that after the comment
– Mathias Ettinger
12 hours ago
@MathiasEttinger: It seems like MaartenFabre is already going in that direction in their answer.
– Graipher
12 hours ago
@MathiasEttinger: It seems like MaartenFabre is already going in that direction in their answer.
– Graipher
12 hours ago
Yep, saw that after the comment
– Mathias Ettinger
12 hours ago
Yep, saw that after the comment
– Mathias Ettinger
12 hours ago
add a comment |
up vote
0
down vote
I would convert the sign flip into a generator, created via a generator comprehension, recognizing that evens should be negative:
# Integers from 1-100, where evens are negative: 1, -2, 3, -4, 5...
sequence_gen = (i if i % 2 else -i for i in range(1,101))
Equivalent to:
def sequence_gen():
for i in range(1, 101):
if bool(i % 2): # For our purposes this is i % 2 == 1:
yield i
else:
yield -i
Then your code becomes:
result = 0
for index, number in enumerate(sequence_gen):
result += number
if index % 10 == 9: # Note the comparison change by starting at 0
print(result)
Note this is about half way to what Mathias proposed, and can be used in conjunction, the combination being:
def sequence_sums(start, stop, step):
result = 0
seq_gen = (i if i % 2 else -i for i in range(start, stop + 1))
for index, number in enumerate(seq_gen):
result += number
if index % step == step - 1:
yield result
You could even go one further step and make the sequence a parameter:
# iterates through a sequence, printing every step'th sum
def sequence_sums(sequence, step):
result = 0
for index, number in enumerate(sequence):
result += number
if index % step == step - 1:
yield result
Called via:
sequence = (i if i % 2 else -i for i in range(1, 101))
for sum in sequence_sums(sequence, 10):
print(sum)
add a comment |
up vote
0
down vote
I would convert the sign flip into a generator, created via a generator comprehension, recognizing that evens should be negative:
# Integers from 1-100, where evens are negative: 1, -2, 3, -4, 5...
sequence_gen = (i if i % 2 else -i for i in range(1,101))
Equivalent to:
def sequence_gen():
for i in range(1, 101):
if bool(i % 2): # For our purposes this is i % 2 == 1:
yield i
else:
yield -i
Then your code becomes:
result = 0
for index, number in enumerate(sequence_gen):
result += number
if index % 10 == 9: # Note the comparison change by starting at 0
print(result)
Note this is about half way to what Mathias proposed, and can be used in conjunction, the combination being:
def sequence_sums(start, stop, step):
result = 0
seq_gen = (i if i % 2 else -i for i in range(start, stop + 1))
for index, number in enumerate(seq_gen):
result += number
if index % step == step - 1:
yield result
You could even go one further step and make the sequence a parameter:
# iterates through a sequence, printing every step'th sum
def sequence_sums(sequence, step):
result = 0
for index, number in enumerate(sequence):
result += number
if index % step == step - 1:
yield result
Called via:
sequence = (i if i % 2 else -i for i in range(1, 101))
for sum in sequence_sums(sequence, 10):
print(sum)
add a comment |
up vote
0
down vote
up vote
0
down vote
I would convert the sign flip into a generator, created via a generator comprehension, recognizing that evens should be negative:
# Integers from 1-100, where evens are negative: 1, -2, 3, -4, 5...
sequence_gen = (i if i % 2 else -i for i in range(1,101))
Equivalent to:
def sequence_gen():
for i in range(1, 101):
if bool(i % 2): # For our purposes this is i % 2 == 1:
yield i
else:
yield -i
Then your code becomes:
result = 0
for index, number in enumerate(sequence_gen):
result += number
if index % 10 == 9: # Note the comparison change by starting at 0
print(result)
Note this is about half way to what Mathias proposed, and can be used in conjunction, the combination being:
def sequence_sums(start, stop, step):
result = 0
seq_gen = (i if i % 2 else -i for i in range(start, stop + 1))
for index, number in enumerate(seq_gen):
result += number
if index % step == step - 1:
yield result
You could even go one further step and make the sequence a parameter:
# iterates through a sequence, printing every step'th sum
def sequence_sums(sequence, step):
result = 0
for index, number in enumerate(sequence):
result += number
if index % step == step - 1:
yield result
Called via:
sequence = (i if i % 2 else -i for i in range(1, 101))
for sum in sequence_sums(sequence, 10):
print(sum)
I would convert the sign flip into a generator, created via a generator comprehension, recognizing that evens should be negative:
# Integers from 1-100, where evens are negative: 1, -2, 3, -4, 5...
sequence_gen = (i if i % 2 else -i for i in range(1,101))
Equivalent to:
def sequence_gen():
for i in range(1, 101):
if bool(i % 2): # For our purposes this is i % 2 == 1:
yield i
else:
yield -i
Then your code becomes:
result = 0
for index, number in enumerate(sequence_gen):
result += number
if index % 10 == 9: # Note the comparison change by starting at 0
print(result)
Note this is about half way to what Mathias proposed, and can be used in conjunction, the combination being:
def sequence_sums(start, stop, step):
result = 0
seq_gen = (i if i % 2 else -i for i in range(start, stop + 1))
for index, number in enumerate(seq_gen):
result += number
if index % step == step - 1:
yield result
You could even go one further step and make the sequence a parameter:
# iterates through a sequence, printing every step'th sum
def sequence_sums(sequence, step):
result = 0
for index, number in enumerate(sequence):
result += number
if index % step == step - 1:
yield result
Called via:
sequence = (i if i % 2 else -i for i in range(1, 101))
for sum in sequence_sums(sequence, 10):
print(sum)
answered 4 hours ago
TemporalWolf
22427
22427
add a comment |
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209364%2fprinting-every-10th-result-in-an-alternating-pm-series%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Do you need the final
result
of the whole sum and just want to report progress as the summing is going on, or do you want the sum of only every 10th element and also print progress?– Graipher
12 hours ago
Maybe I'm missing something, but isn't the alternating sum you want $$-sum_{n=1}^{m} n (-1)^n equiv -frac{1}{4}-frac{1}{4}(-1)^m (2m+1)$$ And then you can substitute m = 10n or whatever value you need. Far faster than looping.
– esote
2 hours ago
@Graipher I want to report progress as the summing is going on. but original question is not clear. So i think it should be interpreted like this.
– jun
2 hours ago