Python3, Advanced Python Code Challenges: Lists, exercise 5

link: https://www.codecademy.com/courses/learn-python-3/articles/advanced-python-code-challenges-lists
Exercise 5, “Middle Item”

instructions:

My question is about the difference between my code and the solution code.

My code:

    if len(lst) % 2 == 0: # this means it's even
        halflength = int(len(lst) / 2)
        return (lst[halflength] + lst[halflength + 1]) / 2
    else: #it'll be odd
        oddhalf = (len(lst) / 2) + .5
        return oddhalf

This code works perfectly when I call the function with [1, 2, 3, 4] or [1, 2, 3, 4, 5]. However, when I try the list provided in the exercise for debugging, [5, 2, -10, -4, 4, 5], my code returns 0.0. Why? It doesn’t make any sense, I can’t see any reason whatsoever why the code I have wouldn’t be able to accommodate negative numbers or numbers out-of-sequence. I’m pretty much only interacting with the indexes, not even the values themselves. I can’t even figure out if the problem is the list being out-of-sequence or the fact it contains negative integers.

Also, the solution code has something I don’t understand:
lst[int(len(lst)/2)] + lst[int(len(lst)/2) - 1]
It converts a len() item into an int inside the square brackets that are supposed to reference an index. Why? And how is that different from mine?

solution code:

For debugging, I have a version that prints rather than returns in PyCharm.

def middle_element(lst):
    if len(lst) % 2 == 0: # this means it's even
        halflength = int(len(lst) / 2)
        print((lst[halflength] + lst[halflength + 1]) / 2)
    else: #it'll be odd
        oddhalf = (len(lst) / 2) + .5
        print(oddhalf))

middle_element([1,3,2,4]) # should be 2.5 but yields 3.0
middle_element([5,4,3,2,1]) # correctly yields 3.0
middle_element([1,-2,3,-4,5]) # correctly yields 3.0
middle_element([-1, -2, -3, -4]) # should yield -2.5 but yields -3.5
middle_element([5, 2, -10, -4, 4, 5]) # should yield -7.0 but yields 0.0

This has only deepened the mystery.

Aside: There has been an enormous, sudden jump in difficulty. I am pulling my hair out over these last two exercises and don’t fully understand them even with the solutions right in front of me. I’m going back and reviewing my notes, I’m Googling official documentation (which is almost absolutely inaccessible at my level), and watching YouTube videos. I even installed an interpreter on my device to debug code outside of the CodeCademy environment.
I can’t figure out why these were so difficult for me or why my notes helped me so little.

@thegovernment0usa,

It’s understandable that this can be confusing, but let’s first walk through what the exercise wants you to do and then what your code does.

The instructions say that if there are an odd number of elements in the list, the function should return the middle element. This is important because in the tests you ran, both of the odd-length lists had 5 elements, with the middle element being 3. This disguised what was going wrong with your code for the odd elements.

You say that they both correctly yield 3.0…

…but these actually should have yielded 3 (the middle element) instead of 3.0. The fact that the output was the float of the correct answer is just coincidence. You defined oddhalf as len(lst) / 2) + .5, so it doesn’t actually return any of the elements in the list.

To show this in action, look at this example:

middle_element([3, 9, 475, 10, 7])

It should return the integer 475, but instead it will return 3.0.

As for the even-length lists, you are very close. The prompt says to return the average of the middle two elements.
The problem is that you aren’t taking into account that Python lists are zero-indexed. So with this code…

if len(lst) % 2 == 0: # this means it's even
        halflength = int(len(lst) / 2)
        return (lst[halflength] + lst[halflength + 1]) / 2

…when you call the function like this middle_element([5, 2, -10, -4, 4, 5]) you are taking the average of -4 and 4, which is 0.0. You should be taking the average of -4 and -10 and getting -7.0 in return.

If you look at your math, int(len(lst) / 2) is the same as int(6 / 2) in this example, which is 3. The element at position 3 in the list is -4. That is one of the numbers you want to average. However, the the second number that you want to average should be the number in position 2 (-10). Your code selects the number in position 4 (4).

Hopefully this helps dispel some of your confusion!

2 Likes

Thaaaaank you! I always expect it to be some knowledge I’m lacking and it’s almost always a mistake or series of mistakes I for which I should have known better.