After a script runs 50 times I want to add a different keystroke to the script, how do I code that?

Asked by joel hatzfeld

I'm a user, not a developer so first I must say my apologies. Here is the code I'm using

for n in range(100):
          wait(6)
          type("T")
          find(<image>)
          click(<image>)
          type(Key.ESC)
          hover(<second image>)
          wait(20)
          rightClick(<third image>)

this code automates tedious farming in a video game, but after about 75 cycles it will stop because an item that a player uses will break. What I can't figure out while reading is how to add something like

after 60 cycles
         type("1")

which will make a player use a new item, without stopping the script.

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

Generally, this is done with if/elif/else:

example:

if n <= 60:
          type("T")
elif n > 60 and n < 70:
          type("1")
elif n > 69 and n < 80:
          type("X")
else
          type("Z")

If the script gets to this, it will check the content of and will
-- type("T"), if it is less than 61 (<=60)
-- type("1"), if it is in the range 61 to 69 inclusive
-- type("X"), if it is in the range 70 to 69 inclusive
-- type("Z") in all other cases

You may have as many elif's (or none) between the if and the else (which might not be there) .

if it is only one line after if/elif/else, you might do it this way:

if n == 60: type("1")
else: type("Z")

so my guess in your case:

for n in range(100):
          wait(6)
          if n == 60:
                  type("1")
          else:
                  type("T")
          find(<image>)
          click(<image>)
          type(Key.ESC)
          hover(<second image>)
          wait(20)
          rightClick(<third image>)

One more thing:
To indent, it seems you are taking 8 blanks. The recommendation general and and especially in the Sikuli IDE, is to use a tab to indent one level and shift-tab to dedent one level. The IDE manages internally, to make each tab/shift-tab to be 4 blanks.

Revision history for this message
joel hatzfeld (hatzfeld-joel) said :
#2

I'm not looking to exclude the

type("T")

at any time, but having continued reading a little more, and then reading what you suggested, I think I can explain what I'm looking to do a little better. I guess 'n' in the first line is what number in the range I'm on, and then at 100 it will stop, is that correct? in the game it won't get through 100 cycles because the item the player uses stops working at 75, so I think reading your if/elif/else code I should increase my range to 300 and use something like

if n <= 75:
          type("1")
elif n > 76 and n < 150:
          type("2")
elif n > 151 and n < 225:
          type("3")
else
          type("4")
          type("T")

pressing 1-4 changes a hotkey to interchangeably switch out the items used, and they're all duplicates so reading the suggestion you're given me makes me assume that during the first 75 cycles it will use the item the player has equiped, then by pressing 1-4 during the cycles between 76-300 it will attempt to equip whatever item is on the players hotbar (no negative side effects if it is already equipped). Pressing "T" opens a window so it can't be moved or switched.

with regards to the spacing / tab issue, I don't understand the why behind what you're saying, but I can certainly understand the "you should use tab instead of 8 blanks" portion, and I'll change that too.

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

Sorry, but it is always a problem to "guess" what might be the behavior of the target application.

At least I think you got it with the use of if/elif/else.

--- with regards to the spacing / tab issue, I don't understand the why behind what you're saying
the why: within one block (e.g. within an if, an else, a while loop, a for loop, ...) the indent must be consistent:
if you indent with 8 blanks, it must be 8 blanks throughout the block.
This might be transparent for one level, but when it comes to a second, third, n-th level (if's within if's within for's ...) it gets non-transparent and these errors are really hard to find.

Therefor from the beginning: use tab/shift-tab.

Tip: If you run into problems. that might be based on indentation errors, select the lines, that might be the cause, use shift-tab until the indent is 0 and tab again to the right indent level.

--- one more thing:
instead of using a for loop or as an additional support, you might think about checking for some other visual objects (exists or observe), that may give you the information, that the status of your app changed.

Revision history for this message
joel hatzfeld (hatzfeld-joel) said :
#4

for n in range(375):
    if n <= 74:
        type("1")
    elif n > 74 and n < 150:
        type("2")
    elif n >149 and n < 225:
        type("X")
    elif n >224 and n <300:
        type("4")
    else:
        type("5")
    wait(3)
    type("T")
    find(<image>)
    click(<image>)
    type(Key.ESC)
    hover(<second image>)
    wait(20)
    rightClick(<third image>)
    wait(6)

trying this now, if it works, then I'm going to to amend it one more time and try the following,

if n = 75:
    type("1")
if n = 150
    type("2")

etc..., so that it only attempts to press the 1 hotkey one time instead of every cycle between the ranges 1-75, or 75-150 and so on.

Thank you for your help Raiman, I appreciate it.

Revision history for this message
joel hatzfeld (hatzfeld-joel) said :
#5

Thanks RaiMan, that solved my question.