Close File Error when pulling data into a dictionary - python-3.x

I am trying to pull the data in the csv file below into a dictionary, but my code returns an operation on closed file error.
LotrGrade = {}
with open('grade_list_large.csv', 'r') as FOpen:
line = FOpen.readline()
LotrGrade = {}
for line in FOpen:
grades = []
line = line.rstrip()
Name = line.split(',')
NameKey = Name[0]
GradeValu = list(Name[1])
while True:
if NameKey in LotrGrade.keys()== True:
LotrGrade.setdefault(NameKey).append(GradeValu)
else:
LotrGrade[NameKey] = GradeValu
else:
False
print(LotrGrade)

This is happening because when you use the with keyword to open a file it will automatically close the file at the end of the with block.
So the error is happening at for line in FOpen: because FOpen has been closed.
Two approaches to fix this, either move all the logic into the with statement (this would keep the file open while the script runs), or parse the data out of the file and into a list before the file is closed (open the file to read data then close it). I'd prefer the latter, but it's up to you. Here's an example of the second approach.
data = []
open('grade_list_large.csv', 'r') as FOpen:
for line in FOpen:
data.append(line)
LotrGrade = {}
for d in data:
# do some work

Issue 1
with open('grade_list_large.csv', 'r') as FOpen:
line = FOpen.readline()
LotrGrade = {}
At this point, you close the file FOpen1 after the indented block. If you check the Python docs,
It is good practice to use the with keyword when dealing with file
objects. This has the advantage that the file is properly closed after
its suite finishes, even if an exception is raised on the way
So you can't access FOpen1 in this line
for line in FOpen
to read the lines in the file because you've already closed it.
Issue 2
The following statements don't make any sense
with open('grade_list_large.csv', 'r') as FOpen:
line = FOpen.readline()
LotrGrade = {}
Essentially, you open a file, read one line from it to line and closes it. As of now, you have just read the very first line from the file.
If you modify these statements to
with open('grade_list_large.csv', 'r') as FOpen:
lines = FOpen.readlines()
LotrGrade = {}
You can later on loop through lines as
for line in lines:
# do something

Related

Python: Reading line with 'readline()' function and appending to a list

My code:
In my file i have these numbers in a list
charge_account = ['4654145', '9658115', '5658845', '5658045', '6181531', '2134874', '5964554']
I am reading the file with a function, appending it to a list and then returning the list:
import os
os.system('cls')
def fileReader():
contentList = []
with open('charge_accounts.txt','r') as f:
line = f.readline().rstrip('\n')
while line !="":
line = f.readline().rstrip(' \n')
contentList.append(line)
# print(contentList)
# print(len(contentList))
#contentList = contentList[:-1]
print(contentList)
return contentList
Now my question is, when i read all the file content and append them to my list, i am getting an extra blank string at the end of the list.
output:
['4654145', '9658115', '5658845', '5658045', '6181531', '2134874', '5964554', '']
Now i have solved it by using slicing (as i commented them out) but i still have not figured out why i am getting the ' ' in the end of the list. i tried filtering it out but noting happens. i have checked if it there is an extra line in the end of the file but what am i doing wrong ?
There are a couple of things. You are reading the file line by line in the while loop. This means that after the last line is read, the while condition is still true so you read an extra line (which is empty) but still added to your list.
But you don't need a while loop: use lines = f.readlines(). It will read the whole file in a list, and you almost have the list you are aiming for. Almost, because you need to strip each element:
def fileReader():
with open('charge_accounts.txt','r') as f:
lines = f.readlines()
return [line.strip() for line in lines]
print(fileReader())
while line !="":
contentList.append(line)
line = f.readline().rstrip(' \n')
print(contentList)
I realized i had to append the while loop primer into the list which i read before the loop started. content.append(line) had to be the first statement in the while loop. This solves the blank entry in the end of list, which in hindsight i realize means that i skipped the first readline value.

How to edit a line in a notepad file using python

I am trying to edit a specific line of a notepad file using Python 3. I can read from any part of the file and write to the end of it, however whenever I have tried editing a specific line, I am given the error message 'TypeError: 'int' object is not subscriptable'. Does anybody know how I could fix this?
#(This was my first attempt)
f = open('NotepadTester.txt', 'w')
Edit = input('Enter corrected data')
Line = int(input('Which line do you want to edit?'))
f.write(Edit)[Line-1]
f.close()
main()
#(This was my second attempt)
f = open('NotepadTester.txt', 'w')
Line = int(input('Which line do you want to edit?'))
Edit = input('Enter corrected data')
f[Line-1] = (Edit)
main()
you can't directly 'edit' a line in a text file as far as I know. what you could do is read the source file src to a variable data line-by-line, edit the respective line and write the edited variable to another file (or overwrite the input file) dst.
EX:
# load information
with open(src, 'r') as fobj:
data = fobj.readlines() # list with one element for each text file line
# replace line with some new info at index ix
data[ix] = 'some new info\n'
# write updated information
with open(dst, 'w') as fobj:
fobj.writelines(data)
...or nice and short (thanks to Aivar Paalberg for the suggestion), overwriting the input file (using open with r+):
with open(src, 'r+') as fobj:
data = fobj.readlines()
data[ix] = 'some new info\n'
fobj.seek(0) # reset file pointer...
fobj.writelines(data)
You should probably load all the lines into memory first, modify it from there, and then write the whole thing to a file.
f = open('NotepadTester.txt', 'r')
lines = f.readlines()
f.close()
Which_Line = int(input('Which line do you want to edit? '))
Edit = input('Enter corrected data: ')
f = open("NotepadTester.txt",'w')
for i,line in enumerate(lines):
if i == Which_Line:
f.writelines(str(Edit)+"\n")
else:
f.writelines(line)
f.close()

How do I copy part of a file to a new file?

In Python I'd like to open a text file as file, and copy only part of the file to a new file. For example, I want to copy only part of the file, say between the line EXAMPLE\n and line END\n. So I want to delete everything before line EXAMPLE\n and everything after line END\n. How can I do that?
I can read the file using the following code, but how do I delete the
with open(r'filepath\myfile.txt', 'r') as f:
file = f.readlines()
<delete unwanted lines in file>
with open(r'filepath\newfile.txt', 'r') as f:
f.writelines(file)
Create a new array and only add the lines you want to that array:
new_lines = []
found_example=False
found_end=False
for line in file:
if line == "EXAMPLE\n": found_example=True
if line == "END\n": found_end=True
if found_example != found_end: new_lines.append(line)
file = new_lines
Now just write file to your file and you are done. Note that in your example you didn't open the file in write mode, so it would look more like this:
with open(r'filepath\newfile.txt', 'w+') as f:
f.writelines(file)
Read each line and notice whether it contains EXAMPLE or END. In the former case, set a flag to start outputting lines; in the latter, set the same flag to stop.
process = False
with open('myfile.txt') as f, open('newfile.txt', 'w') as g:
for line in f:
if line == 'EXAMPLE\n':
process = True
elif line == 'END\n':
process = False
else:
pass
if process:
line = line.strip()
print (line, file=g)

How can I start reading text at a specific line and stop and specific line

Long time listener first time caller, I'm quite new to this so please be kind.
I have a large text document and I would like to strip out the headers and footers. I would like to trigger the start and stop reading lines with specific strings in the text.
filename ='Bigtextdoc.txt'
startlookup = 'Foo'
endlookup = 'Bar'
with open(filename, 'r') as infile:
for startnum, line in enumerate(infile, 1):
if startlookup in line:
data = infile.readlines()
for endnum, line in enumerate(infile, 1):
if endlookup in line:
break
print(data)
like this I can read the lines after the header contain 'Foo' and If I move the data = line after the if endlookup line it will only read the line in the footer starting at 'Bar'
I don't know how to start at Foo and stop at Bar?
For readability I'll extract the logic in a function like:
def lookup_between_tags(lines, starttag, endtag):
should_yield = False
for line in lines:
if starttag in line:
should_yield = True
elif endtag in line:
should_yield = False
if should_yield:
yield line
Using the fact that an opened file is iterable, it can be used like:
with open('Bigtextdoc.txt') as bigtextdoc:
for line in lookup_between_tags(bigtextdoc, 'Foo', 'Bar'):
print(line)

python3 opening files and reading lines

Can you explain what is going on in this code? I don't seem to understand
how you can open the file and read it line by line instead of all of the sentences at the same time in a for loop. Thanks
Let's say I have these sentences in a document file:
cat:dog:mice
cat1:dog1:mice1
cat2:dog2:mice2
cat3:dog3:mice3
Here is the code:
from sys import argv
filename = input("Please enter the name of a file: ")
f = open(filename,'r')
d1ct = dict()
print("Number of times each animal visited each station:")
print("Animal Id Station 1 Station 2")
for line in f:
if '\n' == line[-1]:
line = line[:-1]
(AnimalId, Timestamp, StationId,) = line.split(':')
key = (AnimalId,StationId,)
if key not in d1ct:
d1ct[key] = 0
d1ct[key] += 1
The magic is at:
for line in f:
if '\n' == line[-1]:
line = line[:-1]
Python file objects are special in that they can be iterated over in a for loop. On each iteration, it retrieves the next line of the file. Because it includes the last character in the line, which could be a newline, it's often useful to check and remove the last character.
As Moshe wrote, open file objects can be iterated. Only, they are not of the file type in Python 3.x (as they were in Python 2.x). If the file object is opened in text mode, then the unit of iteration is one text line including the \n.
You can use line = line.rstrip() to remove the \n plus the trailing withespaces.
If you want to read the content of the file at once (into a multiline string), you can use content = f.read().
There is a minor bug in the code. The open file should always be closed. I means to use f.close() after the for loop. Or you can wrap the open to the newer with construct that will close the file for you -- I suggest to get used to the later approach.

Resources