0

I'm having trouble with this code. Although name errors seem to be prevalent, I couldn't find a fix by searching. Here's the code...

def fmp_sel():
 with open ('MonPlotDb.csv', 'rU') as csvfile: 
 next(csvfile, None)
 fmpList = csv.reader(csvfile, delimiter=',', dialect=csv.excel_tab)
 for item in enumerate(fmpList):
 print "[%d] %s" % (item)
 while True:
 try:
 in_Sel = raw_input(('''Choose from list or 'q' to quit:''')) 
 if in_Sel == 'q':
 print 'Quit?' 
 conf = raw_input('Really? (y or n)...') 
 if conf == 'y': 
 print 'Seeya!' 
 break
 else:
 continue 
 plotOrig = DataPlotLoc[int(in_Sel) + 1] 
 print 'You selected', plotOrig[1] 
 break
 except (ValueError, IndexError):
 print 'Error: Try again'

and the traceback....

File "E:\FireRegDb\Rec_2012\dblist_outonly.py", line 28, in fmp_sel 
plotOrig = DataPlotLoc[int(in_Sel) + 1] 
NameError: global name 'DataPlotLoc' is not defined

This function is being called from main() but I can't see why 'DataPlotLoc' is a global name as it's within this function. Either way, I think I'm missing a line to define it but how and where, I don't know. I would love some help.

EDIT: Just to add some more info..'DataPlotLoc' was the name of the list when it was inserted into the code ie. DataPlotLoc=[['a', 'b', 'c',....]] and it worked. The line plotOrig = DataPlotLoc[int(in_Sel) + 1] refers to this list, but obviously it's now being read in by csv.reader so now I'm not sure how to assign this variable. I assumed I still need it to accept an integer after confirming if the user enters 'q' or not and the +1 is to add to the number entered so it aligns with the correct index number for the corresponding row item selected from the list. Sorry if this is a bit confusing, but I'm a bit confused myself...

asked Apr 22, 2013 at 23:36

2 Answers 2

2

Well, as the error message says, you're using DataPlotLoc before defining it. If you search your code you'll see it's never defined anywhere. Can't really answer more than that without knowing what you mean it to be.

Python assumes you meant the global variable of that name because you never assigned anything to it, which would have made it a local variable.

answered Apr 22, 2013 at 23:41
Sign up to request clarification or add additional context in comments.

2 Comments

+1. The "global name" part of the error can be a bit confusing to new users, but the easy way to think about it this: If you don't define DataPlotLoc either locally or globally, the error message says "global". If you want to understand why that's what the error message says, you have to learn how Python decides when to look for locals vs. globals; if you just want to fix it, just assign it either locally or globally, whichever is appropriate for your design.
As you may be able to see, I'm trying to get user input first to check if they enter 'q', then accept integer input after, which is an index number for the user to select a row in the list. I can now see how I haven't defined DataPlotLoc, but this should be the csv file name correct??
0

Python is saying global name ... not defined because it doesn't see any assignment to DataPlotLoc inthe function body, so it assumes it must be a global variable, and fails to find it there. (See abarnert's comment below)

Judging from your code, I imagine you want DataPlotLoc to contain the information you extract from MonPlotDb.csv, in which case you need to do two things:

(A) Initialize DataPlotLoc

def fmp_sel():
 DataPlotLoc = [] # <-----------------!!!!
 with open ('MonPlotDb.csv', 'rU') as csvfile:

(B) Append the values to DataPlotLoc while you're looping and printing the options.

 next(csvfile, None)
 fmpList = csv.reader(csvfile, delimiter=',', dialect=csv.excel_tab)
 for item in enumerate(fmpList):
 DataPlotLoc.append(item[1]) # <---------!!!
 print "[%d] %s" % (item)

I'm not sure why you add one in the line for plotOrig = DataPlotLoc[int(in_Sel) + 1], and I think you may be able to simplify your csv.reader line to the following csv.reader(csvfile) (I think excel with commas is the default behavior)

Edit: To extract just one column from each row of the CSV change the code in part B to something like the following:

 next(csvfile, None)
 fmpList = csv.reader(csvfile, delimiter=',', dialect=csv.excel_tab)
 for item in enumerate(fmpList):
 i, data = item # enumerate returns tuples of the form (i, data)
 vals = (i, data[1]) # <----- put in the proper index of the column
 DataPlotLoc.append(vals)
 print "[%d] %s" % vals # <--- assuming you want to change the print as well
answered Apr 22, 2013 at 23:51

8 Comments

PS, anyone know if the Markdown spec has been updated to allow starting lists at numbers other than 1? the code blocks and the numbering don't play nicely...
It's not really true that "the last place it looks is in the globals". That's a useful way to think about it for novices, but the reality is that Python is only looking in the globals. (At the time it evaluated the function body to make a code object, it saw that there were no explicit assignments to DataPlotLoc, and therefore didn't add it to co_names. So, even if you sneak a value into locals, Python will never look there.) So kindall's answer is more accurate. But I think, if you changed this one so it wasn't technically false, it might be more useful.
I don't need it to be a global variable. That line is supposed to allow integer input and the selection from the list based on index number (hence the +1 to line up with correct index number once header row is removed). This was working when I had the actual list at the top of the function ie. DataPlotLoc=[[a, b, c, d.....] but I wanted to read it from csv file therefore I added the 'with open....' line. Not sure where to go from here
The CSV reader does not define any local variables (it can't), so it's up to you to define them. The two lines I've marked are creating this list for you so that you can access it later on.
@Felipe..you're a champion! I was trying this solution yesterday but kept getting NameError. Tried again this morning and it seems to work. Must have had 1 line in wrong spot. Thanks again. If I can push my luck, what if I want just the index number col (col 0 I assume that's created after enumerate) and col 2 (the name of the plot)? Any chance??
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.