rbku
rbku

Reputation: 41

Python- Adding odd numbers in a range including the limits?

I need to write a program where the user inputs 2 numbers and then it gives the sum of all odd numbers in that range plus the 2 numbers that the user entered. I've searched around a lot but haven't found anything that includes the limits. So far I have:

x=int(input('Enter first number: '))
y=int(input('Enter second number: '))

def SumOdds(x,y):
  count=0
  for i in range(x,y):
     if (int(i%2==1)):
        count=count+i

  print(count)
SumOdds(x,y)

This gives the sum of the odds, but doesn't include the limits. For example, say I put in 10 and 20. This gives me 75, but it needs to add on the 10 and 20 to make it 105. I'm sure this is a simple fix, but I'm very new to Python so any help would be appreciated. Thanks!

Upvotes: 3

Views: 5446

Answers (9)

Sinelk
Sinelk

Reputation: 1

Maybe we can make it a little simpler... Try this

>> start = int(input("Enter the start of range: "))

>> end = int(input("Enter the end of range: "))

>> tot = [n for n in range(start, end+1) if n%2] or [n for n in range(start, end+1) if not n%2]

>> print("your odd numbers are")

>> print(tot, end = "")

>> print ("and their sum is their sum is")

>> print(sum(tot))`

Upvotes: 0

Ken Ma
Ken Ma

Reputation: 21

To avoid adding the limits twice, you may also use sets. Not simple at first glance but it can make your code more elegant.

x=int(input('Enter first number: '))
y=int(input('Enter second number: '))

def sum_odds_and_limits(x,y):
    to_sum = set() #sets are collections of unique elements
    to_sum |= {x,y} #union
    for num in range(x,y+1):
        if num%2==1 :
            to_sum|={num}
    print(sum(to_sum))

sum_odds_and_limits(x,y)

And for efficiency I suggest you avoid the modulos(%) and conditions in a loop. slice notation is a great tool in python to do that:

range(x,y+1)[(x+1)%2::2]
#list()[<start position>:<ending position>:<take every N element>]

And you will end up with a code like:

x=int(input('Enter first number: '))
y=int(input('Enter second number: '))

def sum_odds_and_limits(x,y):
    #sum all the odd numbers and boundaries in the given range
    to_sum = set(range(x,y+1)[(x+1)%2::2])
    to_sum |= {x,y}
    print(sum(to_sum))

sum_odds_and_limits(x,y)

I insist on making function names clear. But that's personal.

Upvotes: 0

Arthur Juli&#227;o
Arthur Juli&#227;o

Reputation: 869

sum([i for i in range(x, y+1) if not i%2==0])

Isn't this enough?

Upvotes: 0

swami_108
swami_108

Reputation: 119

You should extend the second number of your range by one because of the way Python ranges work (first number included and last number excluded). Then calculate the sum of the odd numbers as you have and at the end simply add the two inputted numbers to your odd number sum. You can create a new variable for this (as I show below) or you can add it to the odd numbers sum variable.

x1=int(input('Enter first number: '))
x2=int(input('Enter second number: '))

def sum_odds(x1, x2):
    odd_sum = 0
    total_sum = 0
    for number in range(x1, x2+1):
        if number % 2 != 0:
            odd_sum+=number
    total_sum = odd_sum + x1 + x2
    print(total_sum)

    return total_sum

sum_odds(x1,x2)

Upvotes: 0

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476567

In a range(..) object the "upper bound" (second parameter) is exclusive. So in order to fix this, using range(x, y+1) is sufficient, like:

def SumOdds(x, y):
    count=0
    for i in range(x, y+1):
        if i%2==1:
            count=count+i
    print(count)

SumOdds(x,y)

Note however that we can improve the speed, since the sum can be calculated with a formula:

 n
---
\                   2     2
/    2*i + 1 = (n+1)   - m
---
i=m

So we can calculate this as:

def sumOdds(x, y):
    m = x//2
    n1 = ((y-1)//2)+1
    print(max(0, n1*n1 - m*m))

The advantage of this approach that it works in O(1) for small to not so small numbers, and in O(log m + log n) for huge numbers (since multiplication can then take more time).

As a result we can calculate the sum of huge numbers quite fast, for example:

>>> timeit.timeit(lambda: SumOdds(12345678901234567890, 98765432109876543210), number=1000000)
0.5030524220055668

So calculating the sum of odd elements between 12'345'678'901'234'567'890 and 98'765'432'109'876'543'210 can be calculated in 503 nanoseconds. An iterative approach will take linear time, and will probably not obtain a result within reasonable time.

Upvotes: 1

Triggernometry
Triggernometry

Reputation: 583

I feel as though I might be missing something here - you're already taking the endpoints as arguments, so why not add them to count?

x=int(input('Enter first number: '))
print x
y=int(input('Enter second number: '))
print y

def SumOdds(x,y):
  count = x + y

  # x + 1 for an exclusive range, i.e (10, 20) will check the numbers 11-19
  for i in range(x+1, y):
     if (int(i % 2 ==1 )):
        count= count + i

  print(count)
SumOdds(x,y)

Try it online!

Also, through the magic of list comprehension, you can reduce that for loop to one line if you'd like:

x=int(input('Enter first number: '))
y=int(input('Enter second number: '))

def SumOdds(x,y):
  # x + y + each i in range 11-19, if i is odd
  count = x + y + sum(i for i in range(x+1, y) if i % 2 == 1)
  print(count)
SumOdds(x,y)

Try it online!

Upvotes: 0

Capn Jack
Capn Jack

Reputation: 1241

So all you're missing is the addition of your two numbers when you finish your for loop. Try this:

x=int(input('Enter first number: '))
y=int(input('Enter second number: '))

def SumOdds(x,y+1):
  count= x + y #notice instead of 0, it's the sum now!
  for i in range(x,y):
     if(i == x or i == y):
         pass
     elif (int(i%2==1)):
        count=count+i

  print(count)
SumOdds(x,y)

Edit: as per your comment, you won't want to add your limits twice if they're odd. The y+1 ensures you're capturing the whole range, and the check for i == x or i == y skips those values in the range, since we've already added them at the start.

Upvotes: 2

vash_the_stampede
vash_the_stampede

Reputation: 4606

First I would extend the range to y+1 then take all the odds in that range, after I would check if x and y were even if so i would add them to the list.

x = int(input('Enter first number: '))
y = int(input('Enter second number: '))
tot = [i for i in range(x, y+1) if i % 2]

if not x % 2:
    tot.append(x)

if not y % 2:
    tot.append(y)

print(sum(tot))

Upvotes: 1

Greg Ver Halen
Greg Ver Halen

Reputation: 11

Just check the bounds separately.

x=int(input('Enter first number: '))
y=int(input('Enter second number: '))

def SumOdds(x,y):
  count=0
  for i in range(x,y):
    if (int(i%2==1)):
      count=count+i
  if(x%2==0):
    count= count+x
  if(y%2==0):
    count= count+7
  print(count)
SumOdds(x,y)

The base loop should include any odd limits, so you only have to add the limits if they are odd.

Upvotes: 1

Related Questions