0

I'm trying to get several functions to run one-after-another, but my code keeps getting stuck in a loop. I've tried implementing multiprocessing, as someone in this thread recommended, but that didn't help.

My function sends a photo to Clarifai to get a list of keywords associated with said photo, after which I tell PyAutoGUI to click somewhere on the screen if said list contains a word that matches a local variable. Here's what one function looks like:

def p1_click(keyword, p1, app, model):
    p1_response = model.predict_by_filename(filename='/Users/raulrodriguez/CODE6_OS/scripts/captcha/saucissons/p1.png')
    p1_concepts = p1_response['outputs'][0]['data']['concepts']
    for concept in p1_concepts:
        clean_list = list(map(lambda s: s.strip(), concept['name']))
        while any(word == inflection.singularize(keyword) for word in concept['name'].split()) == True:
            pyautogui.click(x=490, y=385)
            break

if __name__=='__main__':
    p1 = Process(target=p1_click(keyword, p1, app, model))
    p1.start()

Evidently, I'm trying to do this for several photos — 10 to be exact — by replicating the previous code and replacing p1 for the number of the photo (i.e. p2_click ... p2.start() for a photo named p2), and changing the coordinate values of the pyautogui.click operator. The issue, however, is that, when I put everything together, my curser moves to the pyautogui.click coordinates of the photo for which there is a match and clicks incessantly. I was intending to have a chain reaction, whereby the program clicks on a match photo once, and then moves on to the next. If anyone would be kind enough to chime in, I would truly appreciate the help.

solo
  • 743
  • 2
  • 6
  • 17

1 Answers1

1

The problem you are facing is in this code:

if __name__=='__main__':
    p1 = Process(target=p1_click(keyword, p1, app, model))
    p1.start()

Specifically this line p1 = Process(target=p1_click(keyword, p1, app, model)). Even more specifically target=p1_click(keyword, p1, app, model). When you do this the function p1_click is called as soon as you assign it to target.

This is not how you call a method through multiprocessing module and pass arguments. To pass parameters in multiprocessing module you do this:

p1 = Process(target=p1_click, args=(keyword, p1, app, model))

You can get more info about multiprocessing and how to use it in this SO answer

Amit Tripathi
  • 7,003
  • 6
  • 32
  • 58
  • Thanks for your response! I modified the code you suggested for the other photos and got the following error message: `objc[3396]: +[NSEvent initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.` Do I need to remove `p1.start()`? – solo Dec 16 '17 at 21:25
  • @rrod This seems like a platform issue or something like that. It's not related to Python. A quick [google search](https://www.google.co.in/search?q=objc%5B3396%5D%3A+%2B%5BNSEvent+initialize%5D+may+have+been+in+progress+in+another+thread+when+fork()+was+called&oq=objc%5B3396%5D%3A+%2B%5BNSEvent+initialize%5D+may+have+been+in+progress+in+another+thread+when+fork()+was+called&aqs=chrome..69i57.391j0j7&sourceid=chrome&ie=UTF-8) might be helpful. If this doesn't help you can ask another question. This answer solves your original problem of calling functions parallely. – Amit Tripathi Dec 17 '17 at 14:32