Common errors

  • Now we know quite a lot more concepts, we also have bigger potential to get in trouble.

  • Here is a list of common errors I see in programming. I will organize by topic.

    Remember: each of the examples below will give an error or are frowned upon, make sure you know why. Don’t do the stuff here in your programs or in your exams.

Functions

  • Massive functions that do many things: find if a value is ok to add to sudoku, add it and then print it. Too much, divide into smaller functions that are easier to decode.

  • Use functions that do not return something incorrectly.

    y = [1,2,3]
    y = y.sort()
    print y
    

    As y is now None, we basically lost the value for y.

  • Using functions that return something incorrectly.

    def do_stuff(x):
        x += 5
        return x
    
    x = 5
    do_stuff(x)
    print x
    

    Realize that when you call the function, it changes the local variable x, not the global one. Do not use global values to fix this. Instead, simply assign the returned value to a variable before printing. The correct call would look like this:

    x = do_stuff(x)
    print x
    
  • Functions that use global variables:

    def print_team(id):
        print teams[id]  ## teams is a global variable here.
        ## if teams is not defined at the time you call this
        ## function, you will get into trouble.
    
  • Functions that have completely useless arguments

    def print_team(id):
        id = 1
        print id
    

    Why did we even bother to use the argument id if you are going to overwrite it in the function. The function would work the same if you did not have it at all:

    def print_team():
        id = 1
        print id
    

    At least, this function is honest about not really needing any arguments.

  • Write functions that do not always return something (by accident).

    def is_good(val):
        if val > 4:
            return 'good'
        elif val > 1:
            return 'medium'
    

    This function returns nothing for some values of val, what are they?

  • Functions that are supposed to change a list, but does not.

    This one is subtle!

    def cap_val(L):
        L1 = []
        for val in L:
            L1.append( val.capitalize() )
        L = L1 ## you are changing the local alias L
               ## not the original list L points to
    

Loops

  • Trying to change values in a list using for loop.

    animals = ['dog','cat','pig']
    for a in animals:
        a = a.capitalize()
        ## you are only capitalizing the local copy of the
        ## string, not the one in the list.
    

    If you want to modify a list, use indexing instead:

    animals = ['dog', 'cat', 'pig']
    for i in range(len(animals)):
        animals[i] = animals[i].capitalize()
    

    Of course, you can do the same with while loops as well.

  • Trying to remove a list while iterating over it with a for loop

    This is subtle! But, if you are iterating over a list and want to remove some elements. It messes up some indices if you do this:

    >>> animals = ['cat','dog','pig','cow']
    >>> for a in animals:
    ...     print a
    ...     if a == 'dog':
    ...         animals.remove(a)
    ...
    cat
    dog
    cow
    

We missed pig altogether, why? Because the loop was looking for the next item (indexed at 2), which after removing dog was now cow. It got confused. It is very hard to write keep track of this. Why not do this instead?

Create a new list but copy only the values you want, and then assign it to the original list:

>>> animals = ['cat','dog','pig','cow']
>>> new_animals = []
>>> for a in animals:
...     print a
...     if a != 'dog':
...         new_animals.append(a)
...
cat
dog
pig
cow
>>> animals = new_animals
>>> animals
['cat', 'pig', 'cow']

Strings

  • Forget that strip() will only removed the stripped value from ends, not middle of string.

  • Forget that split() will split before and after the split value.

    >>> a = "this\nis\nsparta\n"
    >>> a.split('\n')
    ['this', 'is', 'sparta', '']
    >>> b = "this\nis\nsparta"
    >>> b.split('\n')
    ['this', 'is', 'sparta']
    

Files

  • The most common error I see is reading a file and then splitting it. This is fine, but beware of the split issue above:

    f = open('300.txt')
    filecontent = f.read()
    lines = filecontent.split("\n")
    i = 1
    for line in lines:
        print "Line no: %d, Line: %s" %(i, line)
        i += 1
    

    In this program, you will get an extra line if the last line ended with a new line. When you split this file, you had an extra empty string as show in the split operation above.