Practice Makes Perfect 15/15 Why do I get an error?


#1

My code does what its supposed to do and returns 6, but I get this error:

median([1]) resulted in an error: list index out of range

Why???

My code:

def median(numbers):
  numbers = sorted(numbers)
  character_nr = (len(numbers) + 1) / 2
  index_nr = character_nr - 1
  median = 0
  if len(numbers) / 2 != 0:
    median += numbers[index_nr]
  else:
    char1 = character_nr // 1
    char2 = char1 + 1
    index1 = char1 - 1
    index2 = char2 - 1
    median += (numbers[index1] + numbers[index2]) / 2.0
    
  return median
print median([7, 12, 3, 1, 6])

#2

Hey @codenamephil

It makes it easier for us to run your code, and try and recreate errors, if you format it properly on the forum. (Use the “preformatted text” option at the top of the box :slight_smile: )

Your code is failing when the Codecademy SCT tests it by calling median([1]).

You’ll also be getting an error from the console, pointing you at the source of the error.

Whilst your Traceback will be telling you that the IndexError is here:

median += (numbers[index1] + numbers[index2]) / 2.0

in actuality, the reason your code is failing the test is due to the integer division you’re using in the test for your if conditional block. The test you’re using is wrong, but I’ll explain why it’s causing your error as it’s an interesting example of how the traceback is not the be-all and end-all of debugging. :slight_smile:

When we pass in the single item list [1] to your function, we know the following will be true:

numbers = [1]
len(numbers) = 1
character_nr = 1           # (1 + 1) /2 = 1
index_nr = 0

When we reach your if-else block, we have the following condition:

if len(numbers) / 2 != 0        # or, if (1 / 2) != 0

which we know is going to be evaluated, for a single item list [1], to 1 / 2. In integer division, this works like this:

>>> 1 / 2
0
>>>

so we go to the else branch of your code, where we calculate and assign the following variables:

char1 = character_nr // 1 = 1 / 1 = 1
char2 = char1 + 1 = 1 + 1 = 2
index1 = char1 - 1 = 1 - 1 = 0
index2 = char2 - 1 = 2 - 1 = 1

We then attempt to calculate the median by doing:

median += (numbers[index1] + numbers[index2]) / 2.0
# which is the same as:
median += (numbers[0] + numbers[1]) / 2.0

The problem with this, is that our list numbers has only one element: [1]. So, there is no item with an index of 1, and we get the IndexError that you’re seeing back from Python.

This is a good example of a case where the Traceback is showing you where Python has fallen over, but where the actual problem is elsewhere in the code.

I’ve explained where your code is going wrong; can you see how you need to fix it? :slight_smile:


#3

Thanks for that, i always wondered how to do that :wink:

I see but…when I try this it doesn’t work…

if len(numbers) / 2 != 0:
    median += numbers[index_nr]
  elif len(numbers) < 2:
    median += numbers[index_nr]
  else:
    char1 = character_nr // 1
    char2 = char1 + 1
    index1 = char1 - 1
    index2 = char2 - 1
    median += (numbers[index1] + numbers[index2]) / 2.0

I thought that if i put ELIF the list is less than 2 characters long(or elif len(numbers) == 1), that will execute the same action as the IF statement, but no luck…that way the code in ELSE is executed if there is more than 1 character long list


#4

Ok so I was looking through my code again…and I discovered the little thing in my code that ruined everything…
In my IF statement, I DIVIDE, but I wanted to MODULO!! I have no idea why I put the divide sign there, but now when I put % inside the if statement it works!! :slight_smile: Both with a list with a lenght of an odd number and an even number…and it works even when we have 1 item in the list!!

This is my code now:

def median(numbers):
  numbers = sorted(numbers)
  character_nr = (len(numbers) + 1) / 2
  index_nr = character_nr - 1
  median = 0
  if len(numbers) % 2 != 0:
    median += numbers[index_nr]
  else:
    char1 = character_nr // 1
    char2 = char1 + 1
    index1 = char1 - 1
    index2 = char2 - 1
    median += (numbers[index1] + numbers[index2]) / 2.0
    
  return median
print median([7, 12, 3, 1, 6])   <---prints out 6
print median([7, 12, 3, 1])       <---prints out 5.0
print median([7])                    <---prints out 7

#5

I was hoping you’d notice that. :slight_smile:

Glad you got it sorted. :+1:


#6

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