Reputation: 31
I have a text file describing resumes where each line looks like:
name university sex filename
So one line would say something like
John Texas M resume1.doc
The file has standard formatting and does not contain any errors. There are four possible names and four possible universities, randomized to create 64 resumes. I'm trying to write a program that reads through the text file, creates a resume object with attributes for the name, university, sex, and filename, and adds these objects to a list of resume objects. I have a lot of experience in C++, but this is my first Python program and I'm getting thrown off by an error:
File "mycode.py", line 142, in <module>
resumes()
File "mycode.py", line 65, in resumes
r = resume(name,uni,sex,filename)
NameError: global name "name" is not defined
My code looks like:
class resume:
def __init__(self, name, uni, sex, filename)
self.name = name
self.uni = uni
self.sex = sex
self.filename = filename
mylist[]
def resumes():
f = open("resumes.txt",'r')
for line in f:
for word in line.split():
if word == ("John" or "Fred" or "Jim" or "Michael"):
name = word
elif word == ("Texas" or "Georgia" or "Florida" or "Montana"):
uni = word
elif word == "M":
sex = word
elif re.match(r'\w\.doc',word):
filename = word
r = resume(name,uni,sex,filename)
mylist.insert(r)
I'm not sure if the error is in the class or the function. My computer isn't showing any syntax errors but I'm new to this so if there are, please feel free to tell me how to fix them.
I've tried defining name, uni, etc. outside the "for word in line.split()" loop but the program still had an issue with the line "r = resume(name,uni,sex,filename)" so I'm not sure what the issue is. I've read through other answers about NameError but I'm new to Python and couldn't figure out the equivalent problem in my code.
Upvotes: 3
Views: 1195
Reputation: 2469
Your code is throwing a NameError
because at some point in the iteration of your file, some word
variable doesn't fulfill any of the conditionals in this line of your function: if word == ("John" or "Fred" or "Jim" or "Michael"):
, and name
doesn't get defined.
The simplest way to workaround this error is to assign default values to your variables outside the scopes of your class and function (or within the scope of your function):
name = "name"
uni = "uni"
sex = "sex"
filename = "filename"
class resume:
# rest of your code
As an alternative, you could include conditional checks within your function for your variables; if the variable isn't yet defined, assign it a default value:
if "name" not in locals():
name = "name"
r = resume(name,uni,sex,filename)
Finally, you'll want to append a colon to this line, from this:
def __init__(self, name, uni, sex, filename)
to this:
def __init__(self, name, uni, sex, filename):
change this line where you intialize mylist
from this:
mylist[]
to this:
mylist = []
and change:
mylist.insert(r)
to:
mylist.append(r)
Upvotes: 1
Reputation: 4010
The NameError
is caused by undefined variables in cases where no values are found in the text file. Define them within the function before you try to assign values from the text file to them:
def resumes():
f = open("resumes.txt",'r')
for line in f:
name = ""
uni = ""
sex = ""
filename = ""
for word in line.split():
...
You can also pre-define the variables in your class initialization by using keyword arguments if you like (this isn't the cause of the NameError
though):
class resume:
def __init__(self, name="", uni="", sex="", filename="")
self.name = name
self.uni = uni
self.sex = sex
self.filename = filename
Defining a list in python is done by typing mylist = []
, not mylist[]
. Also, at the moment, the list would be defined in the global namespace which is generally discouraged. Instead, you can make resumes
return a list and assign this value to mylist
:
def resumes():
resume_list = []
f = open("resumes.txt",'r')
for line in f:
for word in line.split():
if word == ("John" or "Fred" or "Jim" or "Michael"):
name = word
elif word == ("Texas" or "Georgia" or "Florida" or "Montana"):
uni = word
elif word == "M":
sex = word
elif re.match(r'\w\.doc',word):
filename = word
r = resume(name,uni,sex,filename)
resume_list.insert(r)
return resume_list
Then you can do the following anywhere in your code:
mylist = resumes()
Remember to close files after opening them; in your case by calling f.close()
after processing all the lines. Even better, have python manage it automatically by using the context manager with
so you don't have to call f.close()
:
def resumes():
with open("resumes.txt",'r') as f:
for line in f:
...
Typically, you'd use append
rather than insert
when working with lists. insert
takes two arguments (position/index, and the element to insert) so mylist.insert(r)
should raise a TypeError: insert() takes exactly 2 arguments (1 given)
. Instead, do mylist.append(r)
to insert r
after the last element in the list.
As, johnrsharpe pointed out in the comments, your word comparisons probably aren't doing what you expect. See this example:
>>> word = "John"
>>> word == ("John" or "Fred" or "Jim" or "Michael")
True
>>> word = "Fred"
>>> word == ("John" or "Fred" or "Jim" or "Michael")
False
>>>
Instead, use a tuple
or a set
and the keyword in
to check if word
equals any of the four names:
>>> word = "John"
>>> word in {"John", "Fred", "Jim", "Michael"}
True
>>> word = "Fred"
>>> word in {"John", "Fred", "Jim", "Michael"}
True
>>>
>>> type({"John", "Fred", "Jim", "Michael"})
<type 'set'>
>>>
Finally, as Daniel pointed out, remember the colon, :
, after function definitions such as def __init__(...)
Upvotes: 2