1

I am trying to write a function that will take either a single number or an array as an input and the result should be the sum of the odd numbers in the array which are smaller than or equal to the input number.

Example: if the input is 9, the result should be 25. i.e. 1+3+5+7+9. If the input is an array, ar[4,5], the result should be 4 and 9 printed in separate lines.

Below is the code I have which works when taking a singular input, but I am not sure on how to proceed using an array as an input.

def oddsum(x): 
    sum = 0
    for i in range(x+1): 
        # Loop to find odd Sum 
        if i % 2 != 0: 
        sum +=i
    return sum
Vaibhav Jadhav
  • 2,020
  • 1
  • 7
  • 20
Aviator9933
  • 13
  • 1
  • 3

2 Answers2

0

Check the type of things in python using the function type:

def oddsum_int(x): 
    sum = 0
    for i in range(1,x+1,2): 
        sum +=i
    return sum

def oddsum(x):
    '''`x` may be `list` or `int`'''
    if type(x) == list:
        for i in x:
            print(oddsum_int(i))
    elif type(x) == int:
        print(oddsum_int(x))
    else:
        raise TypeError("Couldn't handle input of type {}".format(type(x)))

>
oddsum(9)
>25
oddsum([4,5])
>4
>9
0

This can be done with isinstance, which is robust against things like subclasses:

def _oddsum(n):
    # efficient generator expression here
    return sum(i for i in range(n + 1) if i % 2 == 1)

def oddsum(arr):
    return [_oddsum(n) for n in arr]

def polymorph_oddsum(x):
    if isinstance(x, list):
        return oddsum(x)
    return _oddsum(x)

if __name__ == "__main__":
    # really all of these are more sensible ways to do this
    print(oddsum([9]))
    print(_oddsum(9))
    print(oddsum([4, 5, 9]))
    print(oddsum((4, 5, 9)))
    print(oddsum({4, 5, 9}))

    # but if you really wanted, you can use polymorph_oddsum for either case
    print(polymorph_oddsum(9))
    print(polymorph_oddsum([4, 5, 9]))

However as you might have seen from my comments, this probably isn't actually what you want to do. You should just call the appropriate function depending on what the type of your input is going to be, which you should really know before runtime.

The isinstance approach is less desirable because it breaks as soon as you give it any other kind of iterable, though the normal oddsum does not, as my code shows.

Incidentally, while I have taken the liberty of putting your loop into a single generator expression, you don't even need a loop here. The sum of odd numbers is an easy progression to find a closed form for, and you can just use

def _oddsum2(n):
    return ((n + 1) // 2) ** 2
Izaak van Dongen
  • 2,450
  • 13
  • 23
  • 1
    +1 for `isinstance` being robust to subclasses. Consider `class MyList(list): pass` -- compare `type(my_list_instance) == list` versus `isinstance(my_list_instance, list)` ... –  Jan 10 '20 at 14:28