Why does it have red squiggly lines under it if it works perfectly fine and no errors happen when I run it?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sat Sep 21 06:25:29 EDT 2013


On Fri, 20 Sep 2013 23:07:57 -0700, William Bryant wrote:

> I am 13 year old beginner in
> python and i am trying to finish the tutorial on code academy and read
> the docs. :)

Hi William, 

I think this is about the fifth or sixth time you've told us this. I'm 
really pleased that a youngster like you is learning to program, but you 
don't have to apologise for your youth in every second email, you're 
starting to make us oldies jealous :-) 

Perhaps when you start a new question, it's okay to remind us. But if 
you're a regular here, we'll soon learn your level of experience.


> def median():
>     medlist = List
>     medlist.sort()
>     if len(medlist) % 2:
>         while len(medlist) > 2:
>             medlist.popleft()
>             medlist.popright()
>         if medlist[0] == medlist[1]:
>             themedian = medlist
>         elif medlist[0] != medlist[1]:
>             #make an if statment to figure out the median if the last 2
>             left are not the same. Eg [1, 2] the middle value is 1.5
>             pass
>     else:
>         while len(medlist) > 1:
>             medlist.popleft()
>             medlist.popright()
>         themedian = medlist
>     return themedian
> 
> It says out of range

If you're going to be a coder, for fun or profit, there are some skills 
you need to learn. One of those skills is to copy and paste the whole 
traceback, not just paraphrase the error message at the end. In this 
case, I can guess what is going wrong without seeing the whole traceback, 
but in general it is best to copy everything from the line

Traceback (most recent call last)

to the end of the error message.

In this case, there is a better approach to calculating the median. Start 
by thinking about how you would calculate it by hand:

* sort the numbers;
* if there is an odd number of items, pick the middle one;
* otherwise pick the two middle ones and take the average.

Python can do the same thing. There's no need to delete items one by one 
from the ends of the list until there are only one, or two left. If you 
have a million items, that would be terribly slow...

So, here we go:

def median():
    # Relies on the global variable called List.
    List.sort()
    n = len(List)
    if n % 2 == 1:
        # Odd number of items.
        return List[n//2]
    else:
        a = List[n//2 - 1]
        b = List[n//2]
        return (a + b)/2.0


There's a couple of useful things to learn from this:

1) In a couple of places, you'll see n//2, which looks like division but 
with the / doubled. This is not a typo! It performs integer division, 
throwing away any remainder instead of giving you a fraction. So:

21//7 => 3

22//7 => 3


2) You'll also see a few places where I say List[...] with something 
inside the square brackets. This is looking into the list to grab 
whatever element is in the position. For example:

>>> L = [100, 110, 120, 130]
>>> L[0]  # List indexes start from zero, not one
100
>>> L[1]
110
>>> L[2]
120
>>> L[3]
130


So you can look up the element at any position inside a list in a single 
operation, without needing to throw elements away first. Just remember to 
start counting at zero, not one!


3) Last but not least, the last line divides by 2.0 instead of 2. Why 
2.0? Unfortunately, older versions of Python treat single-slash 
division / differently depending on whether the values have a decimal 
point or not. This was a bad design, and Python 3 has fixed that, but I 
don't know whether you have Python 2 or Python 3. So to be safe, I divide 
by 2.0 to ensure that it calculates the right answer no matter what 
version you are using.



Regards,



-- 
Steven



More information about the Python-list mailing list