read files in python 3 - python

I'm learning how to read files and I want to know why this is happening and how to fix it. I made a .txt file just for practicing this and I have it in my documents. When I run the code though it tells me.
Errno2 no such file or directory: jub.txt
I have tried listing it as C:\Users and so on as well. I have watched tons of tutorials. Can some one please explain this to me so I can get it to work.
print ("Opening and closing a file")
text_file = open("jub.txt", "r")
print (text_file('jub.txt'))
text_file.close()

First check that your file exists in current directory, you can add this simple validation.
Secondly use with wrapper, it will close file for you after you exit this block. Thirdly: You read from file using read and readlines methods.
print ("Opening and closing a file")
f_name = "jub.txt"
if not os.path.exists(f_name):
print 'File %s does not exist'%f_name
return
with open(f_name , "r") as text_file:
print (text_file.read())
For your path to be more precise, mayby use full system path, and not relative. Example: '/home/my_user/doc/myfile.txt'

Just to complement the code provided by Beri, I would rather use a try/except statement, and the new-style string formatting:
print("Opening and closing a file")
f_name = 'jub.txt'
try:
with open(f_name, 'r') as text_file:
print(text_file.read())
except FileNotFoundError:
print("File {} does not exist".format(f_name))
By the way I would recommend reading directly from the official Python doc, it's pretty clear and concise:
https://docs.python.org/3.4/tutorial/inputoutput.html#reading-and-writing-files

Related

Good way to determine the correct filename from a small set of possible filenames in Python

I have a python project for a GUI to be used with the slurm queuing manager at our computing cluster. One thing I can do is to print the contents of certain files for a specific job in a text window.
However, the extensions people use for the same type of file will sometimes change. I could program it such that it works for me, but I also want to be able to look up other people's files.
The way I have solved this is the following
extensions = [".ex1", ".ext2", "ext3"]
for ext in extensions:
try:
f = open(jobname+ext), "r")
content = f.read()
f.close()
<doing some stuff with content>
except IOError:
if ext == extensions[-1]:
print("File not found")
return
If the actual extension used is covered by extensions, then my code will find it. I would like to know if more experienced programmers have a better/more elegant/more efficient way of doing it. Luckily the files to be read are very small, so looping over all the possibilities will not take much time. But this particular solution might not be suitable for other cases.
As I understand the Question, you already know the filename and path, and only the extension is unknown.
Use the glob package to find all files with that name like this:
from glob import glob
matches = glob("/path/to/files/knownfilename.*")
if not matches:
print("File not found!")
return
try:
with open(matches[0], "r") as f:
content = f.read()
# do stuff
except IOError:
print("Error reading file {}".format(matches[0]))
In this case you might have to deal with the possibility that
there are multiple files with that name and different extensions
the first file in the matches list is not the kind of file you want (maybe some backup file with .bak extension or whatever), so you might also want to blacklist some extensions
You could use the with statement to open a file and then have it automatically closed. Also, you could omit the mode parameter to open() (which defaults to 'r') and probably add a break after you found a valid extension:
extensions = [".ex1", ".ext2", "ext3"]
for ext in extensions:
try:
with open(jobname+ext)) as f:
content = f.read()
# do some stuff with content
break
except IOError:
if ext == extensions[-1]:
print("File not found")
return
You can use os.listdir('.') to get a list of file names in the current working directory, iterate through the list with a for loop, and slice the file name from the length of jobname and use the in operator to test if it is one of extension names in the extensions list/tuple. break after processing the file when a file is found with the desired name. Use the else block for the for loop to print a File not found message if the loop finishes without breaking:
import os
extensions = '.ext1', '.ext2', '.ext3'
for filename in os.listdir('.'):
if filename.startswith(jobname) and filename[len(jobname):] in extensions:
with open(filename) as f:
content = f.read()
# doing some stuff with content
break
else:
print("File not found")
Even if that works, the logic of comparing the current extension with the end of the list feels weird. In the worst case, if the last extension is accidentally duplicated earlier in the list, this would lead to hard-to-diagnose errors.
Since (presumably) you already return out of the loop as soon as you have found the file, you could just put the "missing-file" behavior after the loop (where it will only be reached if no file was found), and leave the catch-block empty:
extensions = [".ex1", ".ext2", ".ext3"]
for ext in extensions:
try:
with open(jobname+ext), "r") as f:
content = f.read()
<doing some stuff with content>
return
except IOError:
pass
print("File not found")

Opening multiple files in Python before closing previous?

I have a noob python question... so bear with me.
Can I open multiple files before closing the previos.
So... can I run
import os
files=[]
for file in os.listdir(os.curdir):
files.append(open(file,'w'))
Then edit each file as I want and finish with
for file in files:
file.close()
Thanks in advance
Seems legit and works fine.
Doing operations would be hard for you this way. the list "files" doesn't contain the filenames. You would not know which file is what.
It is perfectly fine to open each file using open and later close all of them. However, you will want to make sure all of your files are closed properly.
Normally, you would do this for one file:
with open(filename,'w') as f:
do_something_with_the_file(f)
# the file is closed here, regardless of what happens
# i.e. even in case of an exception
You could do the same with multiple files:
with open(filename1,'w') as f1, open(filename2,'w') as f2:
do_something_with_the_file(f)
# both files are closed here
Now, if you have N files, you could write your own context manager, but that would probably be an overkill. Instead, I would suggest:
open_files = []
try:
for filename in list_of_filenames:
open_files.append(open(filename, 'w'))
# do something with the files here
finally:
for file in open_files:
file.close()
BTW, your own code deltes the contents of all files in the current directory. I am not sure you wanted that:
for file in os.listdir(os.curdir):
files.append(open(file,'w')) # open(file,'w') empties the file!!!
Maybe you wanted open(file, 'r') or open(file, 'a') instead? (see https://docs.python.org/2/library/functions.html#open)
Your solution will certainly work but the recommended way would be to use contextmanager so that the files gets handled seamlessly. For example
for filename in os.listdir(os.curdir):
with open(filename, 'w') as f:
# do some actions on the file
The with statement will take care of closing the file for you.

Python 3.6 - file.write() not actually writing

In case you didn't catch it in the title, this is Python 3.6
I'm running into an issue where I was able to write to a file, and now I cannot. The crazy thing is that this was working fine earlier.
I'm trying to either append my file if it exists, or write to a new file if it doesn't exist.
main_area_text represents the div tag text below
<div id="1131607" align="center"
style="width:970px;padding:0px;margin:0px;overflow:visible;text-
align:center"></div>
and below is my code:
main_area_text = #this is equal to the html text above
#I've verified this with a watch during debugging
#But this doesn't actually matter, because you can put
#anything in here and it still doesn't work
html_file_path = os.getcwd() + "\\data\\myfile.html"
if os.path.isfile(html_file_path):
print("File exists!")
actual_file = open(html_file_path, "a")
actual_file.write(main_area_text)
else:
print("File does not exist!")
actual_file = open(html_file_path, "w")
actual_file.write(main_area_text)
Earlier, in it's working state, I could create/write/append to .html and .txt files.
NOTE: If the file doesn't exist, the program still creates a new file... It's just empty.
I'm somewhat new to the python language, so I realize it's very possible that I could be overlooking something simple. (It's actually why I'm writing this code, to just familiarize myself with python.)
Thanks in advance!
Since you're not closing your file, the data isn't being flushed to disk. Instead try this:
main_area_text = "stuff"
html_file_path = os.getcwd() + "\\data\\myfile.html"
if os.path.isfile(html_file_path):
print("File exists!")
with open(html_file_path, "a") as f:
f.write(main_area_text)
else:
print("File does not exist!")
with open(html_file_path, "w") as f:
f.write(main_area_text)
The python with statement will handle flushing the data to disk and closing the data automatically. It's generally good practice to use with when handling files.

Check to see if file exists is failing

Here is my code:
# header.py
def add_header(filename):
header = '"""\nName of Project"""'
try:
f = open(filename, 'w')
except IOError:
print "Sorry could not open file, please check path"
else:
with f:
f.seek(0,0)
f.write(header)
print "Header added to", filename
if __name__ == "__main__":
filename = raw_input("Please provide path to file: ")
add_header(filename)
When I run this script (by doing python header.py), even when I provide a filename which does not exist it does not return the messages in the function. It returns nothing even when I replace the print statements with return statements. How would I show the messages in the function?
I believe you are always creating the file. Therefore, you won't see a file not there exception. It does not hurt to put a write or file open write under try except, because you might not have privileges to create the file.
I have found with statements like try except and else to test those at the Python command line, which is a very excellent place to work out cockpit error, and I'm very experienced at generating a lot of cockpit error while proving out a concept.
The fact you're using try except is very good. I just have to go review what happens when a logic flow goes through one of them. The command line is a good place to do that.
The correct course of action here is to try and read the file, if it works, read the data, then write to the file with the new data.
Writing to a file will create the file if it doesn't exist, and overwrite existing contents.
I'd also note you are using the with statement in an odd manner, consider:
try:
with open(filename, 'w') as f:
f.seek(0,0)
f.write(header)
print("Header added to", filename)
except IOError:
print("Sorry could not open file, please check path")
This way is more readable.
To see how to do this the best way possible, see user1313312's answer. My method works but isn't the best way, I'll leave it up for my explanation.
Old answer:
Now, to solve your problem, you really want to do something like this:
def add_header(filename):
header = '"""\nName of Project"""'
try:
with open(filename, 'r') as f:
data = f.read()
with open(filename, 'w') as f:
f.write(header+"\n"+data)
print("Header added to"+filename)
except IOError:
print("Sorry could not open file, please check path")
if __name__ == "__main__":
filename = raw_input("Please provide path to file: ")
add_header(filename)
As we only have the choices of writing to a file (overwriting the existing contents) and appending (at the end) we need to construct a way to prepend data. We can do this by reading the contents (which handily checks the file exists at the same time) and then writing the header followed by the contents (here I added a newline for readability).
This is a slightly modified version of Lattywares solution. Since it is not possible to append data to the beginning of a file, the whole content is read and the file is written anew including your header. By opening the file in read/write mode we can do both operations with the same file handler without releasing it. This should provide some protection against race conditions.
try:
with open(filename, 'r+') as f:
data = f.read()
f.seek(0,0)
f.write(header)
f.write(data)
#f.truncate() is not needed here as the file will always grow
print("Header added to", filename)
except IOError:
print("Sorry, could not open file for reading/writing")
this script opens a file in "w" mode (write mode),which means once the file dose not exist,it will be created. So No IOError.

Take user input and put it into a file in Python?

I must have skipped a page or two by accident during my PDF Tutorials on Python commands and arguments, because I somehow cannot find a way to take user input and shove it into a file. Don't tell me to try and find solutions online, because I did. None made sense to me.
EDIT: I am using Python 3.1.2, sorry for forgetting
Solution for Python 3.1 and up:
filename = input("filename: ")
with open(filename, "w") as f:
f.write(input())
This asks the user for a filename and opens it for writing. Then everything until the next return is written into that file. The "with... as" statement closes the file automatically.
Solution for Python 2
Use raw_input() to take user input. Open a file using open() and use write() to write into a file.
something like:
fd = open(filename,"w")
input = raw_input("user input")
fd.write(input)
Try Something Like This.
#Getting Where To Save File
where = raw_input('Where Do You Want To Save Your File? ')
#Getting What To Write To File
text = raw_input('What Do You Want To Write To Your File? ')
#Actually Writing It
saveFile = open(where, 'w')
saveFile.write(text)
saveFile.close()
Try this out as this also places your input lines each on a new line.
filename = "temp.txt"
with open(filename, "w") as f:
while True:
try:
f.write(input())
f.write("\n")
except EOFError:
break

Categories

Resources