24

I am taking a programming class in college and one of the exercises in the problem sheet was to write this code:

number = int(input())
x = 0
y = 0
for n in range(number):
    if n % 2 == 0:
        x += n
    else:
        y += n
print(x)
print(y)

using only one "for" loop, and no "while" or "if".

The purpose of the code is to find the sum of the even and the sum of the odd numbers from zero to the number inputted and print it to the screen.

Be reminded that at this time we aren't supposed to know about functions.

I've been trying for a long time now and can't seem to find a way of doing it without using "if" statements to know if the loop variable is even or odd.

Davide Casiraghi
  • 15,591
  • 9
  • 34
  • 56
Rui Coito
  • 379
  • 1
  • 3
  • 6
  • 3
    Can you please share with us what you've been trying so far - and exactly where you are stuck? Thanks. – S3DEV Nov 26 '20 at 08:49
  • 1
    You phrased this question a bit oddly - you stressed "using only one for loop" but then just mentioned no if statements just in brackets. But your snippet already *does* have only one for loop, so avoiding the if statement is not just a footnote but sorta the whole point. I had to read your question a couple of times to notice the full requirements. – Arthur Tacca Nov 26 '20 at 09:59
  • 1
    @ArthurTacca you are absolutely correct after i posted it i noticed that as you said the whole point of it was to eliminate the if statements, i only wrote it like that because it was how the exercise was phrased in problem sheet – Rui Coito Nov 26 '20 at 10:04

12 Answers12

17

Purely for educational purposes (and a bit of fun), here is a solution that does not use any for loops at all. (Granted, in the underlying logic of the functions, there are at least five loops.)

num = list(range(int(input('Enter number: '))))

even = num[::2]
odd = num[1::2]

print('Even list:', even)
print('Odd list:', odd)

print('Even:', sum(even))
print('Odd:', sum(odd))

Output:

Enter number: 10
Even list: [0, 2, 4, 6, 8]
Odd list: [1, 3, 5, 7, 9]
Even: 20
Odd: 25

How does it work?

  • The input() function returns a str object, which is converted into an integer using the int() function.
  • The integer is wrapped in the range() and list() functions to convert the given number into a list of values within that range.
    • This is a convention you will use/see a lot through your Python career.
  • List slicing is used to get every second element in the list. Given the list is based at zero, these will be even numbers.
  • Slice the same list again, starting with the second element, and get every second element ... odd numbers.
  • The simply use the sum() function to get the sums.
S3DEV
  • 8,768
  • 3
  • 31
  • 42
  • 2
    That is fun and clever, but I see *five* loops in it: `list`, the two slices, and the two `sum` calls. (I'm not counting the loops to render the strings in the first two `print` calls.) – Michael Geary Nov 26 '20 at 09:03
  • 1
    the op's requirement was only one "for" loop so this meets the requirement – an inconspicuous semicolon Nov 26 '20 at 09:04
  • @MichaelGeary - Fair point! I'll revise the commentary. Thanks. – S3DEV Nov 26 '20 at 09:05
  • If we create the list on a seperate line we could do `sum_even, sum_odd = [sum(num[i::2]) for i in [None, 1]]`. Maybe the input and the creation of the list could be part of this line too if we use the new walrus operator (`:=`) but I still haven't installed the new Python version so I can't check. – Matthias Nov 26 '20 at 09:10
13
for n in range(number):
    x += (1 - n % 2) * n
    y += (n % 2) * n
delta
  • 3,778
  • 15
  • 22
11

You asked for a solution with one loop, but how about a solution with no loop?

It is well known that the sum of the numbers from 1 to n is (n+1)*n/2. Thus, the sum of even numbers is 2 * (m+1)*m/2 with m = n//2 (i.e. floor(n/2)). The sum of odd can then be calculated by the sum of all numbers minus the sum of even numbers.

n = 12345
m = n // 2
e = (m+1)*m
o = (n+1)*n//2 - e

Verification:

>>> e, e==sum(i for i in range(n+1) if i % 2 == 0)
38112102 True
>>> o, o==sum(i for i in range(n+1) if i % 2 == 1)
38105929 True

Note: This calculates the sums for number up to and including n.

tobias_k
  • 81,265
  • 12
  • 120
  • 179
4
for n in range(1,number,2):
  x += n
  y += n-1
print(y)
print(x)

This code has the same output with the example.

  • 1
    This will fail if the upper bound is even. – tobias_k Nov 26 '20 at 09:00
  • If `number` is `3` the output for `y` is `0`. – Matthias Nov 26 '20 at 09:02
  • Although this doesn't quite work, I do think it comes closest to capturing the spirit of the original question. It doesn't just use the mathematical formula (obviously in the real world that's the best solution but isn't the point here) and doesn't use any tricks to simulate an if statement. It's a pity the question doesn't allow a single if statement outside the loop to tidy up the difference between even and odd maximum number. – Arthur Tacca Nov 26 '20 at 09:54
  • This is exactly what i've done, but then again it failled when i tried doing it for even numbers, and if i corrected it to do the even numbers right than it would fail in the odd numbers, but as @ArthurTacca this was sort of the idea i had when I wrote the question. – Rui Coito Nov 26 '20 at 10:14
4

Ternary operator:

for n in range(number):
  x += (n,0)[n%2]
  y += (0,n)[n%2]
user20191130
  • 340
  • 1
  • 9
4

I think you are a beginner. I wouldn't like to confuse you with slicing operators complex implementation.

As you mentioned

The purpose of the code is to find the sum of the even and the sum of the odd numbers from zero to the number inputted and print it to the screen.

There is no need to find the initial number is odd/even And your program is wrong if you want to include the input number in calculating the even/odd sum.

Example

Input

5

Expected Output

6 9

Explanation

Even Sum : 2+4 = 6

Odd Sum : 1+3+5 = 9

Your Output

6 4 (wrong output)

The range() function will exclude the number. It will only iterate from 0 to 4 while the input is 5. so if you want to include 5, you should add 1 to the number while passing it in the range() function.

number = int(input())
x = 0
y = 0
for n in range(number+1):
    x += (1 - n % 2) * n  #this will add 0 if not even
    y += (n % 2) * n      #this will add 0 if not odd
print(x)
print(y)
4

There is also mathematical way:

num = int(input("Enter number:"))
odd = ((num+1)/2)**2
even = num*(num+1)/2 - odd

The sum of the first n odd numbers is n^2. To get count of odd numbers we use (num+1)/2. To get sum of even numbers, we could use similar approach, but I preferred, subtracting odd from the sum of the first n numbers, which is n*(n+1)/2.

Tugay
  • 2,057
  • 5
  • 17
  • 32
3

Here is my 2cents if we are allowed to use numpy.

import numpy as np
number = int(input())

l = np.array(range(number)) 
print('odd:',sum(l % 2 * l))
print('even:', sum((1- l % 2) * l))
IoaTzimas
  • 10,538
  • 2
  • 13
  • 30
2

If you're allowed to use a list

number = int( input() )
counts = [ 0, 0 ]
for n in range( number ):
    counts[ n % 2 ] += n
print( counts[ 0 ] )
print( counts[ 1 ] )
AKHolland
  • 4,435
  • 23
  • 35
2

There's another way which sums the odd and even indices together in the for loop based on the remainder modulo 2:

number = int(input())
odd = 0
even = 0
for i in range(len(number)):
    odd += i * (i % 2)
    even += i * ((i + 1) % 2)

print (odd, even)
chngzm
  • 608
  • 4
  • 13
2
number = 1000000
x = 0
y = 0
[(x:=x+n, y:=y+(n+1)) for n in range(0,number,2)]
print(f'{x}, {y}')

This uses a list comprehension and the new Python assignment operator.

user74691
  • 21
  • 2
1

Sum of first n numbers is n(n+1)/2 (Mathematically derived). So if we know the value of n then we can find the sum of all numbers from 1 to n.

If we find the sum of all odd numbers before n and subratract it from the sum of first n we get he sum of all even numbers before n.

Here's the code:

n = int(input("Enter a number: "))
odd = 0
for i in range(1,n+1,2):
    odd += i
even = int(n*(n+1)/2) - odd
print("even:",even,"odd:",odd)
The Beast
  • 89
  • 1
  • 6