Format of if statement to check if a file exists - python

I understand that this question may exist, however I am just trying to figure out my formatting. I am not the best when it comes to formatting things like this and am just doing a bit of guess work that just leads to issues.
I have a custom file type that it must save to, a .gcom and a file name that is declared with the function. Currently the function looks like this:
def cComFile(): # This will NOT write command code (Yet) I want to see if file creation works!
filetype='.gcom'
commands_Directory = 'C:\\Genisis_AI\\Commands\\' # Unused at the moment
file_name = command
if os.path.isfile(("C:\\Genisis_AI\\Commands\\{}").format(file_name).join("{}").format(filetype)):
a = raw_input(('{} already exists! Would you like to overwrite this? [Y/N]: ').format(cComFile.file_name))
string.lower(a)
if a == 'y':
print(("Command: {} , has been rewritten!").format(file_name))
elif a == 'n':
pass
else:
f = open((cComFile.commands_Directory.join(cComFile.file_name.join(cComFile.filetype)),'w+'))
f.write('command was made')
print(('Command made" {}').format(cComFile.command))
I am getting an issue with line 135 which is the following line:
if os.path.isfile(("C:\\Genisis_AI\\Commands\\{}").format(file_name).join("{}").format(filetype)):
The error I am receiving is the following:
Traceback (most recent call last):
File "testing/aaa.py", line 149, in <module>
cComFile('test')
File "testing/aaa.py", line 135, in cComFile
if os.path.isfile(("C:\\Genisis_AI\\Commands\\{}").format(file_name).join("{}").format(filetype)):
KeyError: 'C'
I understand that I am most likely doing this all the wrong way but its a learning experience I suppose. And the chances are that me getting that wrong means that the formatting for the rest of this function are also incorrect as well. Thank you for reading and any help would be nice.
(I understand this is messy and I don't mind it at the moment, I tend to clean up after things work)

You can pass several arguments to format:
if os.path.isfile("C:\\Genisis_AI\\Commands\\{}.{}".format(file_name, filetype)):
Or if you're using Python 3.6 (note the f before the string):
if os.path.isfile(f"C:\\Genisis_AI\\Commands\\{file_name}.{filetype}"):
Or if you prefer the % syntax:
if os.path.isfile("C:\\Genisis_AI\\Commands\\%s.%s" % (file_name, filetype)):

you can pass multiuple values to format function like this, with multiple '{}'.
"C:\\Genisis_AI\\Commands\\{}.{}".format(file_name, filetype)

So basically you jut want to check if a file exists? Why not use a try statement instead of the if?
import errno
try:
with open(filename,'w') as file:
# do stuff with the file
except IOError as e:
# if returned error is [Errno 2] "No such file or directory"
if e.errno == errno.ENOENT:
#do something else
This uses the errno module which makes available error codes from your system. This works for me on windows, may be slightly different on Linux not sure.

Related

How to properly handle errors while working with files?

Program description:
Program creates a .txt file with the given name from the first input. After that it accepts text lines for the file from each input, until the input only consists of a string "end" (this end line should not be included). The program should also handle all possible errors.
My solution:
def writef(f, st):
try:
assert st == "end", "* End of the file (not included)"
assert not(f.endswith(".txt")), "txt only"
except IOError:
print("Unexpected error")
except AssertionError as sterr:
print(sterr)
f.write(st + "\n")
t = input("* Beggining of the file (.txt supported only): ")
f = open(t, "w+")
while True:
exec_st = input("> ")
writef(f, exec_st)
Problems:
My program accepts all sorts of files. I can't figure out how to handle an error which will display that the file should be of .txt extension (properly display an AssertionError message).
After each input line it also outputs the AssertionError message if the string only contains "end": * End of the file (not included). However, when I try typing the string containing only the word "end" it outputs the following error instead of the AssertionError:
Traceback (most recent call last):
File "C:\Users\1\Desktop\IT\pycharm\em_1.py", line 15, in <module>
writef(f, exec_st)
File "C:\Users\1\Desktop\IT\pycharm\em_1.py", line 4, in writef
assert not(f.endswith(".txt")), "txt only"
AttributeError: '_io.TextIOWrapper' object has no attribute 'endswith'
I will appreciate any help, thanks in advance.
The endswith function only works with strings. If you want to check whether the input file is legal, you may do it by checking f.name.
The file extension will not be checked until writef is called, which doesn't make sense because the file name is already given in t = input("* Beggining of the file (.txt supported only): ")
t = input("* Beggining of the file (.txt supported only): ")
f = open(t, "w+")
assert f.name.endswith(".txt"), "txt only"
The code above raises an AssertionError if the file name doesn't end with ".txt".
assert st == "end", "* End of the file (not included)" in the try block raises an exception to output the AssertionError every time the user types in anything other than "end". Instead of checking it in writef, you may want to do it in the while loop.
while True:
exec_st = input("> ")
if exec_st == "end":
f.close()
break
writef(f, exec_st)
The code above breaks the loop as soon as a string containing only "end" is entered, and it will not be written into the output file.
Here is the complete solution:
def writef(f, st):
try:
f.write(st + "\n")
except IOError:
print("Unexpected error")
t = input("* Beggining of the file (.txt supported only): ")
f = open(t, "w+")
assert f.name.endswith(".txt"), "txt only"
while True:
exec_st = input("> ")
if exec_st == "end":
f.close()
break
writef(f, exec_st)
The way assert statements work is that when you say
assert st == "end", "* End of the file (not included)"
You are saying that you assume st is equal to end. If for some reason this isn't true, raise an error. Using != would make the program work as you explained, however, you shouldn't even be using an assert statement here. Assert statements are only meant for sanity checks, and they get stripped out in production. What I mean by that is most companies will run Python in a special optimized mode that skips over assert statements. See this question for more info. Instead raise an error like so:
if st == "end":
raise RuntimeError("* End of the file (not included)")
That'll take care of making sure your error gets raised when it should, but we still need to take care of the '_io.TextIOWrapper' object has no attribute 'endswith' error. You're checking if f does not end with ".txt". f is whatever open() returns, and if you lookup the documentation to see what that function returns, you'll find that it does not return a string, but the endswith function can only operate on strings, hence the error. What you can do instead is pass t to your writef function and check if that ends with "txt", or you can do as PIG208 mentioned and check if f.name ends with ".txt".
Some other things to consider:
You should get in the habit of using more descriptive names. It helps you when you come back to your code later on. I have no idea what t and st stand for, and future you won't know what they stand for either.
You should avoid printing out "Unexpected error" whenever you can in favor of a more specific error message. You'll just annoy the user by not telling them what is going on, you'll annoy yourself when your users complain about this very generic error message.
Your try catch block is around some assert statements that aren't doing any IO work, but your catching an IO error anyways. This isn't necessary. If you get an IO error, it's going to come from f.write or open or f.close.
In order to check the file name, i would recommend you use regex, i'd recommend reading up on it because it makes no sense until you do.
for the "end" case, i believe you want to have f.close() rather than f.close
if you don't want to use regex, you can check if the filename string contains ".txt", which will fix the majority of cases.

Why is the raw file path not working in python?

I have looked and tried different methods posted online but I cant get this to work.
This is my file path:
file_path = '\\something.com\1400_somethingelse\1400_somethingyes\1400_Design\1500_sketch\ShotCam'
This file path is going to change multiple times so I need this to become a variable.
I have tried using the following in order to convert it into a raw file as another variable:
the r before to get the raw file path and that works but what happens if this file path is going to be change? Naturally I would need a variable
I have used the repr(file_path) and that works in some cases but when I try to use the os.listdir it doesnt!
I have tried the r'%s' %file_path as well but nothing
Im sure its something very simple so please let me know if someone has an answer for this!
Thank you!
**UPDATE
This is the code Im having problems with:
variable = '\\something.com\1400_somethingelse\1400_somethingyes\1400_Design\1500_sketch\ShotCam'
#Result:\something.com`0_somethingelse`0_somethingyes`0_Designh0_sketch\ShotCam
raw_path= repr(variable)
#Result:'\\something.com\x0somethingelse\x0somethingyes\x0Designh\x00_sketch\\ShotCam'
list_dir = os.listdir(raw_path)
print list_dir
#Result: # Error: WindowsError: file <maya console> line 8: 3 #
To make it a raw path I know I have to do:
variable = r'\\something.com\1400_somethingelse\1400_somethingyes\1400_Design\1500_sketch\ShotCam'
But I want this to become a variable so I can change it multiple times.
You can verify that your string is not a valid path by just printing it.
>>> '\\something.com\1400_somethingelse\1400_somethingyes\1400_Design\1500_sketch\ShotCam'
'\\something.com`0_somethingelse`0_somethingyes`0_Designh0_sketch\\ShotCam'
>>> r'\\something.com\1400_somethingelse\1400_somethingyes\1400_Design\1500_sketch\ShotCam'
'\\\\something.com\\1400_somethingelse\\1400_somethingyes\\1400_Design\\1500_sketch\\ShotCam'
use r to escape those \.

Python - Open file in notepad that is contained in a variable

I couldn't find this anywhere, so sorry if I missed it. It seems like it should be simple but somehow isn't. I have a simple program that opens a log (log1.lg let's say) and strips any lines that don't contain keywords. It then tosses them into a 2nd file that is renamed to Log1.lg.clean.
The way I've implemented this is by using os.rename so the code looks like this:
#define source and key words
source_log = 'Log1.lg'
bad_words = ['word', 'bad']
#clean up the log
with open(source_log) as orig_log, open('cleanlog.lg', 'w') as cleanlog:
for line in orig_log:
if not any9bad_word in line for bad_word in bad_words):
cleanlog.write(line)
#rename file and open in Notepad
rename = orig_log + '.clean'
new_log = os.rename("cleanlog.lg", rename)
prog = "notepad.exe"
subprocess.Popen(prog, new_log)
Error I'm getting is this:
File "C:\Users\me\Downloads\PythonStuff\stripMmax.py", line 23, in cleanLog
subprocess.Popen(prog, new_log)
File "C:\Python27\lib\subprocess.py", line 339, in __init__
raise TypeError("bufsize must be an integer")
TypeError: bufsize must be an integer
I'm using Python 2.7 if that's relevant. I don't get why this isn't working or why it's requiring a bufsize. I've seen other examples where this works this way so I'm thinking maybe this command doesn't work in 2.7 the way I'm typing it?
The documentation shows how to use this properly using the actual file name in quotes, but as you can see, mine here is contained in a variable which seems to cause issues. Thanks in advance!
See the Popen constructor here: subprocess.Popen. The second argument to Popen is bufsize. That explains your error. Also note that os.rename does not return anything so new_log will be None. Use your rename variable instead. Your call should look like this:
subprocess.Popen([prog, rename])
You likely also want to wait on the created Popen object:
proc = subprocess.Popen([prog, rename])
proc.wait()
Or something like that.

eval lines from a file

I am creating a program that stores options in a txt file, and I tried a few different lines but so far I think an eval is the best one.
I got this info in the file:
colordefondo = "#abcdef"
and I got this eval in the program:
for line in open("filename.txt", "r"):
eval(line)
However, when I try the code it gives me this error:
Traceback (most recent call last):
File "D:\project-sae\Sae.py", line 25, in <module>
eval(line)
File "<string>", line 1
colordefondo = "#abcdef"
^
SyntaxError: invalid syntax
My question is Why? And if anyone knows a better way to load and store the value of several options from a txt file it would be great. Nevertheless my question is about why that eval is failing, my knowledge about how eval works seems wrong and I don't know why, used it several times before, just never from a file.
As the documentation says, 'eval' evaluates an expression. Not a statement. Assignments are statements.
You could use the exec statement. But if you want to exec all of the lines of a file, that's exactly what execfile does. (I'm assuming Python 2.x here; things are a little different in 3.x, but the idea is similar.)
However, this is a bad idea to do in the first place. A better way to load and store the value of several options from a txt file is to use anything other than Python source as your format. JSON, .ini files, .rc files, etc. Python comes with code built-in to handle a variety of such formats. See File Formats and Internet Data Handling for a list of the relevant modules, read through them, and pick the one you want.

I don't even know what infile > outfile means. How am I supposed to use it?

I don't know how to use Python, and I'm trying to use a script on a document. I have no idea how to tell it do this!
If I just run the script, this is the message I get:
Use: C:\Python27\hun2html.py infile > outfile
Traceback (most recent call last):
File "C:\Python27\hun2html.py", line 75, in <module>
sys.exit(1)
SystemExit: 1
I'm not sure what info is relevant to anyone who knows about this stuff, but this is the most relevant part of the code, I believe:
if __name__ == '__main__':
import sys
if not sys.argv[1:]:
print "Use: %s infile > outfile" % sys.argv[0]
sys.exit(1)
contents = open(sys.argv[1]).read()
print hun2html(contents)
It's supposed to change the formatting in a document. If anyone can make sense of this stupid question, I would really appreciate some help!
It means that you should write the path to the file you want to use for input where infile is and the path to the file you want to store the output where outfile is. For example,
C:\Python27\hun2html.py C:\input.txt > C:\output.txt
Note that the input file is being passed as a parameter (accessed in the code by sys.argv[1] ) and the output is being piped, meaning that the Python prints it to standard output, but because you put the > character it will be redirected to the file you indicate. If you left off the > outfile you would see the output displayed on your terminal.
You give it the input file as the first parameter and redirect the standard output to the file where you want to write the result. For example:
C:\Python27\hun2html.py myfile.hun >myfile.html
The > symbols tells it that whatever gets printed to the standard output will get written to a file, instead of the console. There is also < which will read a file to the standard input.
Suppose you have a document named input.doc. If you run hun2html.py input.doc it will display the output to that terminal.
However, since you want to have the output in another file you'll have to redirect the output to a file. That's where > outfile comes into play. If you want to save the output in output.html, you'll have to do this:
hun2html.py input.doc > output.html
Hope it helps.

Categories