Can't get wait to do something if it can't find image

Asked by Gmen

Hello,
     I'm having a problem with some of my code.

what i want it to do is wait for an image and if the image is not present it will do something else. here is an example of what im trying to do:

#code here
#more code
wait(img,60) #1will wait for the image a max of 60 seconds
click()#2starts doing the sequence of commands if the image is found
click()#starts doing the sequence of commands if the image is found
click()#starts doing the sequence of commands if the image is found
else: #3this is where i want it to go if the image is NOT found
     click()#4
     click()
     click()
     #5 after it completes this sequence of commands since the image WAS NOT found...
     #... i want it to go back up to #1 and look for the image again.
with (img): #this is more code i want completed when else: does NOT come into play *img found*
     click()
     click()

thanks for any help

Question information

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

--- 1.
have a look at the "Complete Guide" to get an impression of some basics (http://sikuli.org/trac/wiki/reference-0.10)

--- 2.
if you want to decide based on the existence/non-existence of images use exists() instead of wait:
https://answers.launchpad.net/sikuli/+question/133538
and
https://answers.launchpad.net/sikuli/+question/123366

--- 3.
Sikuli talks Python language, so
-- else: needs an if: before
-- with(img) is not defined (only valid for regions)

--- 4.
so in general your code might look like this:
if I understand right, that you want to wait for the image as long as needed

while True:
    if exists(img,60): #1will wait for the image a max of 60 seconds
       click()#2starts doing the sequence of commands if the image is found
       click()#starts doing the sequence of commands if the image is found
       click()#starts doing the sequence of commands if the image is found
       break # this ends the loop
    else: #3this is where i want it to go if the image is NOT found
       click()#4
       click()
       click()
       #5 after it completes this sequence of commands since the image WAS NOT found...
       #... i want it to go back up to #1 and look for the image again.
# her script continues if image was found
# with (img): # not valid - see comment
#this is more code i want completed when else: does NOT come into play *img found*
click()
click()

The while-loop will run endless if img never comes up.
So you might implement some additional code to end the loop and or the script in this case.

Revision history for this message
Gmen (way-2-hot-a-yahoo) said :
#2

AHH thanks yes, much better to use *if exists* thank you.

Another question i have. something random.

like this:

click()
click()
type ("t")#1
or
type ("I")#2 # 1,2,3 i want it to choose one randomly or lets say i want a 33.3% chance to type T, I, Or R
or
type ("R")#3
click()
click()

and if this is possible more random.

click()
click() #when it gets here i wonder if there is a 50% chance it will skip #set 1 and go to #set 2
#set 1 #or execute #set 1 and skip #set 2
click()
click()
click()
#set 2
click()
click()
click()

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

rather easy (you may look at Python random http://docs.python.org/library/random.html)

--- 1.
type(random.choice("T", "I", "R")) # selects randomly from the given list

--- 2.
if random.random() > 0.5: # generates a random float between 0 and 1
# exec set 1
    click()
else:
# exec set 2
   click()

Revision history for this message
Gmen (way-2-hot-a-yahoo) said :
#4

so if im understanding correctly i can do something like this:

if random.random() >0.5: # so from this point it will either execute set 1 or 2, but not both.
   click() #set 1
   click()
   type("hello")
   click()
else: # but what if i wanted to include a set 3 would this be possible?
   click() #set 2
   click()
   type("hello2")
   click()
with : #more code
   click()

thank you

Revision history for this message
Gmen (way-2-hot-a-yahoo) said :
#5

so if im understanding correctly i can do something like this:

if random.random() >0.5: # so from this point it will either execute set 1 or 2, but not both.
   click() #set 1
   click()
   type("hello")
   click()
else: # but what if i wanted to include a set 3 would this be possible?
   click() #set 2
   click()
   type("hello2")
   click()
with : #more code
   click()

thank you

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

in other programming languages you have a special construct for this (e.g. case .. when ... when ...). That is not available in Python. But you have if: ... elif: ... elif: ... elif: ... else: ... - where you may have as many elif's as you want and one final (optional) else, which is processed if none of the elif's before are chosen.

an example in your case:

we have to store the random number, so the same number is evaluated with each if: / elif:

rNum = random.random()

if rNum < float(1)/3:
   print "set 1"
elif rNum > float(1)/3 and rNum < float(2)/3:
   print "set 2"
elif rNum > float(2)/3:
   print "set 3"
else:
   print "This should never happen!"
   exit()
print "after the case selection"

the construct float(1)/3 is necessary if you want to be as exact as possible. It enforces a floating point number for 1/3. You may use 0.3333 and 0.6666 instead.

Revision history for this message
Gmen (way-2-hot-a-yahoo) said :
#7

ok ok. i see now. thats great :)

i looked through the resource manual here for sikuli, but i couldn't quite figure out the observer function.

i i set an observer if that image where to come up it would do something? lets say for an example, how would i work an error like if a page wouldnt load *which would cause an find patter error* how could i have sikuli observ and wait for this page, and if it doesnt come up and it finds patter *meaning the page loaded* to stop observing?

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

to use the observer feature only makes sense in two cases:
---1. your script might do something else while Sikuli is observing in the background - until a certain point, where the script depends on the existence/non-existence of the observed visual event
---2. you implement something like a dispatcher, that waits for different visual events and triggers the appropriate action

In all other cases I prefer to use exits().

This may change with the upcoming Sikuli X, where the observer feature is free of bugs and can be fine tuned.

In your case I suppose, that you only have to wait for the page and nothing else can be done meanwhile. Then these are your options:

--- most simple: (you have to decide for a maximum wait time)
if not exists("some-image-that-proves-the-existence-of-the-page", 100): # looks 100 seconds and then gives up
   print "page did not show up"; exit() # makes no sense to go on

--- most complex: (repeated wait with a retry limit)
nTries = 10
while nTries > 0:
   if not exists("some-image-that-proves-the-existence-of-the-page", 100): # looks 100 seconds and then gives up
      # some corrective actions that make sense
      # to wait again
      nTries -= 1
if n == 0:
      print "page did not show up"; exit() # makes no sense to go on

I have never seen any sense in solving this using the observer feature: it makes it even more complex because of the handler.