Repeat Loops

One of the great strengths of computers is their ability to perform repetitive tasks with ease. SenseTalk provides several different types of repeat loops for this purpose.

A repeat loop is used any time you want to execute one or more statements repeatedly some number of times. The statements to be repeated are preceded by one of the repeat statements described below, and must always be followed by an end repeat statement to mark the end of the loop. Repeat loops may be nested.

Repeat Forever

Behavior: This form of repeat loop repeats indefinitely until terminated. Usually, you do not really want your script to keep looping forever (a condition known by programmers as an “infinite loop”), so repeat forever loops typically include at least one exit, return, or pass statement that breaks out of the loop when some condition has been met: The word forever is optional.

Syntax:

repeat {forever}

statementList

end repeat

Example:

repeat forever

get nextValue(partList)

if it is empty then exit repeat // Generally there will be some handling within a forever repeat loop that provides a way to exit the repeat loop

TypeText it

end repeat

Repeat Number Times or For Duration

Behavior: This form repeats the number of times specified by the expression number or for the amount of time specified by the duration.

Syntax:

repeat {for} number {times}

statementList

end repeat

repeat {for} duration

statementList

end repeat

Example:

repeat 6 times

click "Arrow"

end repeat

Example:

repeat 1 minute

If imagefound(imageName:"Notification", waitFor:0) then

Logwarning "The warning is still present."

wait 2

else

Log "The warning is gone."

Exit Repeat

end if

end repeat

Repeat Until Condition, Repeat Until Time

Behavior: This form of repeat loop executes until the condition expression evaluates to a value of true, or until a given date/time arrives. The condition or time expression is evaluated before the first and each subsequent execution of the loop.

Syntax:

repeat until condition

statementList

end repeat

Syntax:

repeat until timeExpression

statementList

end repeat

Example:

repeat until list is empty

put the last item of list

delete the last item of list

end repeat

Example:

on ScrollUntilFound ImageName, myTime

Repeat until imagefound(image:imageName,waitfor:mytime)

if the repeatindex is greater than 10 // Read more about the repeatIndex below

throw "image not found", imageName&&"not found when scrolling."

end if

Typetext PageDown

Wait 1

end repeat

end ScrollUntilFound

Example:

repeat until "3:17 pm" // Repeats until the local system (eggPlant machine) clock hits 3:17 pm"

log "counting the seconds"

wait 1

end repeat

Repeat While

Behavior: This form of repeat loop will execute as long as the condition expression evaluates to a value of true. The condition is evaluated before the first and each subsequent execution of the loop.

Syntax:

repeat while condition

statementList

end repeat

Example:

set CountDown to 1000

repeat while CountDown is greater than 500

put readtext("TimerTL","TimerLR") into CountDown // Uses OCR to read a dynamic value off the SUT's screen

wait 3

end repeat

Example:

put 10 into x

repeat while x < 100

add x to x

end repeat

Repeat With Variable = Start to Finish

Behavior: This form of repeat sets a variable to each of a sequence of values. The term up to or down to may be used instead of the word to to indicate whether the loop variable should be incremented (increased) or decremented (decreased) each time through the loop. If neither direction is specified, up to is assumed. A step option lets you specify an amount other than 1 by which the loop variable is changed.

Syntax:

repeat [with | for] variable [= | as | from] start {up | down} to finish {step stepAmount}

statementList

end repeat

Example:

put "Countdown"

repeat with n=10 down to 1

put n

wait one second

end repeat

put "BOOM!"

Example:

repeat with n=1 to the number of lines in file "/tmp/legalDoc"

put n & ": " & line n of file "/tmp/legalDoc"

end repeat

Example:

repeat with rate = 4.75 to 8.5 step 0.25

put "Rate: " & rate & tab &"Payment: " & calcPayment(rate)

end repeat

Example:

repeat with discount = 50 down to 0 step 5

insert (amount - discount%) after discountList

end repeat

Tech Talk

The value of variable is set to the value of start before the first execution of the loop. Variable is then incremented (or decremented for “down to”) by the value of stepAmount (or by 1, if no stepAmount is given) before each subsequent repetition. The value of variable is compared to the value of finish before each execution. When variable is greater than finish (or less than finish for “down to”) the loop is terminated. If variable is a reference, it will be reset to an ordinary variable before use.

Tip: When a repeat loop using a loop variable is nested inside another, be sure to use a different variable for each loop, in order to avoid conflicts.

Repeat With Each

The repeat with each form is perhaps the most powerful and useful of all of SenseTalk’s repeat loops. This form of repeat makes it easy to step through each of the values in a list, the words in a sentence, the lines of text in a file, or many other subdivisions of a value.

When using this form to repeat through the items of a list, etc., the repeat variable (or it) will be set to each of the values in turn, from the first to the last. To step through the values in the opposite order, include the phrase in reverse order.

Syntax:

repeat with each subitemType [of | in] containingItem {in [reverse | reversed] order } {[as {a} | by] reference}

statements

end repeat

repeat with variable = each subitemType [of | in] containingItem {in [reverse | reversed] order } {[as {a} | by] reference}

statements

end repeat

repeat with each {subitemType} variable [of | in] containingItem {in [reverse | reversed] order } {[as {a} | by] reference}

statements

end repeat

Example:

repeat with each item of myAccountList

set property balance of it to zero -- Set the balance of each account in a list of account objects to zero

end repeat

Example:

put empty into condensedList -- Start with nothing; gather all non-blank lines of a file into a container

put file "/tmp/somefile" into sourceText -- Read the file

repeat with each line of sourceText

if it is not empty then put it & return

after condensedList

end repeat -- Count the number of times each word occurs in a text file

Example:

answer file "Select a file to count its words" -- Get the file to be counted:

if the result is "Cancel" then exit handler

put it into sourceFile

put {:} into wordCounts -- Start with an empty property list

repeat with each word of file sourceFile

add 1 to property (it) of wordCounts

end repeat

Example:

put "Word counts in file " & sourceFile & ":"

repeat with each item of the keys of wordCounts

put it && "appears" && wordCounts.(it) && "times"

end repeat

Example:

repeat with each line of file "/tmp/example" by reference

if it begins with "#" then delete it -- Delete every line that begins with "#" in a text file:

end repeat

Example:

put files(SuiteInfo().imagesFolder&slash&"OKButton") as a list into imageFiles // Stores a list of objects representing all of the files in the image collection named "OKButton"

repeat with each item of ImageFiles

if it contains ".imageinfo" then delete it from ImageFiles // Checks whether the text representation of the file object contains the string ".imageinfo" and deletes the item from the list if so

end repeat

Example:

set the RemoteWorkInterval to .1

repeat with each item of everyimagelocation("CheckBox")

click it

end repeat

set the RemoteWorkInterval to .7

Tech Talk

These repeat formats execute the statements within the repeat loop (until the matching end repeat statement) exactly once for each object or part (as specified by subitemType) that is contained within the specified containingItem. Virtually any of the combinations of subitemType and containingItem that are allowed with the number function can be used (that is, anything that can be counted within some containing object or container).

In all forms of the repeat with each statement, subitemType indicates the type of item being iterated over (if omitted in the third format shown above, "item" is assumed), and containingItem is the specific object or container whose parts are being iterated over.

In the second and third formats, variable is the name of a variable which will be assigned the identifier or contents of a particular subitem each time through the repeat loop. In the first format, where no specific variable is specified, the variable it is used. If by reference is specified, variable is set to be a reference to each subitem. Otherwise, if variable (or it) is already a reference, it will be reset to be an ordinary variable before being used as the loop variable.

In cases where subitemType is a type of object, the long id of the specific subObject will be assigned to it or variable each time through the loop. In cases where subitemType is a type of text chunk, the actual chunk of text will be stored in it or in variable.

Tip: When a repeat loop using a loop variable is nested inside another, be sure to use a different variable for each loop. In particular, watch out for nested repeats which implicitly use it as a loop variable.

Repeat At Least Once Until, Repeat At Least Once While

Behavior: Executes the statements within the repeat loop once before checking the condition, ensuring that the statements will be performed at least once.

Syntax:

repeat at least once until condition

repeat at least once while condition

Example:

repeat at least once until list is empty

put the last item of list

delete the last item of list

end repeat

Example:

// Use code like below to detect when you've scrolled to the bottom of a page/screen.

put RemoteScreenSize() into DUTScreenSize // Stores the size of the screen of the SUT

put (.25*DUTScreenSize.x, .25*DUTScreenSize.y, .75*DUTScreenSize.x, .75*DUTScreenSize.y) into ClippingRectangle

CaptureScreen (Name: "state", Rectangle: ClippingRectangle) // Captures a screenshot of the SUT, only in the center portion of the screen

put the result into refImage // Stores the file path of the CaptureScreen image in a variable

repeat at least once while not imageFound(image:refImage,searchRectangle:ClippingRectangle,waitFor:0) // Forces the statements within the repeat loop to happen at least once, even if the condition is immediately met

CaptureScreen (Name: "state", Rectangle: ClippingRectangle) // Captures a new screenshot of the SUT

put the result into refImage

TypeText PageDown // Scrolls the screen toward the bottom of the page

Wait 2.5 // Wait long enough to allow the scrolling action to "settle"

end repeat

Counter Function, RepeatIndex Function

Behavior: The counter or repeatIndex function returns the current iteration count of the innermost executing repeat loop. This approach is useful for keeping track of how many times a loop repeated or took action once a certain count is reached.

Syntax:

counter()

the counter

repeatIndex()

the repeatIndex

Example:

repeat for 3 minutes

if the counter is a multiple of 100 then put the counter

end repeat

Example:

repeat until imagefound(imagename:"NextButton",waitFor:0)

if repeatindex() = 2 then throw "Image not found", "Image not found while scrolling."

SwipeUp

wait 2

end repeat

Example:

function FindColorPercentage myImage,myColor // Declares the custom function FindColorPercentage with two parameters myImage and myColor

assert that myColor is not empty // Confirms that a value was passed in for the myColor parameter, and throws an exception if one was not

put the width of imageSize(myImage) into XDirection // Determines how many pixels wide the image is

put the height of imageSize(myImage) into YDirection

set TotalPixels to XDirection times YDirection // Calculates the total number of pixels in the captured image

set ColorPixels to 0

repeat YDirection times

put the repeatIndex - 1 into YCoord // Uses the repeatindex to keep track of which coordinate we are operating on

repeat XDirection times

put the repeatIndex - 1 into XCoord

put imagecoloratlocation(myImage, (XCoord,YCoord)) into ReturnedColor // Uses the imageColoratLocation() function to retrieve the RGB value of the current pixel

if ReturnedColor is color(myColor) then add 1 to ColorPixels // Uses the color() function to compare the actual RGB value against the RGB value passed into the FindColorPercentage function

end repeat

end repeat

return round((ColorPixels/TotalPixels) * 100, 1) // Calculates the percentage of pixels matching that desired color

end function

Tip: Use the repeatIndex in any type of repeat loop. Its value is set to one the first time through the loop and increases by one on each iteration. If used inside nested loops it reports the index of the innermost loop in which it resides.

 

This topic was last updated on August 19, 2021, at 03:30:51 PM.

Eggplant icon Eggplantsoftware.com | Documentation Home | User Forums | Support | Copyright © 2022 Eggplant