15. median


#1

https://www.codecademy.com/courses/python-intermediate-en-rCQKw/2/5?curriculum_id=4f89dab3d788890003000096

The code that I wrote compiles fine, but it tells me the calculation of the median is messed up. I can't figure out what I've done wrong in terms of how the median is calculated--does anyone see something that I don't???

def median(lst):
    sorted([lst])
    for numbers in lst:
        if len(lst) % 2:
            mid = (len(lst) / 2)
            next_mid = mid - 1
            middle = (int(lst[mid]) + int(lst[next_mid])) / 2.0
            return middle
        elif len(lst) == 1:
            return lst([0])
        else:
            midodd = len(lst) / 2
        return lst[midodd - 1]
median([2, 3, 1, 4])

Oops, try again.
median([4, 5, 5, 4]) returned 5 instead of 4.5


#2

lst is already a list. This exression is making it the sole member of another list, so is not being sorted.


#3

Some more comments in addition to @mtf's insight to bring you back on the right track, it might not be everything, but it gets you closer.

It's true that Python gets compiled in some sense (to byte-code) but the program is executed by another program (a Python interpreter) and the only or at least almost only compile-time checking of your code is syntax. Most crashes therefore happen as the program runs, that's the nature of dynamic languages.

You have a for-loop in your code. How many iterations will it perform? It's not really a loop after all, is it, keep your code clean, remove everything that doesn't have a purpose.

len(lst) % 2
doesn't evaluate to True for even numbers. Consider what % does and consider, or test, what bool(1) is.

length=1 isn't a special case, it's an odd length

Parentheses can help clarify things, but too many is just clutter.

lst([0]) is lst a function, or something else that can be called? Because that is calling lst.


#4

Thank you so much for your help. Here is my new code, but I have a few questions:

def median(lst):
sorted([])
for numbers in lst:
if len(lst) == bool(1):
mid = (len(lst) / 2)
next_mid = mid - 1
middle = (int(lst[mid]) + int(lst[next_mid])) / 2.0
return middle
elif len(lst) == 0:
return lst
else:
midodd = len(lst) / 2
return lst[midodd - 1]
median([2, 1, 3, 4])

What does bool(1) exactly mean? What parentheses do you think I have to change? how do I sort a list without sorting it in the same list? Can you help me understand what I am doing wrong?


#5

Start by sorting the actual lst given in the parameter:

ordered = sorted(lst)
# or
lst.sort()

Then store the length:

count = len(lst)   # (or len(ordered) if you used that approach)

Now we can set up the odd/even conditions and return the appropriate median value. For an odd length, the median value will be the floor (integer) that results from integer division:

lst[count/2]

For an even length, the median is the computed average of the middle two elements. It will be a float, so we'll use float division:

(lst[count/2] + lst[count/2 - 1]) / 2.0

This is what you already have, so sort out the return values and you should be away. Of course, we can further simplify, but get it working correctly first, then refactor/simplify if you feel like a challenge. Remember to return the median values, not a list.

Now as to your question,

This is a built-in function for converting a value to a Boolean. bool(1) will return True. I don't see a need for it in this program and that means the line it is contained in may be removed.

The SCT doesn't test with an empty list, but if you wish your program to test, then return an error message, not a list or other object.


#6

You have a "condition" that evaluates to 1 which if converted to bool is True. So if the remainder is 1, then that expression is True, which it should not be.


#8

Thanks so much; I did what you said and here's my code,

def median(lst):
lst.sort()
count = len(lst)
for numbers in lst:
if count % 2.0:
answer = (lst[count/2] + lst[count/2 - 1]) / 2.0
return answer
elif count == 0:
return lst[0]
else:
answer2 = lst[count/2]
return answer2
median([2, 1, 3, 4])

But I still get the same error for it--

Oops, try again.
median([4, 5, 5, 4]) returned 5 instead of 4.5

Any insight into why this error is still happening?


#9

could be written,

    if count % 2:

However, if this is true, then there is a remainder, so the length is odd. The action you are currently instructing is for the even length.

This should return an error message, not a value.


#10

THANK YOU VERY MUCH, the code below works!

def median(lst):
lst.sort()
count = len(lst)
for numbers in lst:
if count % 2 == 0:
answer = (lst[count/2] + lst[count/2 - 1]) / 2.0
return answer
elif count == 1:
return (lst[0])
else:
answer2 = lst[count/2]
return answer2
median([2, 1, 3, 4])