user5272899
user5272899

Reputation:

Converting text file to list and getting at it using indexes:

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

Answers (3)

Padraic Cunningham
Padraic Cunningham

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

Aris F.
Aris F.

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

Vishnu Upadhyay
Vishnu Upadhyay

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

Related Questions