On Fri, 7 Jan 2005, Mark Kels wrote:
> I started to read the following code (I will start working on it when > this problem is fixed) and it looks OK while I read it. But for some > reason it doesn't work... Hi Mark, Ok, let's take a look at the error message: > Traceback (most recent call last): > File "C:\maillist.py", line 80, in ? > useMailList.writelines(memMailList) # Copy internal mailing list to > file > > NameError: name 'memMailList' is not defined Ok, good, so we know what we should look for: we should see where 'memMailList' is defined, and see if there's any way that the program flow can route around the definition. Ok, I see it, embedded within the context of a try/except block. ###### try: ## some code before definition of memMailList... memMailList=useMailList.readlines() ## some more code cut... finally: useMailList=open("maillist.txt", "w") useMailList.writelines(memMailList) useMailList.close print useFoot.read() useHead.close; useFoot.close; ###### There's one possibility that strikes me: it's very possible that in the code before the definition of memMailList might raise an exception, or exit out prematurely due to a sys.exit(). If that happens, then Python will finish things up by jumping into the 'finally' block. And if that happens, then we haven't reached memMailList's definition, and the NameError is inevitable. Here's a simplified example of what might be happening: ### >>> try: ... a = 42 ... 5 / 0 ... b = 17 ... finally: ... print "a is", a ... print "b is", b ... a is 42 b is Traceback (most recent call last): File "<stdin>", line 7, in ? NameError: name 'b' is not defined ### A direct way to debug this is to drop the 'finally' block altogether. If we do so, like this: ###### ## some code before definition of memMailList... memMailList=useMailList.readlines() ## some more code cut... useMailList=open("maillist.txt", "w") useMailList.writelines(memMailList) useMailList.close print useFoot.read() useHead.close; useFoot.close; ###### then the real cause of the problem should pop up quickly. A few more comments: 1. The calls to close() need parentheses. Unlike some other programming languages, function calls fire off only with parens. Instead of: useFoot.close you probably want: useFoot.close() 2. I also see that the code is hardcoded to use Python 1.5. Is there any way you can use a more modern version of Python? The reason I ask is that recent versions of Python have really good modules for debugging CGI programs, including the excellent 'cgitb' module: http://www.python.org/doc/current/lib/module-cgitb.html Writing CGI programs without 'cgitb' is almost criminal. *grin* If you can, use it. 3. The program is long. Can you break it down into some functions? The program looks like one big monolith, and I'm actually quite terrified of it. *grin* Small functions are much easier to debug, and more approachable for maintainers of the code. This is a style critique, but it does matter because although computers don't care what code looks like, human programmers do. 4. Related to Comment Three is: there are way too many comments on the side margin. Comments like: ### if email != email2: # Checks to see if two entered # email addresses match print "Email addresses do not match" # If no match print error sys.exit(0) # Exit script with error 0 elif password != password2: # Checks to see if two # entered passwords match print "Passwords do not match" # If no match print error sys.exit(0) # Exit script with error 0 ### are redundant, since they basically parrot what the code is doing. Concise comments that explain the reason why the code is doing what it's doing can be more useful. Comments are meant to show us authorial intension: if we were interested in what the code was actually doing, we'd just read the code. *grin* Something like: ###### ## Check for valididated emails and passwords, and exit if either are ## invalid. if email != email2: print "Email addresses do not match" sys.exit(0) elif password != password2: print "Passwords do not match" sys.exit(0) ###### is probably sufficient. Even better would be to break this out as a function: ### def validateEmailsAndPasswords(email, email2, password, password2): """Check for valididated emails and passwords, and exit if either are invalid.""" if email != email2: print "Email addresses do not match" sys.exit(0) elif password != password2: print "Passwords do not match" sys.exit(0) ### but I guess we should take this one step at a time. If you have any questions, please feel free to ask. I hope this helps! _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor