Practice makes perfect 15/15


#1

https://www.codecademy.com/courses/learn-python/lessons/practice-makes-perfect/exercises/median?action=lesson_resume

First of all, when I run the solution given by codecademy, there’s a error “TypeError: list indices must be integers, not float”.

Secondly, below is my code, and it says invalid syntax in line 10 return result. What could possibly go wrong with this? Besides, is the int() necessary since we already know the number inside a[ ] must be an integer? Finally, codecademy tells me that this code turns out to be 4 instead of the correct number 4.5. I have no clue which part is wrong. Please help! Thanks a lot.

def median(a):
  a = sorted(a)
  amount = 0
  for item in a:
    amount = amount + 1
  if amount % 2 != 0:
    result = a[int((amount+1)/2-1)]
  else:
    result = (a[int((amount/2)-1)]+a[int(amount/2)]/2
  return result

a = [4,5,5,4]
print(median(a))

#2

Do you still have a copy of that code? Otherwise this is a non-question.

Not sure I follow where that code is going.


#3

Yes. The code is below. This is the solution given by codecademy. When I run it using a real python such as through the PowerShell, it says “list indices must be integers or slices, not float.”

def median(lst):
    sorted_list = sorted(lst)
    if len(sorted_list) % 2 != 0:
        #odd number of elements
        index = len(sorted_list)//2 
        return sorted_list[index]
    elif len(sorted_list) % 2 == 0:
        #even no. of elements
        index_1 = len(sorted_list)/2 - 1
        index_2 = len(sorted_list)/2
        mean = (sorted_list[index_1] + sorted_list[index_2])/2.0
        return mean
   
print median([2, 4, 5, 9])

For the second part, the code is for counting the number of list ‘a’. But actually I should have just used len(a) instead.


#4

The difference is the Python versions. This site is presently on 2.7.x which in terms of division will return an integer quotient if both numerator and denominator are integers.

7 / 5    #->  1     2.x

7 / 5    #->  1.4   3.x

As we can see, 3.x returns floats by default. Integers must be cast. In 2.x, floats must be cast.

The CC code is correct(ish) on the site. For 3.x we need to be explict about index being an int.


Looking more closely at that code, we see floor division in the first branch, but not in the second. Floor division gives an explicit integer result.


#5

Thanks! Why is line 10return result a bad input then?

def median(a):
  a = sorted(a)
  amount = 0
  for item in a:
    amount = amount + 1
  if amount % 2 != 0:
    result = a[int((amount+1)/2-1)]
  else:
    result = (a[int((amount/2)-1)]+a[int(amount/2)]/2
  return result

a = [4,5,5,4]
print(median(a))

#6

Commentary

Floor division is useful in computation, but can be missed by the reader.

int(n / 2)

is easy to spot, and to read.

One thing I like to do is scale down to bare bones and work on the code structure and syntax. Then it is easy to debug. Once the code is acceptable, then the readability aspect can be considered and all the variables given appropriate names.

A lot of times a piece of code turns out to be a utility that is self evident, and in many cases a pure function. These can be written like math functions and still be understood by the reader. It’s important that we as writers are able to draw the distinction, and employ intelligent naming schemes that will help both our reader, and us six months down the road.

median is a utility function that does not need a lot of documentation. The code speaks for itself if we make it readable, and avoid duplication.

def median(sample):
    s = sorted(sample)
    n = len(s)
    m = int(n / 2)
    return s[m] if n % 2 else float(s[m - 1] + s[m]) / 2

Style guides will tell us not to use single letter variables, but I think there is some wiggle room. This is not a zero-sum priority.

In six months time will we the reader be able to analyze the above code? Absolutely. What does that tell us? Verbose names are not always needed. The header line and the second line do all the talking for us.


#7

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