Median Madness


#1

Okay so I feel confident that this is as refined as I could make my code. I basically made 2 if statements: one that takes the middle number of a list whose length is an odd number; the other takes the middle two numbers and averages them together.

What am I doing wrong?

def median(lst):
    lst = sorted(lst)   #Turns lst into a sorted list
    if len(lst) % 2 != 0:
        return lst[int((len(lst)/2.0))]   #Returns the item that sits in the middle, assuming the length of the list is an odd number
    else:
        if len(lst) % 2 == 0:
            return ((lst[len(lst)]/2.0) + ((lst[len(lst)]/2.0)-1.0) /2.0) #Returns the average of the 2 items that sit in the middle, assuming the length of the list is an even number

Here's the error I am getting: > Oops, try again. median([4, 5, 5, 4]) resulted in an error: list index out of range


#2

return ((lst[len(lst)]/2.0) + ((lst[len(lst)]/2.0)-1.0) /2.0)

This part of code is buggy.
List's index can't be a float and also list index lies between 0 to len(list) - 1 (if you're using positive index)

You need to find average of two mid numbers ,as number of items in list are even.

Also..

return lst[int((len(lst)/2.0))]

You can just get advantage of Python 2.0's behavior of / operator.
No need to use int() but you need to make 2.0 as 2.

Python 2.0

integer / integer -- > result will be an integer
if any of the number/operand is float ,we will have float.

Python 3.0
anyNumber / anyNumber -- > Float
It returns a float value.


#3

It's not actually a behavior as much as how rationals are treated. When one or the other of numerator/denominator in a rational expression is a float, the quotient is a float. When both are integers, the quotient is an integer. To many readers, x / 2.0 does not make sense since 2 is a counting number, not a float. Changing it to a float is a sort of cudgel.

When dividing an unknown quantity by a known integer, be explicit and declare the float on the unknown quantity and leave the integer alone. Then your code doesn't look like it is fudged.

float(x) / 2

where x can be any expression that yields a number.

Fortunately in Python 3 this problem is addressed and all quotients are floats unless explicitly declared as integers.


#4

Can we say that operator EDIT : / (TYPO: \ ) acts with respect to operands it gets and yields float/int accordingly? (Or we should just go with same definition as mentioned,As words are quite vague so Im asking this :slight_smile:)


#5

Not to be overly critical, but your code is not very D. R. Y. There is a lot of repetition of patterns. This suggests caching of the expression as a first step toward simplicity.

Approaching the problem from a planning perspective first, helps us to create a DRY program from the start.

What are the knowns?

  1. An unordered sample space
  2. The size of the sample space

What do we need to compute?

  1. Sort the sample space
  2. The middle index
  3. The average of the middle two data elements if sample size is even

What do we return?

  1. The value in the middle element if sample space size is odd
  2. The average computed above if even.

Only the second case needs to be a float. The other is not a computed value.

""" Sort sample space """
ss = sorted(lst)
""" Cache the size """
n = len(ss)
""" Compute the middle """
m = int(n / 2)

The above turns this,

return lst[int((len(lst)/2.0))]

to this,

return ss[m]

and it turns this,

return ((lst[len(lst)]/2.0) + ((lst[len(lst)]/2.0)-1.0) /2.0)

to this,

return float(ss[m -1] + ss[m]) / 2

It never hurts to study the problem while you plan. When we start with something simple, it is easy to extend and easy to debug or find omissions.


#6

@mtf thanks for your response! I am not sure what D.R.Y. Really means and I am not sure if I completely understand your suggestions.

I belive what I need to do is fix the 'else' statement by eliminating my int() and replacing '/ 2.0' with '\ 2' ? I'm at work now so can't test it out.


#7

The back slash is not a math operator as far as I know. It is the line continuation operator

return homework * 0.1 + \
quizzes * 0.3 + \
tests * 0.6

#8

Oh my Bad, Typo!
Just Fixed.


#9

It is programming acronym that means, Do not Repeat Yourself.

Ask questions.


#10

The forward slash indicates division or a fraction. As long as we are working in Python 2, the nature of the operands determines the outcome. No floats in the rational means integer yield value, otherwise float. Using the trick of fudging a float to force a float yield is valid code, but as mentioned above may leave some readers scratching their head. I prefer the explicit declaration, but I'll leave it at that.


#11

Thanks for your help!


#12

Thank you, this made it much cleaner and easier for me to understand! So "caching" refers to the simplification through the creation of reusable mini-blocks/tools within the program?


#13

In a sense. A reusable block would be a function, so not cached as such, but defined. Caching is when we store a value that appears in more than one place in the code. In the example, we cached the length since it is referred twice...

m = int(n / 2)

and

if n % 2:

The middle is also cached since we refer to it in both conditional branches. There is a minimum of computation that needs to take place in the return statements.


#14

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.