Coditioning in python loops - python

import time
import pyautogui
location = pyautogui.locateOnScreen('ok.png')
pyautogui.click(location)
HOW DO I WRITE THE FOLLOWING STATEMENT AS CODE?
If image is no found on screen, keep running location until the image is found.
otherwise the code is terminating immediately.
I tried :
While location == None : #Or location == False
pyautogui.click(location)

Try using while like this:
while location is not None:
pyautogui.click(location)

According to the Pyautogui documentation:
If the image can’t be found on the screen, locateOnScreen() raises ImageNotFoundException
This means that you have to handle the error message in order to keep the program running in case the image is not there.
Try using exception handling:
import pyautogui
while True:
# Try to do this
try:
location = pyautogui.locateOnScreen('ok.png')
# Location found with no errors: break the while loop and proceed
break
# If an error has occurred (image not found), keep waiting
except:
pass
pyautogui.click(location)
NOTE: This generates an infinite loop until the image is found on screen. To break this loop and stop the script execution use CTRL+C on the Shell.
In alternative you may set a maximum time waiting for the image:
import time
import pyautogui
max_wait = 30 # Seconds
end = time.time() + max_wait
while time.time() <= end:
# Try to do this
try:
location = pyautogui.locateOnScreen('ok.png')
# Location found with no errors: break the while loop and proceed
break
# If an error has occurred (image not found), keep waiting
except:
pass
pyautogui.click(location)

Related

How to reexecute if an error occurs in python?

I'm working with Twint(a Twitter scraper) but somehow there is a problem that I can't fix. I wonder if there is a way that when an error occurs, wait 1 min and re-execute this?
My code is like this:
import twint
geos = ["40.74566208501717, -73.99137569478954", "35.68802408270403, 139.76489869554837", "31.22521968438549, 121.51655148017774"]
for geo in geos:
print(str(geo)+','+'10km')
c = twint.Config()
c.Limit = 20
c.Geo = str(geo)+','+'10km'
twint.run.Search(c)
Sometimes,twint.run.Search(c) can't function correctly.So, once there is an error, is there a way to only execute this loop again but not re-executing the whole loop?
Would anyone help me? Any idea would be really helpful. Thank you much!
If you want to simply pretend the error didn't happen, you could do:
try:
twint.run.Search(c)
except WhateverExceptionType:
pass
(replace WhateverExceptionType with the actual type of error you're seeing)
If when there's an error you wanted to have the whole program wait for a minute before continuing the loop, put that in the except:
import time
...
try:
twint.run.Search(c)
except WhateverExceptionType:
time.sleep(60)
If you want it to re-execute that specific search after waiting (rather than continuing with the next loop iteration), put that in the except. Note that if code within an except raises, then it will raise out of the except and stop your program.
try:
twint.run.Search(c)
except WhateverExceptionType:
time.sleep(60)
twint.run.Search(c)
You could do something like this to try the search again after 60 sec and with say maximum 10 retries:
import time
for geo in geos:
print(str(geo)+','+'10km')
c = twint.Config()
c.Limit = 20
c.Geo = str(geo)+','+'10km'
success=False
retries = 0
while not success and retries <= 10:
try:
twint.run.Search(c)
success=True
except twint.token.RefreshTokenException:
time.sleep(60)
retries += 1
except: # <- catches all other exceptions
retries = 11 # <- e.g. stop trying if another exception was raised

Python Selenium: Quitting a browser instance outside of original function

I started learning python + selenium a few days ago, and am struggling to quit the browser outside of my bbdc_check function. My goal is whenever I interrupt bbdc_check or it encounters an error, I would like to quit the existing browser to start from scratch.
I keep encountering errors with quitting the browser. The error message for driver.quit() is "TypeError: quit() missing 1 required positional argument: 'self'".
I have a nagging suspicion that I'm supposed to use a class here, which I tried loosely off this solution, but still could not get it to work. Any ideas are appreciated, thank you.
FYI, date_a and date_b are not defined here because I deleted a bunch of code redundant to this issue. Assume that line of code works.
import selenium
from selenium import webdriver
import time
import sys
breakloop = 0
def bbdc_check():
global breakloop
driver = webdriver.Chrome(r'C:\<some dir>\chromedriver.exe')
driver.get('<a website>')
# A bunch of code here to compare 2 different dates
if (date_a < date_b):
breakloop = 1
else:
driver.quit()
time.sleep(600)
# The main while-loop to run the programme
while breakloop == 0:
try:
bbdc_check()
# If I manually interrupt, kill the programme
except KeyboardInterrupt:
driver = webdriver.Chrome
driver.quit()
sys.exit()
# If programme encounters error, try again from scratch
except:
driver = webdriver.Chrome
driver.quit()
time.sleep(30)
Seems you are creating new object of driver in each blocks as well as your function bbdc_check(). Create a single driver instance and use the same.

Checking for keyboard inputs not Working. Help Please

I am trying this code provided and accepted here: https://stackoverflow.com/a/55369170/14307622
but I am getting this error. Any ideas why ? I am new here so if I am breaking some rules for this question, then please let me know but if possible, please suggest some solutions to the problem first.
import keyboard
import time
listedSongs = []
currentSong = "idk"
exit = False # make a loop control variable
def alt_k():
i = 1
paused = False
def alt_q():
global exit
exit = True
def alt_s():
if currentSong not in listedSongs:
listedSongs.append(currentSong)
print(listedSongs)
# assign hooks to the keyboard
keyboard.on_press_key("alt+k", alt_k) # on press alt+k, execute alt_k()
keyboard.on_press_key("alt+q", alt_q)
keyboard.on_press_key("alt+s", alt_s)
# main loop
while not exit:
keyboard.wait() # "block" for input (essentially, do nothing until a key is pressed and yield CPU resources to anything else that wants them)
The error I am getting is this:
Traceback (most recent call last):
File "D:\AJ\Coding\test.py", line 26, in <module>
keyboard.on_press_key("alt+k", alt_k) # on press alt+k, execute alt_k()
File "C:\Users\AJ\AppData\Local\Programs\Python\Python39\lib\site-packages\keyboard\__init__.py", line 510, in on_press_key
return hook_key(key, lambda e: e.event_type == KEY_UP or callback(e), suppress=suppress)
File "C:\Users\AJ\AppData\Local\Programs\Python\Python39\lib\site-packages\keyboard\__init__.py", line 493, in hook_key
scan_codes = key_to_scan_codes(key)
File "C:\Users\AJ\AppData\Local\Programs\Python\Python39\lib\site-packages\keyboard\__init__.py", line 324, in key_to_scan_codes
raise ValueError('Key {} is not mapped to any known key.'.format(repr(key)), e)
ValueError: ("Key 'alt+k' is not mapped to any known key.", ValueError("Key name 'alt+k' is not mapped to any known key."))
It seems on_press_key() works only with single key like q but not with combination alt+q. Or maybe it is problem only on some systems. At least it doesn't work on my Linux.
Or maybe they change code in module. Answer in Checking for keyboard inputs uses too much cpu usage, Is there something wrong with my code? is 2 years old.
You can use add_hotkey() and it doesn't need wait()
import keyboard
import time
listedSongs = []
currentSong = "idk"
exit = False # make a loop control variable
def alt_k():
print('pressed: alt+k')
i = 1
paused = False
def alt_q():
global exit # need it to assign `True` to global/external variable instead of creating local variable
print('pressed: alt+q')
exit = True
def alt_s():
print('pressed: alt+s')
if currentSong not in listedSongs:
listedSongs.append(currentSong)
print(listedSongs)
keyboard.add_hotkey('alt+k', alt_k)
keyboard.add_hotkey('alt+q', alt_q)
keyboard.add_hotkey('alt+s', alt_s)
# main loop
while not exit:
time.sleep(1)
See examples in documentation: Example
Eventually you may use hotkye = read_hotkey(...) with if/else to execute correct function.
I'm not sure but sometimes it works for me also with hotkey = keyboard.wait(suppress=False) but sometimes it doesn't work.
while not exit:
hotkey = keyboard.read_hotkey(suppress=False)
#hotkey = keyboard.wait(suppress=False)
print('hotkey:', hotkey)
if hotkey == 'alt+k':
alt_k()
elif hotkey == 'alt+q':
alt_q()
This is how I solved my issue.
I ditched the keyboard module since it was not working the way I wanted it to and then I used the Python Global-Hotkeys Module. The code was pretty much the same but now everything just clicked in place.
Hope this helps someone in the future.

Python exits at random times without throwing exception when running OpenCV

First time asking, I havent found any answers to this after some days of looking. Also im absolutely not a programming pro so I might have missed something obvious.
I am running a code that goes through a large library of images (some 2M) and extracts information from them. The code runs fine for several iterations (20-10000ish) but then the program just stops without any errors reported.
The main code exits (terminates?) most of the time at an OpenCV edge detection or houghlines, but not all the time. about 10% of the time it is at some other point in the code.
Using:
OpenCV 4.1.1
Python 3.7.1
Windows 10
Image at: https://www.dropbox.com/s/5lfzkw6sqmu73eb/Image_00_00_00_00.bmp?dl=0
I have tried to get an exception from the Opencv code in some ways, but nothing pops up. The latest attempt is in the code below.
I have tried to use the trace and log modules but I cant really get them to do anything useful.
import numpy as np
import cv2
import traceback
import sys
def cropping_points2(img):
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # Gray image needed for edge detection
try:
edges = cv2.Canny(gray,20,70,apertureSize = 3)
except Exception as e:
print(traceback.format_exc())
print(sys.exc_info())
print(e, 'there was actually an exception!')
exit()
lines = []
try:
lines = cv2.HoughLines(edges,3,np.pi/180,65, 50, 10, min_theta = 1.4, max_theta = 1.75) # analyse image to find lines - thetha setting looks for horizontal
except Exception as e:
print(traceback.format_exc())
print(sys.exc_info())
print(e, 'there was actually an exception!')
exit()
if lines is None: # All black images return a NoneType image
print('no lines!') # Capture NoneType without crashiing
rect = []
has_lines = False
return rect , has_lines
has_lines = True
return lines[0][0], has_lines
if __name__ == "__main__":
img= cv2.imread('Image_00_00_00_00.bmp')
for index in range(10000):
rect, has_lines = cropping_points2(img)
print(rect)
print(index)
I expect the program to give me a hint of why it stops running =|

Python failure file handling freeze

I am using a python script to transfer the contents of three files to a different three files. The original files are data from three thermometers I have connected to an RPI running raspian. All the script is supposed to do is take the contents of the files and move them so that I can have another program (ComScript) read and parse them.
My problem is that if one or more of the thermometers is disconnected before the script starts, it freezes. It doesn't freeze if I disconnect a thermometer while the script is running.
Here is the code
import time
a = 1
while a == 1:
try:
tfile = open("/sys/bus/w1/devices/28-000004d2ca5e/w1_slave")
text = tfile.read()
tfile.close()
temperature = text
tfile2 = open("/sys/bus/w1/devices/28-000004d2fb20/w1_slave")
text2 = tfile2.read()
tfile2.close()
temperature2 = text2
tfile3 = open("/sys/bus/w1/devices/28-000004d30568/w1_slave")
text3 = tfile3.read()
tfile3.close()
temperature3 = text3
textfile = open("/home/pi/ComScriptPi/profiles/Temperature_parse/w1_slave1", "w ")
textfile2 = open("/home/pi/ComScriptPi/profiles/Temperature_parse/w1_slave2", "w ")
textfile3 = open("/home/pi/ComScriptPi/profiles/Temperature_parse/w1_slave3", "w ")
temperature = str(temperature)
temperature2 = str(temperature2)
temperature3 = str(temperature3)
textfile.write(temperature)
textfile2.write(temperature2)
textfile3.write(temperature3)
textfile.close()
textfile2.close()
textfile3.close()
print temperature
print temperature2
print temperature3
time.sleep(3)
except:
pass
I added the exception pass because I need it to keep running even if it gets bad values. WHen one of the thermometers is disconnected the file python is trying to read is blank, but still there.
Remove the blanket except.
Your script is not freezing, but any error you get is being ignored in an endless loop. Because you use a blanket except: you catch all exceptions, including the keyboard interrupt exception KeyboardInterrupt.
At the very least log the exception, and catch only Exception:
except Exception:
import logging
logging.exception('Oops: error occurred')
KeyboardInterrupt is a subclass of BaseException, not Exception and won't be caught by this except handler.
Take a look at the shutil module for copying files, you doing way too much work:
import time
import shutil
import os.path
paths = ('28-000004d2ca5e', '28-000004d2fb20', '28-000004d30568')
while True:
for i, name in enumerate(paths, 1):
src = os.path.join('/sys/bus/w1/devices', name, 'w1_slave')
dst = '/home/pi/ComScriptPi/profiles/Temperature_parse/w1_slave{}'.format(i)
try:
shutil.copyfile(src, dst)
except EnvironmentError:
import logging
logging.exception('Oops: error occurred')
time.sleep(3)
Handling files should only ever raise EnvironmentError or it's subclasses, there is no need to catch everything here.
The open of the unplugged device is most likely blocking because the device driver won't open if the device is not present.
You'll need to use os.open which is the equivalent of the Unix system call "open" and specify the flag O_NONBLOCK and check the return code. You can then use os.fdopen to turn the return value of os.open into a normal Python file object.

Categories

Resources