Sikuli script doesn't work

Asked by Wiw3K kisu

I have no idea why it doesn't want to run, it compiles without errors but nothing happens O.o

Pasted script on pastebin if anyone can check what i did wrong i would be thankful

http://pastebin.com/ywskXBmG

Question information

Language:
English Edit question
Status:
Solved
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Solved by:
RaiMan
Solved:
Last query:
Last reply:
Revision history for this message
Best RaiMan (raimund-hocke) said :
#1

Interesting approach, but Sikuli script does not work, as you seem to expect ;-)

when your script starts, all the exists() are processed and most of them I guess evaluate to None, since the images are not visible on the screen at that moment.

I guess you think, that the search takes place, at the time, the variable is used in your script:

e.g. you say:
iron1 = exists(Pattern("1344920814078.png").similar(0.85))

and use later
    if iron1:

expecting, that the search takes place now.

but that is not the case, sorry ;-)

But it is rather easy to repair with Pythonbs lambda feature:

iron1 = lambda : exists(Pattern("1344920814078.png").similar(0.85))

this turns iron1 into a callable function, that returns the result of the exists at use time

usage later:

    if iron1():

the bracket pair is needed, to tell Python that the function saved in iron1 should be called.

This is the best way, to get your script running as you expect with little systematic changes (insert some lambda : and some ()) while keeping your (very good) naming scheme and script structure.

But it is a very uncommon way.

Normally you would have the exists() in the places where you use the names:

instead for the iron1 case

- no definition of iron1 at the beginning
- usage: if exists(Pattern("1344920814078.png").similar(0.85))

An approach, that ends up in a similar naming and script structure would be:

again your iron1 case:

iron1 = Pattern("1344920814078.png").similar(0.85) # this is a "static" definition

and usage later:
   if exists(iron1):

This approach has other advantages:
- you can ajust the exists() later on in the workflow with a specific waiting time, e.g.
   if exists(iron1, 5):
- you can restrict the search region during your workflow, e.g.
   if some_region.exists(iron1):
making your script more robust and faster.

there are some interesting topics on such problems in the faqs.

Revision history for this message
j (j-the-k) said :
#2

Thanks for the interesting lambda function.
I always used a closure:

def getWrapper(pattern):
    def wrapper():
        return exists(pattern)
    return wrapper

method = getWrapper(Pattern("abc.png").similar(0.85))

method()

But lambda seems to be much simpler.

Revision history for this message
RaiMan (raimund-hocke) said :
#3

@ j-the-k
--- But lambda seems to be much simpler.
yes, but only in those cases, where the inner function body consists of only one expression (this is the limitation of lambda), but it might have n parameters.

In all other cases, your solution is the one, you have to use.

So you could do this:

myExists = lambda i, s : exists(Pattern(i).similar(s))

myExists("some-image.png", 0.95)

Revision history for this message
Wiw3K kisu (kisu1337) said :
#4

Thanks, that was helpful, did Your second advice about iron = pattern ... then use if exists(iron):

Revision history for this message
Wiw3K kisu (kisu1337) said :
#5

Thanks RaiMan, that solved my question.