0

I have the following code in which the comments explain the output and desired output. I don't seem to be able to access (or understand the logic) behind how to access different fields in the list.

def viewrecs(username):
    username = (username + ".txt")
    with open(username,"r") as f:
      fReader=csv.reader(f)
      for row in fReader:

         for field in row:

            #print(field) #this prints everything in the file
            #print(row) #this also prints everything in the file
            #print(row[0])  #this also prints everything!!!!!!
            #print(field[0]) #this prints the first ELEMENT in each row, namely the "["
            #How do I access the first field of each column (the genre, like SCI-FI, or Romance)

The file in question is a text file based on the user's username. The contents are:

"['Sci-Fi', 'Blade Runner']"
"['Sci-Fi', 'Star Trek']"
"['Sci-Fi', 'Solaris']"
"['Sci-Fi', 'Cosmos']"
"['Drama', ' The English Patient']"
"['Sci-Fi', 'Out of the Silent Planet']"
"['Drama', ' The Pursuit of Happiness']"
"['Drama', ' The English Patient']"
"['Drama', ' Benhur']"
"['Drama', ' Benhur']"

An answer as to how to access the column field (e.g. Sci-Fi, Drama etc) AND an explanation would be much appreciated.

I want to print the entire first column ....i.e SCI-FI, SCI-FI, SCI-FI, DRAMA etc.....I need these to be read into a list ideally so they can be manipulated inside of the list

Based on one of the answers below, IF the problem is regarding the way the data has been written to the file in the first place, the code /function that writes this data to the file is below:

def viewfilmfunction(x,username):
   #open the file as student file (variable)
   print(username, ":You are about to view Film:", x, "Enter the selection     ID number of the film again to confirm viewing")
   with open("films.txt","r") as filmsfile:
        #prompt the user to enter the ID number they require
        idnumber=input("Enter the ID number you require:")
        #call upon our reader (this allows us to work with our file)
        filmsfileReader=csv.reader(filmsfile)
        #for each row that is read by the Reader    
        for row in filmsfileReader:
            #and for each field in that row (this does it automatically for us)
            for field in row:
                #if the field is equal to the id number that is being searched for
                if field ==idnumber:
                    #print the row fields (genre and title) corresponding to that ID number
                   #create a list which contains the relevant fields in the row.
                  viewedlist=[row[1],row[2]]
                  print("You have viewed:", viewedlist)
   with open("fakeflixfile.txt","r")as membersfile:
      #Open Reader
            membersfileReader=csv.reader(membersfile)
            for row in membersfileReader:              
               for field in row:
                  if field==username:

                     #Open Writer to append to file -this time it looks for the file stored by that username
                     with open("%s.txt" % username,"a") as membersfile:

                        membersfileWriter=csv.writer(membersfile)
                        #Use the writer to append the viewedlist to the appropriate member's user file. 
                        membersfileWriter.writerow([viewedlist])

FAKEFLIXFILE.txt contents

username13022,Username@123,user,name1,2/02/3022,user Road,US455P,Mle,Nothing,[email protected] AugustineSalins1900.txt,Augstine@123,Augustine,Salins,5/02/1900,Hutchins Road,CRBBAAA,Male,Theology,[email protected] JosieBletchway3333,Bb@123,Josie,Bletchway,29/02/3333,Bletch Park,BB44AA,Female,Encryption,[email protected] JoeBloggs.0.0,Joe@Bloggs12,Joe,Bloggs,0.0.0.0,0 Road,00000,Male,Joe Blogs,[email protected]

UPDATE: I have now changed the txt file (based on username) so that the output generated doesn't produce a list:

Drama, The English Patient

Drama, Benhur

Sci-Fi,Cosmos

However, on running:

def viewrecs(username):
   #pass
   username = (username + ".txt")
   with open(username,"r") as f:
          fReader=csv.reader(f)
          for row in fReader:
             print(eval(row)[0])

The error persists:

    print(eval(row)[0])
    TypeError: eval() arg 1 must be a string, bytes or code object
5
  • How does your 'fakeflxfile.txt' look like? Can you paste a few lines of it? Commented Jan 29, 2017 at 19:15
  • pasted FAKEFLIXFILE.txt contents in the edit above Commented Jan 29, 2017 at 19:20
  • because you want to access a csv file and access specific columns you could try using a dataframe with pandas if implementing pandas is an option. That would be pretty straight foward in framing all your contents and accessing rows and columns easily. Commented Jan 29, 2017 at 19:31
  • No, unfortunately, I want to ONLY use straightforward file handling ....txt files and csv reader type alternatives. No JSON or Pandas...... Commented Jan 29, 2017 at 19:37
  • Using eval is very dangerous proposition. Essentially what you doing is running the code that came from the user file as python code inside of your script. Commented Jan 29, 2017 at 19:46

1 Answer 1

1

Because your file is not a valid CSV file. It looks more like a series of JSON objects. Each line in your file is enclosed in double quotes. So CSV reader treats it as a single column. That's why what you get in row[0]

This is caused by the way you are writing your file. The line below tells CSV writer to write one object that is a list containing two values

membersfileWriter.writerow([viewedlist])

what you really want is to tell CSV writer to write multiple objects. Change your line to this, no need to enclose it square brackets:

membersfileWriter.writerow(viewedlist)

Then you can just use this to read your file:

with open(username,"r") as f: fReader=csv.reader(f) for row in fReader: print (row) # print entire row print (row[0]) # print just the first field

Sign up to request clarification or add additional context in comments.

2 Comments

json.loads() wouldn't work; the rows are not valid JSON because they have single quotes instead of double.
I want to be able to solve the problem without using JSON - just plain read and write and straight forward file handling ....

Your Answer

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