I have a problem with a code i'm writing. One of it's parts is responsible for creating a file, and it is also supposed to tell me if it was successful. If not, it should inform me as well, but the problem is - it checks if the file exists before it gets created. I tried to make a break between creation of file and checking if it exists by using time module (specifically time.sleep option, inserted in almost every place possible), but with no results. I also tried to use another way to check if the file exists. It didn't help. Whole thing works fine (excluding this part), because if the file is already there and i tell the program to create it, it tells me that it was successful, so it can read it properly, but it's too fast. I attached part of my code down below. Thank you in advance.
First way i tried, using os module:
path = 'D:\screen'
os.chdir(path)
exists = os.path.isfile('.\screenshot.png')
exists2 = os.path.isfile('.\screenshot2.png')
And here's the execution part:
def printer():
pyautogui.screenshot('D:\SCREEN\screenshot.png')
time.sleep(3)
if exists:
print("Screenshot was created successfully")
else:
print("Screenshot was not created successfully")
def printer2():
pyautogui.screenshot('D:\SCREEN\screenshot2.png')
time.sleep(3)
if exists2:
print ("Screenshot was created successfully")
else:
print ("Screenshot was not created successfully")
Second way i tried, using pathlib:
path = 'D:/screen'
file1 = Path("D:/screen/screenshot.png")
file2 = Path("D:/screen/screenshot2.png")
And the execution part:
def printer():
pyautogui.screenshot('D:/SCREEN/screenshot.png')
time.sleep(3)
if file1.isfile():
print("Screenshot was created successfully")
else:
print("Screenshot was not created successfully")
def printer2():
pyautogui.screenshot('D:/SCREEN/screenshot2.png')
time.sleep(3)
if file2.isfile():
print("Screenshot was created successfully")
else:
print("Screenshot was not created successfully")
Those variables (file1, file2) were assigned before creating the screenshot, hence they dont exist. screenshot actually returns a PIL image object. So you can check if without even using os.
def printscreen():
try:
image = pyautogui.screenshot('D:/SCREEN/screenshot.png')
except Exception as e:
print(f'Exception occured during screenshotring {str(e)}')
If you want to still check with os if they exist, use it after the screenshot.
pyautogui.screenshot('D:/SCREEN/screenshot.png')
assert os.file.exist('D:/SCREEN/screenshot.png')
I have no idea what pyautogui.screenshot() does but here goes:
Assuming that the first half of each attempt is executed before the printer functions are called, you are storing the result of os.path.isfile() before you've created the file you are testing.
You should also pick a case for the folder name, really it should be in a variable so that you are not typing it twice. You should also use os.path.join instead of typing directory separators.
In printer and printer2 of the first half you should be able to change exists/exists2 to a call to os.path.isfile().
In the simple case this should work:
def printer():
pyautogui.screenshot('D:\screen\screenshot.png') #assume this attempts to create a file
if os.path.isfile('.\screenshot.png'):
print("Screenshot was created successfully")
else:
print("Screenshot was not created successfully")
path = 'D:\screen'
os.chdir(path)
printer()
Welcome to SO!
The best to check if the file exists or not is using a try/catch block.The problem in the code is that their is a race condition between the line os.path.isfile('.\screenshot.png') and the if exists part.
You can try to use the following -
try:
fh = open('.\screenshot.png', 'rw'):
# Do something
except FileNotFoundError:
print("File not found")
Thank you for all of your answers. I was able to deal with my problem by using the solution proposed by Zonyl. It looks like the reason standing behind it was trivial(,,Those variables (file1, file2) were assigned before creating the screenshot" ,,Assuming that the first half of each attempt is executed before the printer functions are called, you are storing the result of os.path.isfile() before you've created the file you are testing.") but i'm thankful you helped me anyway. I hope another newbie in the future may find it useful.
Related
HELO
I am new to Python and learning a lot thanks to Stackoverflow, but at the moment I am stuck at this simple task where I was sure I would resolve it myself but spent few hours looking around.
I have Tkinter GUI with a button, where if pressed it will look for such name in specific file path and if it finds "Check For Updates", it will run it else it will do nothing as expected.
import tkinter as tk
import os
root = tk.Tk()
button = tk.Button(root, text="Open", height=1, width=25, borderwidth="2", command=lambda: openupdt())
button.grid()
def openupdt():
os.startfile(r"C://ProgramData//Microsoft//Windows//Start Menu//Programs//Java//Check For Updates")
root.mainloop()
Here I tried to use IF statement but it seems like I am doing something wrong. If no file in such path is found I would like it to print message or do what ever is instructed.
def openupdt():
os.startfile(r"C://ProgramData//Microsoft//Windows//Start Menu//Programs//Java//Check For Updates")
if openupdt == False:
print("No such file")
gives me an error "The system cannot find the file specified:" as if it fully ignores IF statement
Thank you.
If you want to check, if something with certain path exists or not, use os.path.exists that returns true or false. In your case, it might be like
import os
def openupdt():
if os.path.exists("/your/path"):
do_something()
else:
print("No such file or directory")
The main problem in your code is fact that in if statement you compare False with openupdt, but your function name is openupdt. You are actually comparing function to bool value, that's incorrect. Better make use of os.path.exists like I provided above and this will work for you.
You should first check if the file exists and then use the os.startfile.
Try something like:
if os.path.isfile("your_path_to_file"):
os.startfile("your_path_to_file")
else:
print("No such file")
You can also use try...except and handle the error as it appears:
try:
os.startfile("your_path_to_file")
except FileNotFoundError:
print("No such file")
The main thing is that you should be using a try-except for os.startfile(). Additionally your if statement is checking the function instead of a variable which makes the comparison not viable. Plus you are using a raw string literal so you don't need the extra slashes.
def openupdt():
try:
os.startfile(r"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Java\Check For Updates")
except:
print("No such file")
Maybe this is just how Python works but I think I'm missing something, I've looked around and I can't find anything addressing this.
Are text files only created after the process is terminated, or have I made a mistake?
Here's the code I'm using to generate the text file:
user_name_token = open("user_name_token.txt", "w")
If that is just how Python works and .txt files are only generated after the process is terminated, then there's no need to look at the code below. However, if I've made a mistake and that's why the .txt file is only generated after the process is terminated, please do let me know.
I've put what I feel to be the relevant code sequence below.
The following code, if the file exists, converts the text inside to a str value and leads to a greeting where the str value is used but it isn't relevant here. Instead, we'll carry on as if the file does not exist yet; and go to initial_greeting_and_initial_user_name_set() after initialization():
initialization()
def initialization():
global user_name
global initial_login_token
if os.path.isfile("user_name_token.txt") == True:
file = open("user_name_token.txt")
user_name = file.read().replace("\n", " ")
file.close
print(user_name)
time_based_greeting()
else:
initial_greeting_and_initial_user_name_set()
The following code allows the user to create the user name and leads to initial_greeting_and_inital_user_name_set_token_generation() when the button is pressed:
def initial_greeting_and_initial_user_name_set():
global initial_greeting_label
global initial_greeting_space0
global user_name
global initial_greeting_progression_button
initial_greeting_label = Label(root, text="Hello! It's nice to meet you, my name is Eve, what's yours?")
initial_greeting_space0 = Label(root, text=" ")
user_name = Entry(root)
initial_greeting_progression_button = Button(root,\
text="Enter",\
command=initial_greeting_and_initial_user_name_set_token_generation)
initial_greeting_label.pack()
initial_greeting_space0.pack()
user_name.pack()
initial_greeting_progression_button.pack()
The following code uses the user Entry to create a .txt file with the user name inside and loops back to initialization():
def initial_greeting_and_initial_user_name_set_token_generation():
global user_name_token
user_name_token = open("user_name_token.txt", "w")
user_name_token.write(user_name.get())
initialization()
Thank you for any help, especially given it's a long read if I have in-fact made a mistake and that's why the .txt file is only created after the window is closed.
Again, if it's just normal for .txt files to only be generated after the process is terminated and not when the code to create it has been run; then there's no need to take the above code into account.
I'm not sure that's the problem, but in that code:
initialization()
def initialization():
global user_name
global initial_login_token
if os.path.isfile("user_name_token.txt") == True:
file = open("user_name_token.txt")
user_name = file.read().replace("\n", " ")
file.close
print(user_name)
time_based_greeting()
else:
initial_greeting_and_initial_user_name_set()
It seems to me like you forgot to call the file.close method.
Add brackets at the end, so it will look as follows:
file.close().
It is unclear just what your code is doing as you're opening a file for writing and then opening it again for reading before you've closed it for writing. You should close your file for writing before you go on to open it for reading:
def initial_greeting_and_initial_user_name_set_token_generation():
global user_name_token
user_name_token = open("user_name_token.txt", "w")
user_name_token.write(user_name.get())
user_name_token.close()
initialization()
or better yet:
def initial_greeting_and_initial_user_name_set_token_generation():
global user_name_token
with open("user_name_token.txt", "w") as user_name_token:
user_name_token.write(user_name.get())()
initialization()
This latter construct is the preferred way to open a file such that you're sure it gets closed. It will remain open only inside the with block and will then be closed automatically.
Python does not hold back any I/O operations. Like other languages, it performs the operations right away. It may buffer up write operations and write the results in larger blocks, but all writing is completed when you call close() on the file (or when the associated with block is exited, closing the file automatically).
I am fairly new to Python and coming from a JavaScript background where I am familiar with capturing the output of a command (success, error) and chaining that result to indicate my application's next command. Is there an approach to do something similar in Python?
For example, I am using the gspread package to interact with a Google Sheet. I am running the command gc.open(*Name*) that searches for a Google Sheet when provided a string (*Name*), but if this does not return a value or if it returns an error as it currently does, SpreadsheetNotFound:, then I would create a sheet with gc.create(*Name) criteria. I was playing around with try/exception, but felt like I was approaching it incorrectly.
This is what I'm hoping to achieve:
if (API Call Finds the Sheet):
Set regression_output = sheet
else:
Set regression_output = creation of sheet with specified name
Current Code:
open_regression_output_sheet = gc.open(file_name)
for value in open_regression_output_sheet:
try:
regression_output = print("Test")
except:
regression_output = print("Error")
Error:
SpreadsheetNotFound:
How about a logic breakdown as such:
try:
open_regression_output_sheet = gc.open(file_name)
except:
print 'SpreadsheetNotFound raised, creating new spreadsheet'
open_regression_output_sheet = gc.create('A new spreadsheet')
You're on the right track with try/except, but pay careful attention to where the traceback says the exception was raised. I'm guessing it was actually the
open_regression_output_sheet = gc.open(file_name) line that raised the exception.
If that's the case, you need to wrap that line in a try/except like
try:
open_regression_output_sheet = gc.open(file_name)
except SpreadsheetNotFound:
# handle the exception or whatever
else:
for value in open_regression_output_sheet:
...
I currently have a process running that should call a method every 10 seconds. I see that it actually calls the method at that interval, but it seems to not execute something in the code. Weird thing is, is that when I cancel the loop, and start it new it does actually do it the first time. Then when I keep it running it does not do anything.
def main():
try:
while True:
read()
time.sleep(10)
except KeyboardInterrupt:
pass
Above is the loop, and the code here is actually the beginning of the method that is being called, and I found out that it does not actually get results in the results, while the file has changed. In this case it gets data from a .json file
def read():
message = Query()
results = DB.search(message.pushed == False)
Am I overlooking something?
Solved. I had the DB declared globally and that did not go so well. It is being fixed by declaring it just before the statement.
def creabackuno():
startbar()
messagebox.showinfo( "Wait..","I am creating the backup, please wait...")
try:
copytree(path,r"backup\dirbackup1\.minecraft")
messagebox.showinfo( "OK!","Backup (1) created!")
stopbar()
except OSError as exc:
messagebox.showerror( "Nope!","There is already a backup to restore")
stopbar()
I have a problem with a progressbar:
The startbar() start the progressbar on the graphic interface, but when start shutil(copytree(path,r"backup\dirbackup1.minecraft")) the interface freezing and the progressbar stop until it finished.
thanks
i'm using python 3.3
sorry for my poor english
What does the progress bar show? If you are trying to show the percent of the file copied then you have to get the total length/bytes of the file first and then update periodically with the number of bytes copied. That would require using "after" to check the size of the copy-to file every so many milliseconds (I think as I am just guessing here, but search first as there has to be someone who has already done something like this.) This is the first link that I found https://mail.python.org/pipermail/tkinter-discuss/2010-December/002613.html It may be more than you want but should help.
copytree is a synchronous function, so all code execution will stop until it's done. Although tkinter is sad not to be thread-safe I recommend that you put that command in another thread:
from thread import start_new_thread as snt
#from _thread import start_new_thread as snt for python 3
def copy(onError,onEnd):
try: copytree(path,r"backup\dirbackup1\.minecraft")
except:
onError()
return
onEnd()
def onEnd():
messagebox.showinfo( "OK!","Backup (1) created!")
stopbar()
def onError():
messagebox.showerror( "Nope!","There is already a backup to restore")
stopbar()
#then call with
snt(copy,(onError,onEnd))
Execs onError if it fails and onEnd on success.
use self.Frame.update_idletasks() after every self.pgBar.step(x) statement,where 'x' stands for the value by which progressbar's value increases