While and If messing up my program?

Steven D'Aprano steve at REMOVETHIScyber.com.au
Wed Oct 5 15:39:31 CEST 2005


On Wed, 05 Oct 2005 06:48:59 +0000, CJ wrote:

>  
>    Hey, I'm new to the Python world, but I do have experience in several 
> other languages. I've been running through a tutorial, and I decided that 
> I'd make a program that runs through a list, finds if there are any 
> duplicates. The program, doesn't work, but since its a first build I 
> wasn't too worried about it. I'd be highly impressed if I got the program 
> to run correctly in the first build, I want to debug it myself later.
> 
>    What does worry me, is that I can't seem to get the program by a 
> certain spot. It keeps giving me the same error, and I don't know why.

Here are some techniques for tracking down this sort of bug. The best
thing is, these techniques will help you write better code in the first
place, as well as easier to debug.


Firstly, encapsulate your code. Instead of writing one big lump of code,
break it into small digestible functions.

def run_test():
    choice=raw_input("Begin? ")
    return choice == "yes" or choice == "y"
    # or better still:
    # choice.lower() in ("yes", "y", "begin"):


def do_test(ttllst):
    # initialise variables
    cnto=0
    cntt=1
    rept=-1
    # loop through the list, counting duplicates
    while cnto<>len(ttllst)+1:

        print "debugging...", cnto, cntt

        if ttllst[cnto]==ttllst[cntt]:
            rept=rept+1
        if cntt==len(ttllst):
            print ttllst[cnto],"appears in the list",rept,"times."
            cntt=-1
            cnto=cnto+1
            rept=-1
        cntt=cntt+1
    print "done."


def main():
    if run_test():
        ttllst=[4,3,45,3]
        do_test(ttllst)

if __name__ == "__main__":
    # only happens when *running* the file, 
    # not when *importing* it
    main()


Now you have separated your user interface from the business end of your
code, and you can isolate more simply where the error lies.

Continue to encapsulate your code: the while loop is a good candidate. It
runs through the list comparing each character to one known character. So
I would change do_test to look like this:

def do_test(L):
    """Run our item-counting test on list L."""
    # loop through the list, counting duplicates
    for index in range(len(L)):
        current_item = L[index]
        item_count = item_counter(L, current_item)
        print current_item, "appears in the list", item_count, "times."
        # or better still
        # print "%s appears in the list %d times." % (current_item,item_count)
    print "done"


def item_counter(L, obj):
    """Return the number of times obj is in list L."""
    counter = 0
    for item in L:
        if item == obj:
            counter = counter + 1
    return counter

Now that you (hopefully) have bug-free code, you can continue to improve
and optimize your program. For example, instead of creating your own
item_counter function, you will soon learn that Python lists have their
own much quicker version.

In general, you want to make your code as general as practical, without
being too specific. You started with the problem "How can I count the
number of times each item in list ttllst exists in ttllst?" A more general
question is "How do I count the number of items *any* object exists in
*any* list?", and then use that code to answer your first question.


Hope this helps,



-- 
Steven.




More information about the Python-list mailing list