Is there a shorter way to check a condition before each line of code without repeating the condition?

76 views Asked by At

I'm trying to make a failsafe with pyautogui. Having to move my mouse cursor to the corner is very difficult at times. Below is a sample of what my code is suppose to do when this key bind is active. It works, but I want to see if there is a better way of writing this code without having to repeat each condition every time. I want to be able to perform the failsafe at anytime during the loop instead of having to wait until the beginning of each iteration.

this is what I want my code to do:

import pyautogui
import sys
from win32.lib.win32con import VK_CAPITAL
from win32.win32api import GetKeyState

def check():
    if GetKeyState(VK_CAPITAL) == 1:
        sys.exit()

for i in range(10):
    check()
    pyautogui.move(100,200, duration=1)
    check()
    pyautogui.move(200,200, duration=1)
    check()
    pyautogui.move(200,300, duration=1)
    check()

this is what it looks like right now:

import pyautogui
import sys
from win32.lib.win32con import VK_CAPITAL
from win32.win32api import GetKeyState

def check():
    if GetKeyState(VK_CAPITAL) == 1:
        sys.exit()

for i in range(10):
    check()
    pyautogui.move(100,200, duration=1)
    pyautogui.move(200,200, duration=1)
    pyautogui.move(200,300, duration=1)
2

There are 2 answers

5
Mark Tolonen On BEST ANSWER

Build a list of callable actions and iterate the list while checking for your condition. The following will call the function list until the caps lock key is active:

import sys
import time
from win32.lib.win32con import VK_CAPITAL
from win32.win32api import GetKeyState

def check():
    if GetKeyState(VK_CAPITAL) == 1:
        print('exiting...')
        sys.exit()

def move(x,y,duration):
    print(f'move to {x},{y}')
    time.sleep(duration)

funcs = (lambda: move(100,200,duration=1),
         lambda: move(200,200,duration=1),
         lambda: move(200,300,duration=1))

while True:
    for func in funcs:
        check()
        func()
0
Riyas On

A different approach,

def func1():
   print('func1')
def func2():
   print('func1')
def func3():
   print('func1')

funcs_map['cond1'] = func1
funcs_map['cond2'] = func2
funcs_map['cond3'] = func3

def get_condition(i:int) -> str:
    if(i == 1):
       return 'cond1'
    elif(i == 2):
       return 'cond2'
    else:
       raise ValueError(f'Unknown i value: {i} to get a condition')


for i in range(x):
   func_ptr = funcs_map[get_condition(i)]
   func_ptr()