2016-07-18 7 views
0

Ich habe ein funktionierendes Stück Code, der meinen Zwecken entspricht, aber ich war mir nicht sicher, ob es einen besseren Weg gab, das Ende zu erfüllen, nach dem ich suche. Hier ist mein Code:Python 3 bestimmen, welcher Teil von "oder" Operation war wahr

def eitherOne(image1, image2): 
    curIm1 = pyautogui.locateOnScreen(image1) 
    curIm2 = pyautogui.locateOnScreen(image2) 
    while curIm1 == None or curIm2 == None: 
     curIm1 = pyautogui.locateOnScreen(image1) 
     curIm2 = pyautogui.locateOnScreen(image2) 
    if curIm1 != None: 
     x, y = pyautogui.center(curIm1) 
     pyautogui.click(x,y) 
    if curIm2 != None: 
     x, y = pyautogui.center(curIm2) 
     pyautogui.click(x,y) 

Was tut dies für eine der beiden Bilder sucht und dann auf welcher auch immer endet wahr zu sein. Gibt es eine Methode oder eine Funktion, die ich verwenden kann, die bestimmen kann, welche der Bedingungen um das "oder" wahr zurückgab, ohne einen nachfolgenden Satz von "Wenn" -Operationen auszuführen? Auch wenn die Antwort "Nein, du brauchst die if-Statements" lautet, würde ich es begrüßen, also gehe ich nicht ohne Grund auf die Jagd.

Vielen Dank für Ihre Zeit!

+0

Sie brauchen irgendeine Art von * Sekundärstruktur *, die hineingeht und schauen, welche der getesteten Bedingungen tatsächlich 'True' waren. Die Sache mit deinem Code, der seltsam ist, ist, dass wenn du zum Beispiel "curIm2 = None" machst, du auch versuchen wirst "curIm1" zu aktualisieren. Willst du das wirklich? –

+0

Ihre aktuelle Logik erfordert, dass * sowohl * curIm1' als auch 'curIm2' nicht' None' sind, bevor die Schleife endet, so dass keine Ihrer 'if' Anweisungen danach notwendig ist. Meinst du für die 'while' ein' und' zu verwenden, so dass es nur Loops gibt, während sie beide 'None' sind? – Blckknght

+1

Vorausgesetzt, genau einer von ihnen ist da, können Sie 'theRightImage = curImg1 oder curImg2'. –

Antwort

3

Ich würde wahrscheinlich so etwas tun. Sie erstellen eine Endlosschleife, die wiederholt ein Bild und dann das andere versucht und bricht, sobald einer von ihnen erfolgreich ist.

def eitherOne(image1, image2): 
    images = itertools.cycle([image1, image2]) 
    for img in images: 
     curIm = pyautogui.locateOnScreen(img) 
     if curIm is not None: 
      break 
    x, y = pyautogui.center(curIm) 
    pyautogui.click(x, y) 

Wenn Sie es vorziehen, eine while Schleife zu einer for Schleife,

def eitherOne(image1, image2): 
    images = itertools.cycle([image1, image2]) 
    curIm = None 
    while curIm is None: 
     curIm = pyautogui.locateOnScreen(next(images)) 
    x, y = pyautogui.center(curIm) 
    pyautogui.click(x, y) 

Oder Sie können mit itertools mehr tun, insgesamt eine explizite Schleife zu vermeiden.

from itertools import cycle, imap, dropwhile 

def eitherOne(image1, image2): 
    curIm = next(dropwhile(lambda x: x is None, 
          imap(pyautogui.locateOnScreen, 
           cycle([image1, image2])))) 
    x, y = pyautogui.center(curIm) 
    pyautogui.click(x, y) 

(Ich bin ein wenig überrascht Sie nicht None als Prädikat zu dropwhile, ähnlich wie kann man mit filterfalse verwenden können.)


Update: tatsächlich, da filter und map bereits Rückkehr Iteratoren in Python 3, gibt es keine Notwendigkeit dropwhile und imap zu verwenden:

def eitherOne(image1, image2): 
    curIm = next(filter(None, 
         map(pyautogui.locateOnScreen, 
          cycle([image1, image2])))) 
    x, y = pyautogui.center(curIm) 
    pyautogui.click(x, y) 

Bonus Inhalt!

def eitherOne(image1, image2) = ([images1, images2] |> 
           cycle |> 
           map$(pyautogui.locateOnScreen) |> 
           filter$(None) |> 
           next |> 
           pyautogui.center |*> 
           pyautogui.click) 
1

A v2.7 Beispiel @ tobias_k Kommentar zu Ihrer Frage:

Um den funktionalen Ansatz zu einem extremen nehmen, könnten Sie die folgend in coconut schreiben. In Boolean Operation s wird der Wert der True espresion zurückgegeben.

class Img(object): 
    def __init__(self, name): 
     self.name = name 
    def __bool__(self): 
     return True 

c1 = Img('c1') 
c2 = None 

current_image = c2 or c1 
if current_image: 
    print(current_image.name) 
else: 
    print('None') 

In diesem Beispiel wird c1 zu current_image zugeordnet, weil es zu bedruckenden True und seine name wird auswertet.

Verwandte Themen