Reputation: 1027
Write a function that accepts a list of integers as parameter. Your function should return the sum of all the odd numbers in the list. If there are no odd numbers in the list, your function should return 0 as the sum.
def odd_numbers (my_list):
total = 0
count = 0
for number in my_list:
if (number % 2 == 1):
total = total + number
else:
count = count + 1
if (number == count):
return (0)
else:
return (total)
#Main Program
my_list = []
n = int(input("Enter the maximum length of a list: "))
while (len(my_list) < n):
item = input ("Enter integer value to the list: ")
my_list.append(item)
print ("This is your list: ", my_list)
result = odd_numbers(my_list)
print (result)
This is my program. When I execute it, there's an error at first if condition in the function odd_numbers and when I call the function from my main program. I can't understand the nature of this error. It just states that
TypeError: not all arguments converted during string formatting
Upvotes: 1
Views: 13269
Reputation: 2732
Try this code:
def read_int(msg):
n = None
while n is None:
try:
n = int(input(msg))
except ValueError:
print("You should enter only integer values!")
return n
def odd_numbers (my_list):
total = 0
count = 0
for number in my_list:
if (number % 2 == 1):
total = total + number
else:
count = count + 1
if (number == count):
return (0)
else:
return (total)
#Main Program
my_list = []
n = read_int("Enter the maximum length of a list: ")
while (len(my_list) < n):
item = read_int("Enter integer value to the list: ")
my_list.append(item)
print ("This is your list: ", my_list)
result = odd_numbers(my_list)
print (result)
Upvotes: 2
Reputation: 20415
A for comprehension brings a concise syntax; for completeness consider also this recursive function,
def f(xs):
if xs == []:
return 0
else:
v = 0 if xs[0] % 2 == 0 else xs[0]
return v + f(xs[1:])
This function terminates as it decreases the list by one element at each recursive call up to the empty list.
Upvotes: 1
Reputation: 10213
A. raw_input
return value which data type is string
, so need Type Casting
>>> item = raw_input("Enter Number:")
Enter Number:2
>>> type(item)
<type 'str'>
>>> item = int(raw_input("Enter Number:"))
Enter Number:4
>>> type(item)
<type 'int'>
>>>
B. Exception Handling during Type Casting: If user enter any other character from digit then above code will raise ValueError
exception which need to handle.
e.g.
>>> item = int(raw_input("Enter Number:"))
Enter Number:w
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'w'
Demo with exception handling:
>>> try:
... item = int(raw_input("Enter Number:"))
... except ValueError:
... print "Enter only digits."
...
Enter Number:rt
Enter only digits.
C. Related to actual algorithm
a. No need of count
variable logic.
b. No need of if
loop during value return.
c. Best to change function number to sumOfOddNumbers
i.e. more meaningful.
Demo :
def sumOfOddNumbers (numbers_list):
total = 0
for number in numbers_list:
if (number % 2 == 1):
total += number
return total
D. Use list comprehension, sum method, lambda function as mention in other answers
E. Time to run following code:
lst = range(10000000)
def sum_of_odd_numbers1():
return sum((i*(i%2) for i in lst), 0)
def sum_of_odd_numbers2():
return sum((i for i in lst if i%2), 0)
def sum_of_odd_numbers3():
return sum(filter(lambda x: x%2, lst), 0)
def sumOfOddNumbers ():
total = 0
for number in lst:
if (number % 2 == 1):
total += number
return total
import time
start_time = time.time()
sum_of_odd_numbers1()
end_time = time.time()
print "Timing of sum_of_odd_numbers1:", end_time - start_time
start_time = time.time()
sum_of_odd_numbers2()
end_time = time.time()
print "Timing of sum_of_odd_numbers2:", end_time - start_time
start_time = time.time()
sum_of_odd_numbers3()
end_time = time.time()
print "Timing of sum_of_odd_numbers3:", end_time - start_time
start_time = time.time()
sumOfOddNumbers()
end_time = time.time()
print "Timing of sumOfOddNumbers:", end_time - start_time
respective output:
vivek:~$ python /home/vivek/workspace/vtestproject/study/timer.py
Timing of sum_of_odd_numbers1: 2.4171102047
Timing of sum_of_odd_numbers2: 1.73781108856
Timing of sum_of_odd_numbers3: 2.09230113029
Timing of sumOfOddNumbers: 1.42781090736
Upvotes: 2
Reputation: 66
try this:
def odd_number(list_):
odd_nums = [nums for nums in list_ if nums % 2 != 0]
if odd_nums:
return sum(odd_nums)
else:
return 0
my_list = range(10)
print (odd_number(my_list))
Upvotes: 1
Reputation: 56634
The problem is: when you do
item = input("Enter integer value to the list: ")
item
is a string. It gets stored in a list, passed to odd_numbers()
, and when you get to
if (number % 2 == 1):
when it sees str % something
it tries to apply old-style string formatting (for example, "%04d" % 3
results in "0003"
). But your string doesn't have any format specifiers (no "%"
characters), so it complains that there are more arguments than there are places to put them ;-)
To avoid this, make sure you convert the string to a number, ie
item = int(input("Enter integer value to the list: "))
A somewhat hacky solution:
def sum_of_odd_numbers(lst):
return sum((i*(i%2) for i in lst), 0)
or a more readable one,
def sum_of_odd_numbers(lst):
return sum((i for i in lst if i%2), 0)
or a functional equivalent,
def sum_of_odd_numbers(lst):
return sum(filter(lambda x: x%2, lst), 0)
Upvotes: 3
Reputation: 59184
Your code would work with Python 2.7 but not Python 3.x, since the input
function returns a string in Python 3. Change
item = input("Enter integer value to the list: ")
to
item = int(input("Enter integer value to the list: "))
That being said, you can also shorten your function as:
def odd_numbers (my_list):
total = 0
for number in my_list:
if (number % 2 == 1):
total = total + number
return (total)
You can also use the generator method provided by @minitoto to optimize even more after you learn about list comprehensions/generator expressions in Python.
Upvotes: 1