back

python workout: exercise 2

summing numbers

problem

The challenge here is to write a mysum function that does the same thing as the built-in sum function. However, instead of taking a single sequence as a parameter, it should take a variable number of arguments. Thus, although you might invoke sum([1,2,3]), you’d instead invoke mysum(1,2,3) or mysum(10,20,30,40,50).

And no, you shouldn’t use the built-in sum function to accomplish this!

attempts

As suggested, we should just use the splat operator:

def mysum(*numbers: tuple[int]):
    total = 0
    for n in numbers:
        total += n
    return total
print(mysum(1, 2, 3))
print(mysum(10, 20, 30, 40, 50))
6
150

solution

Book’s implementation:

def mysum(*numbers):
    output = 0
    for number in numbers:
        output += number
    return output
print(mysum(10, 20, 30, 40))
100

beyond the exercise

2 arguments

  • problem

    The built-in version of sum takes an optional second argument, which is used as the starting point for the summing. (That’s why it takes a list of numbers as its first argument, unlike our mysum implementation.) So sum([1,2,3], 4) returns 10, because 1+2+3 is 6, which would be added to the starting value of 4. Reim- plement your mysum function such that it works in this way. If a second argu- ment is not provided, then it should default to 0.

  • attempts

    Straightforward modification:

    def mysum2(numbers: list[int], start: int = 0):
        total = start
        for number in numbers:
            total += number
        return total
    print(mysum2([1,2,3], 4))
    
    10
    

arithmetic mean

  • problem

    Write a function that takes a list of numbers. It should return the average (i.e., arithmetic mean) of those numbers.

  • attempts

    Just need to add a division:

    def mean(numbers: list[int]):
        total = 0
        for number in numbers:
            total += number
        return total/len(numbers)
    print(mean([1,2,3]))
    
    2.0
    

word stats

  • problem

    Write a function that takes a list of words (strings). It should return a tuple con- taining three integers, representing the length of the shortest word, the length of the longest word, and the average word length.

  • attempts

    We can make use of min and max:

    def word_stats(words: list[str]):
        word_lengths = list(map(len, words))
        total_lengths = 0
        for length in word_lengths:
            total_lengths += length
        avg_length = total_lengths/len(words)
        return min(word_lengths), max(word_lengths), avg_length
    print(word_stats(['hello', 'darkness', 'my', 'old', 'friend']))
    

summing objects

  • problem

    Write a function that takes a list of Python objects. Sum the objects that either are integers or can be turned into integers, ignoring the others.

  • attempts

    The main challenge here is knowing which objects can be turned into integers.

    Strings can for example, so can booleans. So maybe the idea here is to use a try except block on casting the object to an int:

    def obj_sum(objects: list[object]):
        total = 0
        for obj in objects:
            try:
                total += int(obj)
            except Exception as e:
                print(f'Object {obj} cannot be cast to int: {e}')
        return total
    print(obj_sum([1,2,3]))
    print(obj_sum([1,'2',3]))
    print(obj_sum([1,'2',True]))
    print(obj_sum([1.5,'2',True]))
    print(obj_sum([1.5,'2',True]))
    print(obj_sum([1.5,'2',True,[]]))
    
    6
    6
    4
    4
    4
    Object [] cannot be cast to int: int() argument must be a string, a bytes-like object or a real number, not 'list'
    4
    

    I think that’s good enough here…

mail@jonahv.com