Waiting for any of a group of threads to finish Python - python

I have a simple Python/Selenium script that has to wait for 4 checks to happen. Each of these on a separated thread. On the first thread that returns information, the program should continue and the remaining threads killed (if possible).
I have a program that is creating the threads just fine, but I have no idea on how to continue on the first that have executed.
these are my function definitions:
def wait_by(search_type, locator, timeout):
WebDriverWait(driver, timeout).until(EC.presence_of_element_located((search_type, locator)))
def multi_locator_verify_element(xpath_locator, css_locator, name_locator, id_locator, timeout):
element = ""
if xpath_locator != "":
tx = Thread(target=wait_by, args=(By.XPATH, xpath_locator, timeout))
tx.start()
if css_locator != "":
tc = Thread(target=wait_by, args=(By.CSS, css_locator, timeout))
tc.start()
if name_locator != "":
tn = Thread(target=wait_by, args=(By.NAME, name_locator, timeout))
tn.start()
if id_locator != "":
ti = Thread(target=wait_by, args=(By.ID, id_locator, timeout))
ti.start()
The multi_locator_verify_element function should finish after the first thread has been able to retrive the right element.
Could someone please help me with that?
Regards,

Related

Python multiprocessing exit condition error intermittently

Multiprocess job is running the tasks, I want to stop the rest of the parallel or dependent tasks if one of them fails or completes all the tasks.
The problem is with 1st print, where it should check if job failed with non-zero exit code and already not completed then enter the loop and stop the rest of the jobs by breaking the while loop.
however, even the execution completed successfully with exit 0, it enters the loop intermittently, stops the rest of the jobs by breaking the loop.
What is going wrong here.
Failed one
enter image description here
Passed one
enter image description here
Main job triggering multiprocess tasks.
def run_block(index):
print index
# do some execution
def run_blocks(target, dict_blocks):
process = []
for (index, (block_id, depend_on)) in \
enumerate(dict_blocks.items()):
proc = multiprocessing.Process(target=run_block, args=index)
process.append(proc)
proc.start()
check_exit(process)
def check_exit(process):
done = False
process_count = len(process)
count = 0
completed = []
while not done:
for proc in process:
if proc.exitcode != 0 and proc.exitcode != None:
print ('1st', proc, count, done, proc.exitcode)
done = True
break
if proc.exitcode == 0 and proc.pid not in completed:
print ('2nd', proc, count, done, proc.exitcode)
completed.append(proc.pid)
count += 1
if count == process_count:
print ('3rd', proc, count, done)
done = True
break
stop_process_exit(process, count, process_count, done)
def stop_process_exit(
process,
count,
process_count,
done,
):
print (process_count, count, done, process)
for proc in process:
if proc.is_alive():
proc.terminate()
if done == True and count != process_count:
exit(1)
Your processes are running independently, so the variable proc.exitcode must be dynamic. In other words, it might change at any moment because the process has just finished. In this statement:
if proc.exitcode != 0 and proc.exitcode != None
you access the variable twice. Suppose proc.exitcode is None when you begin to execute this line. Python does the first comparison and it evaluates True. Now suppose that the process finishes at that exact moment, and now proc.exitcode becomes zero. Python performs the second comparison, and now that is also True! So your print statement fires, and then you break out of the loop when you really don't want to.
Of course I don't know this is what's happening since I can't run your program, but the evidence points that way.
I would change the loop like this:
for proc in process:
if proc.is_alive():
continue
if proc.exitcode != 0:
print ('1st', proc, count, done, proc.exitcode)
done = True
break
# ... everything else is not changed

selenim web driver python repet code ultimate

how repeat code again again again this every work
I want the code below to always work and it should be repeated, and again this function should be repeated and not removed from the program.
def ref(self):
driver = self.driver
nextB2 = driver.find_element_by_xpath("""//section/span/button/span[#aria-label='Like']""")
nextB2.click()
time.sleep(5)
nextB3 = driver.find_element_by_xpath("""//section/span/button/span[#aria-label='Like']""")
nextB3.click()
time.sleep(6)
nextB4 = driver.find_element_by_xpath("""//section/span/button/span[#aria-label='Like']""")
nextB4.click()
time.sleep(7)
driver.refresh()
time.sleep(5)
driver.switch_to_frame('ref')
driver.refresh('ref')
you can use for loop with range to stop at perticular count like
for i in range(10): #10 times
ref() #function call
if you want it to run for ever
while True: #loop that never stops
ref()
you can use break and continue for conditional breaks
while True:
if foo == foo:
break #break or stop the while oop
elif foo == bar:
continue #skip current iteration and continue execution
else:
ref()

Dynamically changing the message of raw_input

I'm looking to move a motorised slider using a Raspberry Pi. However, while debugging the system I was wondering if it is possible to use:
target = int(raw_input(<message>))
In a way that message could dynamically change before the user inputs a value. For me, it would be great to see the current value that is read from the slider in this <message> for example.
And if that isn't possible, is it possible to have a line printed above or below the raw_input that remains changing while the system waits for the users' input?
You can find that as a non-blocking input.
Here is a solution from stack overflow, which uses threads
I did a little modified solution, it still needs some tweaking, but its more or less what you have to do.
python
import threading
import time
import random
userInput = ""
finished = False
sensorValue = 100
previousValue = 0
def Listener():
global userInput, finished, sensorValue
userInput = raw_input(sensorValue)
if len(userInput) > 0:
print(len(userInput))
finished = True
else:
finished = False
while True:
if sensorValue != previousValue:
print("Received new slider info. SliderValue is {}".format(sensorValue))
previousValue = sensorValue
else:
print("No new info from slider. Sleeping two seconds.")
if not finished:
listener = threading.Thread(target=Listener)
listener.start()
else:
break
if random.randint(0,1) == 1:
sensorValue += 10
time.sleep(2)
See if that answers your question! :)

Threads not exiting and program won't exit

Using the script below, I cannot seem to exit the threads. The script runs smoothly without issues but never exits when done. I can still see the thread alive, I have to use htop to kill them or completely exit the command line.
How can I get this script to exit and the threads to die?
def async_dns():
s = adns.init()
while True:
dname = q.get()
response = s.synchronous(dname,adns.rr.NS)[0]
if response == 0:
dot_net.append("Y")
print(dname + ", is Y")
elif response == 300 or response == 30 or response == 60:
dot_net.append("N")
print(dname + ", is N")
elif q.empty() == True:
q.task_done()
q = queue.Queue()
threads = []
for i in range(20):
t = threading.Thread(target=async_dns)
threads.append(t)
t.start()
for name in names:
q.put_nowait(name)
Remove and return an item from the queue. If optional args block is true and timeout is None (the default), block if necessary until an item is available. If timeout is a positive number, it blocks at most timeout seconds and raises the Empty exception if no item was available within that time. Otherwise (block is false), return an item if one is immediately available, else raise the Empty exception (timeout is ignored in that case).
Remember to check your queue.
See the document of queue.
Your threads are stuck in dname = q.get()
If you reaching empty queue, q.get() will wait forever for value to arrive.
You can replace get with get_nowait() but get ready to catch Queue.Empty execption

Pause and resume a running script in Python 3.42 in Windows

I'm new to Python and have been googling for a couple of days and read all I can find on this forum. Might be that I don't understand it all but I haven't found a solution to my problem yet. Ask for forgiveness already if there's an answer already to my problem, then I haven't understood it.
I want to make a Pause function for my program Tennismatch. The program will when it's being run print the score of a tennis match like this: "15-0, 15-15 etc ongoing till the match ends. It will print the score line by line.
I want the user to be able to pause after x number of balls, games, etc. So I don't know when the user wants to pause and after the user has paused I want the user to be able to resume the tennismatch where it was.
Have seen the time.sleep() but as I have understood it you must know when you want to pause to use this and it also ain't an indefinetie pause like I want. With input() it's the same.
Am going to make a GUI later on when the code is finished. Happy for anything that leads me to solving my problem.
I use Windows and Python 3.42 and run the program in Shell.
A piece of the code (haven't written it all yet, it's more of a general situation when something is being printed line after line for some time and want to be able do pause in the CIL:
#self.__points = [0,0]
def playGame(self):
if self.server == True: #self.server is either True or False when someone calls playGame()
server = self.player_1.get_win_serve() #self.player_1 = an object of a class Player():
else:
server = self.player_2.get_win_serve() #get_win_serve() method returns the probability to win his serv (1-0)
while (0 < self.__points[0] - self.__points[1] >= 2 or 0 < self.__points[1] - self.__points[0] >= 2) and (self.__points[1] >= 4 or self.__points[0] >= 4):
x = random.uniform(0,1)
if x > 0 and x < server:
self.__points[0] += 1
else:
self.__points[1] += 1
# print('The score, by calling a score() function that I haven't written yet')
For dealing with events in main loop you need to make a separated thread which capture input or any other event.
import sys
from sys import stdin
from time import sleep
from threading import Thread
from Queue import Queue, Empty
def do_something():
sleep(1)
print 42
def enqueue_output(queue):
while True:
# reading line from stdin and pushing to shared queue
input = stdin.readline()
print "got input ", input
queue.put(input)
queue = Queue()
t = Thread(target=enqueue_output, args=(queue,))
t.daemon = True
t.start()
pause = False
try:
while True:
try:
command = queue.get_nowait().strip()
print 'got from queue ', command
except Empty:
print "queue is empty"
command = None
if command:
if command == 'p':
pause = True
if command == 'u':
pause = False
if not pause:
print pause
do_something()
except KeyboardInterrupt:
sys.exit(0)
I came up with the following.
while True:
try:
## Keep doing something here
## your regular code
print '.',
except KeyboardInterrupt:
## write or call pause function which could be time.sleep()
print '\nPausing... (Hit ENTER to continue, type quit to exit.)'
try:
response = raw_input()
if response.lower() == 'quit':
break
print 'Quitting...'
except KeyboardInterrupt:
print 'Resuming...'
continue
The Event loop might as well be the code I wrote with.
I don't see any user input so I assume that x emulates it. To pause the game if x < 0.1 and to unpause(/resume) it if x > 0.9, you could:
while your_condition(self.__points):
x = random.random()
if x < 0.1: # pause
self.pause()
elif x > 0.9: # resume
self.resume()
if self.is_paused:
continue # do nothing else only wait for input (`x`)
# assume your_condition() has no side-effects
# here's what the resumed version does:
print("...")
# change self.__points, etc
where pause(), resume(), is_paused() methods could be implemented as:
def __init__(self):
self.is_paused = False
def pause(self):
self.is_paused = True
def resume(self):
self.is_paused = False
as you can see the implementation is very simple.

Categories