15/15 Median - Practice Makes Perfect


#1

My code is coming to a halt when checking if the list has an even number of elements. Can anyone help?

def median(numlist):
        #Sortlist 
        numlist.sort()
        #Determine the length
        length = len(numlist)
        #Determine if odd or even
        If length% 2 == 0:
            #If even return the average of the central two numbers (the average of length of array divided by two minus one, and length of array plus one)
            return 0.5*numlist[(length/2)+1]+numlist[(length/2)-1]
        #If odd return the middle item in the center of the array( length of array/2)
            else:
                return numlist[(length/2)]

#2

Hello :smile:

First problem is here:

If length% 2 == 0:

Python is case sensitive, it must be if.

The second problem is related to your else. It must have the same level of indentation as if.


There is also a problem with the way you are calculating the median, but I think that you will be able to figure this out without my help :smile:


#3

Thanks- I spotted these errors but still am having problems. I have modified the code, but am getting error " Oops, try again. median([1]) resulted in an error: list index out of range" From this I guess that the it is receiving an element array with one value ie 1. Therefore the problem must lie somewhere in the part of the code relating to odd numbers. Here is my revised code.

   def median(numlist):
    #Sortlist 
    sorted(numlist)
    #Determine the length
    length = len(numlist)
    #Determine the mid position assuming odd number of elements
    oddmidposition= (length+1)/2
    #Determine the low mid value assuming even number of elements    
    evenlowmidvalue= numlist[(length/2)-1]
    #Determine the high mid value assuming even number of elements 
    evenhighmidvalue= numlist[(length/2)+1]
    #Determine if odd or even
    if length% 2 == 0:
     #If even return the average of the two mid numbers
        return 0.5*(evenlowmidvalue+evenhighmidvalue)
    #If odd return the middle item in the center of the array
    else:
        return numlist[oddmidposition]

#4

This error says that your program tried to access element of the list that does not exist.

If our list is num_list = [1] and, for example, we try to get value of num_list[2] this error will appear.

Let's see what happens in your code, we are interested in lines where you are exctracting values from your list:

oddmidposition= (length+1)/2
evenlowmidvalue= numlist[(length/2)-1]
evenhighmidvalue= numlist[(length/2)+1]
oddmidposition= (length+1)/2

What happens when length of our list is 1?

evenlowmidvalue= numlist[(length/2)-1] = numlist[-1]
evenhighmidvalue= numlist[(length/2)+1] = numlist[1]
oddmidposition= (length+1)/2 = 1

First index (numlist[-1]) is not a problem, this means the same as numlist[len(numlist) - 1].

Second index is incorrect.

Third value is incorrect, it should be 0. To get median where length of the list is odd you should use this formula:

oddmidposition = length / 2

How to fix the problem with the second index?

Well, you can calculate indexes and retrieve data when you are sure that these values exists:

def median(numlist):
    #Sortlist 
    sorted(numlist)
    #Determine the length
    length = len(numlist)
    #Determine the mid position assuming odd number of elements
    oddmidposition = length / 2
    print oddmidposition
    #Determine the low mid value assuming even number of elements    
    evenlowmidvalue= (length/2)-1
    #Determine the high mid value assuming even number of elements 
    evenhighmidvalue= (length/2)+1
    #Determine if odd or even
    if length% 2 == 0:
     #If even return the average of the two mid numbers
        return 0.5*(numlist[evenlowmidvalue]+numlist[evenhighmidvalue])
    #If odd return the middle item in the center of the array
    else:
        return numlist[oddmidposition]

But there is still one more problem to solve. Think again about the way to calculate the median when length of the list is even.

You have to change this line:

evenhighmidvalue= numlist[(length/2)+1]

Just think about it for a while.


#5

Thanks for the help.I fixed it
Part of my problem was forgetting that the array starts at position 0. The second problem was that sorted(numlist) doesn't appear to sort, so I used numlist.sort() instead, which works fine.
.
I amended oddmidposition to: oddmidposition= ((length+1)/2)-1. This worked. Maybe your version would have worked too ie. oddmidposition = length / 2 -but if the array length is 1 then this would evaluate to 0.5 which is not an integer.


#6

Great!

Just to clarify: 1 / 2 is 0, not 0.5 :smile:


#7

This will not add anything except food for thought; you two have done a great job of resolving the issues, I just wanted to toss this in, in retrospect:

oddmidposition = length / 2
# ...
evenhighmidvalue= length/2

In other words, the evenhighmidvalue is at the same index as oddmidposition, so if it is already present in memory, we don't need this one.


#8

Thanks Roy, I did not notice it. Great advice!


#9

This is a complete segue...

The above resembles a prime pair problem. Given two odd numbers around an even axis divisible by 6...

l = n * 6 - 1
u = n * 6 + 1

If l and u are both prime, then this represents a prime pair.

It further illustrates that such a pattern will always render around a central pivot. n * 6 - 1 and n * 6 + 1, where n * 6 is obviously in between.