I was doing my homework when I encountered this problem:
Write a function, mysum_bigger_than , that works the same as mysum ,
except that it takes a first argument that precedes *args . That
argument indicates the threshold for including an argument in the sum.
Thus, calling mysum_bigger
_than(10, 5, 20, 30, 6) would return 50 —because 5 and 6 aren’t greater than 10 . This function should similarly work with any type
and assumes that all of the arguments are of the same type. Note that ‘>’ and ‘<‘ work on many different types in Python, not just on numbers; with strings, lists, and tuples, it refers to their sort order.
THE PROBLEM WITH THE CODE UNDERNEATH: I can’t sum elements which are bigger than threshold value without threshold value itself!
def mysum_bigger_than(*values): if not values: return values output = values for value in values[1:]: if value < output: continue else: output += value return output print(mysum_bigger_than(10,5,20,30,6)) #returns 60 instead of 50 print(mysum_bigger_than('mno', 'abc', 'pqr', 'uvw', 'efg', 'xyz')) #returns everything i need with unnecessary 'mno'
One problem with your attempt: You use the threshold (
output) as a starting point of the summation. Another: You check for bigger and equal than the threshold. And I think you should actually model your function signature according to this part of the instructions:
… except that it takes a first argument that precedes *args …
def mysum_bigger_than(threshold, *values):
This has the advantage that (1) without providing a
threshold the function would return an error. And (2) you don’t have to separate the threshold from the
values list in the function definition.
Here’s a suggestion:
def mysum_bigger_than(threshold, *values): summing = False result = None for value in values: if value > threshold: if summing: result += value else: result = value summing = True return result
summing is a control variable: It’s value is
False as long as the values in
values are below the threshold. Once the first value is above the threshold it’s value is set to
True. And at the same time the
result variable gets “properly” initialized and is used afterwards as summation variable. If no value in
values is above the threshold the function returns
None, otherwise the required sum.
Here’s another suggestion, which is more compact but probably not as efficient (which would only matter for an extremely large
def mysum_bigger_than(threshold, *values): sum_values = [value for value in values if value > threshold] if not sum_values: return None result = sum_values for value in sum_values[1:]: result += value return result
The first step filters those values from
values that meet the requirement of being bigger than the threshold (using a list comprehension). The next step checks if there are actually values that are bigger than the threshold. The function returns
None if that’s not the case. The rest is just summing up over the filtered values, if there are any.
If you’re allowed to, you could use some tools from the standard library,
from functools import reduce from operator import add def mysum_bigger_than(threshold, *values): sum_values = [value for value in values if value > threshold] if not sum_values: return None return reduce(add, sum_values)
But I think this is a bit overkill.
(One thing you definitely shouldn’t use here is
sum, because by design it doesn’t work for strings.)
Try this approach:
def mysum_bigger_than(*values): if not values: return values cond = lambda x: x > values return sum(filter(cond, values[1:]))