[HowTo] Use Region to speed up execution

Asked by David Borghi on 2019-10-28

I'd like to try to implement the Region class to make the script run faster, the script is clicking after ~550msec after the images appear on the screen, I don't know If It would be possible to make it run even faster.

Do you think it would be possible?

If so, does anybody can point out to me where I should start?

Sikulix version: 1.1.3 (Should I update to the 2.0 version?)

That's my script:

img1 = "img1.png"
img11 = "img11.png"
img111 = "img111.png"
img12 = "img12.png"
img121 = "img121.png"
img2 = "img2.png"

def do(a, b, ab, abc):
    if not (exists(a, 0) and exists(ab, 0)):
        return

    click(abc)
    start = time.time()

    while exists(ab, 0):
        wait(0.1)

    while time.time() < (start + 3) and exists(a, 0):
        pass

    if exists(a, 0):
        click(b)
        return

while True:
    do(a="img1", b="img2", ab="img11", abc="img121")
    do(a="img1", b="img2", ab="img12", abc="img111")

Thank you for your help and attention!
I'm sorry for any inconvenience.

Question information

Language:
English Edit question
Status:
Open
For:
Sikuli Edit question
Assignee:
No assignee Edit question
Last query:
2019-11-07
Last reply:
2019-11-07
RaiMan (raimund-hocke) said : #1

Supposing that the images do not move while the script is running, then it brings the most, if you restrict the search region to a smaller area than the whole screen.
This can be achieved either by absolute Regions (given with coordinates/dimension, with selectRegion() or by evaluating the app window) or relative with respect to matches you already know (logos, titles, buttons, ...).

Searchtime is dramatically reduced, if you have searched an image before and then later search it in the place it was found before.

your example:

# add a region parameter
def do(a, b, ab, abc, reg):
    #save matches for later use
    #if not (exists(a, 0) and exists(ab, 0)):
    ma = reg.exists(a, 0)
    mab = reg.exists(ab, 0)
    if not (ma and ab):
        return

    reg.click(abc)
    start = time.time()

    # you suppose this vanishes in any case: risky
    """
    while mab.exists(ab, 0):
        pass
        #wait(0.1) # does not make sense
    """
    #better use waitVanish()
    if not mab.waitVanish(mab):
      exit(1) # did not vanish within 3 secs

    # replace with waitVanish()
    """
    while time.time() < (start + 3) and ma.exists(a, 0):
        pass

    if ma.exists(a, 0):
        click(b)
        return
    """
    if ma.waitVanish(ma, 3):
      reg.click(b)
      return # might be redundant

# usage
someRegion = ...
# outer border - evaluate somehow (contains all images searched)

do(a="img1", b="img2", ab="img11", abc="img121", someRegion)

RaiMan (raimund-hocke) said : #2

... and yes, you should upgrade to 2.0.0

David Borghi (davidborghi) said : #3

Thank you RaiMan.

I decided to simplify the script as I wasn't using the most "complex" part of it.

Just to be clear, whenever a click is executed, img1 "disappears" (it changes from 0 to something, for example, "1"). The script is only "activated" when another image pops up on the screen (img11 and img12).

I think I didn't get some points (like the someRegion), I'll try to rewrite the script as per your orientation.

That's how the script is now (without the Region implementation):

img1 = "img1.png"
img11 = "img11.png"
img111 = "img111.png"
img12 = "img12.png"
img121 = "img121.png"

def do(a, ab, abc):
    if not (exists(a, 0) and exists(ab, 0)):
        return

    click(abc)

    while exists(ab, 0):
        wait(0.1)

while True:
    do(a="img1", ab="img11", abc="img121")
    do(a="img1", ab="img12", abc="img111")

Should it be something like the script below? (As I said, I didn't get the usage for someRegion.)

img1 = "img1.png"
img11 = "img11.png"
img111 = "img111.png"
img12 = "img12.png"
img121 = "img121.png"
reg = Region(653,1129,1902,310)

def do(a, b, ab, abc, reg):
    ma = reg.exists(a, 0)
    mab = reg.exists(ab, 0)
    if not (ma and mab):
        return

    reg.click(abc)

    while mab.exists(ab, 0):
        pass

while True:
    do(a="img1", ab="img11", abc="img121")
    do(a="img1", ab="img12", abc="img111")

I'll upgrade.

Thank you for your help and attention.

David Borghi (davidborghi) said : #4

RaiMan, I'm sorry that I just added a new comment when I should have chosen the other button.

The script does exactly what you described in the second paragraph ("Searchtime is dramatically...").

I tried to implement what you suggested but I'm going anywhere since I didn't understand how should apply the someRegion.

How should I add the region parameter here:

while True:
    do(a="img1", ab="img11", abc="img121")
    do(a="img1", ab="img12", abc="img111")

I'm asking this since it doesn't seem to be the same as was if "a", "ab" etc.

I'm sorry for the inconvenience.

David Borghi (davidborghi) said : #5

how I should apply*
as was with*

RaiMan (raimund-hocke) said : #6

someRegion = Region(653,1129,1902,310)

....

while True:
    do(a="img1", ab="img11", abc="img121", reg=someRegion)
    do(a="img1", ab="img12", abc="img111", reg=someRegion)

David Borghi (davidborghi) said : #7

Thank you RaiMan.
I'm sorry for the confusion.

Turns out that I was just forgetting to remove one of the arguments from the function.

I tried what you suggested before but I was getting an error and just found out now when I was checking word by word.

Should I get a different number in the log now?

I was getting ~530ms in the log before the change, but now I'm getting the same numbers, although, the script seems faster than before.

Thank you for your help and attention.
I'm sorry for all the confusion.
I really appreciate what you all have been doing with Sikuli!

RaiMan (raimund-hocke) said : #8

It is always very hard to judge things like that from far away ;-)

But if you send me your final version of the script (use sikulix---at---outlook---dot---com), the size of your screen and if possible the images you are using, then can have a look.

David Borghi (davidborghi) said : #9

Thank you for your help (and willingness to help!) and your attention!

No need to worry about that, the script is definitely faster!

If I would like to change this script to a different variation, for example, make the click only if the img11 e img12 appears three times in two seconds, should I use the same method that I was using before or would you advise me to use another method?

Just so you can understand, the img11 e img12 are both kind of "pop-ups", so, I'd like the script to only make the click if the img11 appears 3 times in a row.

I don't know If I was clear enough, If not, please, just forget/ignore it, I'll try to do and If I can't, I'll ask for help.

Thank you again!

Have a wonderful time you all.

RaiMan (raimund-hocke) said : #10

start = time.time()
end = start + 2
count = 0

while time.time() < end:
    if (reg.has(img)): count += 1

if count > 2:
    print "appeared %d times in 3 seconds" % count

David Borghi (davidborghi) said : #11

Thank you for your suggestion, although, I don't know If I understood the workflow or If I failed to implement it, considering I didn't get the print.

I hope I don't sound confusion.

I used the img11 as an example, considering I'd like to create the variation where If one of both images (11 e 12) appears more than 3 times in a row, so, If It happens I expect the script to click (img111 or img121).

The pop-ups appear above each other.

To simplify:

If img1 is there and img11 or img12 appear 3 times (the count will start as soon as one of them appear) in a period of 2 seconds, click img111 or img121.

Considering the pop-ups are almost exactly the same (there is just a variation of numbers and a specific word - which triggers the script), do you think the script will be capable to understand that the images appeared 3 times (I mean, 3 pop-ups)?

I'm sorry for all the confusion.

Thank you for all your help and your time.

Can you help with this problem?

Provide an answer of your own, or ask David Borghi for more information if necessary.

To post a message you must log in.