Reputation:
Can anyone tell me why this doesn't work (Python 3) and what I need to do to fix it. Code and error message below:
def verifylogin():
fin=open("moosebook.txt","r")
data=fin.readlines()
line=data
allData = []
for ln in line.split(')('):
allData.append( ln.lstrip('(').rstrip(')').replace("'", '').replace(' ', '').split(',') )
for data in allData:
print (data[0]) # print user
print (data[5]) # print profession
output error message:
line 30, in verifylogin
for ln in line.split(')('):
AttributeError: 'list' object has no attribute 'split'
The data in the text file is:
('CoderBlogJ', 'ggs123', 'J', 'Bloggs', 'Male', 'Coder')('DoctorSmitD', 'ith123', 'D', 'Smith', 'Male', 'Doctor')('teacherminaR', 'neb123', 'R', 'minajneb', 'female', 'teacher')('WriterGardK', 'ens123', 'K', 'Gardens', 'Male', 'Writer')('', '123', '', '', '', '')('', '123', '', '', '', '')('', '123', '', '', '', '')
I want data[0] and data[5] etc to print out the relevant field in the list.
Thank you very much for the answer: My final quest however, is to get the username and password to work and because I can't translate it, I can't quite get it to work ....
def verifylogin():
with open("moosebook.txt") as f:
data = literal_eval(f.read().replace(")", "),"))
for user, pw,_,sur,_, job in data:
if user:
print("{} is a {}".format(user, pw))
flag=0
for counter in range(0,len(data)):
if textlogin.get()==data[counter] and textpassword.get()==data[counter+1]:
flag=flag+1
if flag>0:
welcome=Label(myGui,text="Access Granted. Loading Profile ....")
welcome.pack()
else:
denied=Label(myGui,text="Access Denied")
denied.pack()
Upvotes: 1
Views: 67
Reputation: 180391
Your error as stated already is because line is a reference to data which is a list, if each tuple is on a separate line in your file you can use ast.literal_eval to parse the data and just index the tuples to get the dat you want:
from ast import literal_eval
def verifylogin():
with open("test.csv") as f:
for line in f:
print(literal_eval(line))
verifylogin()
Output:
('CoderBlogJ', 'ggs123', 'J', 'Bloggs', 'Male', 'Coder')
('DoctorSmitD', 'ith123', 'D', 'Smith', 'Male', 'Doctor')
('teacherminaR', 'neb123', 'R', 'minajneb', 'female', 'teacher')
('WriterGardK', 'ens123', 'K', 'Gardens', 'Male', 'Writer')
('', '123', '', '', '', '')
('', '123', '', '', '', '')
('', '123', '', '', '', '')
If you have it all in a single line you can str.replace
putting a trailing comma after each )
, that will wrap all the tuples in a tuple so ast can parse the file content correctly:
def verifylogin():
with open("test.csv") as f:
data = literal_eval(f.read().replace(")", "),"))
for t in data:
print(t)
verifylogin()
Output will be the same as previously.
If you are using python3 we can use extended iterable unpacking to get the data we want, ignoring the data with no user with an if check:
from ast import literal_eval
def verifylogin():
with open("test.csv") as f:
data = literal_eval(f.read().replace(")", "),"))
for user, *rest, job in data: # python2 -> for user, _,_,_,_, job in data:
if user:
print("{} is a {}".format(user, job))
Output:
CoderBlogJ is a Coder
DoctorSmitD is a Doctor
teacherminaR is a teacher
WriterGardK is a Writer
You can get whatever info you want, all the data is unpacked in the loop:
def verifylogin():
with open("test.csv") as f:
data = literal_eval(f.read().replace(")", "),"))
for user, pw, _, _ , _, job in data:
if user:
print("Details for user: {}\nPassword: {}\nJob: {}\n".format(user, pw, job))
Output:
Details for user: DoctorSmitD
Password: ith123
Job: Doctor
Details for user: teacherminaR
Password: neb123
Job: teacher
Details for user: WriterGardK
Password: ens123
Job: Writer
Upvotes: 2
Reputation: 1117
With the format of the data you give (one line with multiple tuples), and keeping your code, try the following.
def verifylogin():
fin = open("moosebook.txt", "r")
data = fin.readlines()
allData = []
for line in data:
for ln in line.split(')('):
allData.append(ln.lstrip('(').rstrip(')').replace("'", '').replace(' ', '').split(','))
for data in allData:
print(data[0]) # print user
print(data[5]) # print profession
verifylogin()
Upvotes: 0
Reputation: 5061
file.readlines()
returns a list of lines in.
you did:-
data = fin.readlines()
then data
is a list
not string
line = data
line
is a list
too, and list
don't have split
method.
Try type()
function.
type(data.readlines())
list
Upvotes: 1