Sign in to follow this  
Followers 0
JohnSAutoIt

When do parameters have to be passed into a Func?

7 posts in this topic

#1 ·  Posted (edited)

I've read the Help but it does not explain what parameters have to be passed to a Func and those that don't (Help calls Func "a user-defined function that takes zero or more arguments"). I've also looked at examples and can't find a pattern. I assume that anything Global should be passed without doing anything?

I had a script that worked fine. Both $iSeq and $k are passed from Advance() into main script when it resumes.

Condensed version:

HotKeySet("{RIGHT}", "Advance")

......main script
For $iSeq = $iStart To $FileList[0] Step 1
    ....bunch of other stuff
    For $k = 1 To 5 Step 1 ; 5 per sec
        Sleep($ImageTime200)
    Next
Next
.......end of main script

Func Advance()
    .....bunch of other stuff
    $iSeq = $iSeq + 1
    $k = 1
EndFunc   ;==>Advance

I split into more Funcs to get:

HotKeySet("{RIGHT}", "Advance")
MainScript()

Func MainScript()
For $iSeq = $iStart To $FileList[0] Step 1
    ....bunch of other stuff
    For $k = 1 To 5 Step 1 ; 5 per sec
    Sleep($ImageTime200)
    Next
Next
EndFunc   ;==>MainScript

Func Advance()
    .....bunch of other stuff
    $iSeq = $iSeq + 1
    $k = 1
EndFunc   ;==>Advance

The code in Advance() works fine (interrupting MainScript() ) but does not pass the values $iSeq and $k into MainScript() when it resumes.

Edited by JohnSAutoIt

Share this post


Link to post
Share on other sites



Well, you have several "misunderstandings" in your script; let's see if I can correct them one by one.

- Variable scope: a variable declared inside a function is KNOWN only inside that function alone

Your $iSeq variable declared in MainScript() is different than $iSeq from Advance() -> $iSeq from Advance() will start with value 0 and the result will be 1 - EVERYTIME you run that function. In order to have the variable known everywhere in your script, you need to declare it in your main code (global variable). $k have the same problem.

- For/Next: a variable used as a counter in a For/Next loop is "better" to not be used for other purposes. If you want to use that variable, just create another one and make it equal every turn.

- Arguments: MyFunc($x) -> $x is an argument; what you really meant in your post is to have a value "RETURNED" to your function. 2 ways to accomplish that: using global variables or using "Return $k"

All I wrote here is general knowledge, however, your script here needs something to be done which is not usual - to "hurry" a loop - the answer is much complicated to that. My example script will be able to "hurry" your main loop depending on how many times you have pressed the right arrow. As for your second loop ($k) I really can't figure what you want to accomplish with that? To make your second loop start from the begining? My script is handling that. Basically what it does is: if $Advance value is greater than 0 it skips the rest of the loop until $Advance becomes 0. Once it becomes 0, your second loop will start from the beginig as well.

Here is how your script should look:

HotKeySet("{RIGHT}", "Advance")
Global $Advance = 0

MainScript()

Func MainScript()
For $iSeq = 1 To 20
    If $Advance Then
        $Advance -= 1
        ContinueLoop
    EndIf
    Sleep(1000)
    For $k = 1 To 5 Step 1 ; 5 per sec
        Sleep(100)
    Next
    MsgBox(0, "main", "$k = "&$k &" $iSeq= "&$iSeq)
Next
EndFunc   ;==>MainScript

Func Advance()
    $Advance += 1
EndFunc   ;==>Advance

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Share this post


Link to post
Share on other sites

.... Variable scope: a variable declared inside a function is KNOWN only inside that function alone

As I intimated in the first post I had assumed that anything declared Global was valid throughout the script. That's what I had in place. Confirmed by you.

.... For/Next: a variable used as a counter in a For/Next loop is "better" to not be used for other purposes. If you want to use that variable, just create another one and make it equal every turn.

The intention of the loop counter $iSeq change in Advance() was to increment it. I was not using it for any other purpose. Originally I had used $i but changed to $iSeq to ensure it was unique.

Share this post


Link to post
Share on other sites

Try these to see the difference.

Global $str = "Text 1"

MsgBox(0x2000, "Example 1", $str)
_ShowPopUp("Text 2")

Func _ShowPopUp($str)
    MsgBox(0x2000, "Example 2", $str)
EndFunc

Global $str = "Text 1"

MsgBox(0x2000, "Example 1", $str)
MsgBox(0x2000, "Example 2", _ReturnString("Text 2"))

Func _ReturnString($str)
    Return $str & " success!"
EndFunc

Global $str = "Text 1"

MsgBox(0x2000, "Example 1", $str)
_ModifyString($str)
MsgBox(0x2000, "Example 2", $str)

Func _ModifyString(ByRef $temp)
    $temp = $temp & " success!"
EndFunc

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

I'm too lazy to read all the replies, but I attempt a reply to your problem from what I read.

Here's the basic how to of a function from what I've learnt (I'm new to autoit):

Let's say you want a function that returns the square root of 2 numbers you decide.

IE: in this example i'll set as numbers 16 and 64:

$i_number1=16
$i_number2=64
$Result=Calculatesquare($i_number1,$i_number2);here we assign a variable to the RETURN result of Func
MsgBox(0,"Squares results","Square of number 1 is: "&$Result[0]&@CRLF& _
"Square of number 2 is: "&$Result[1])

Func CalculateSquare($Num1,$Num2);Calculatesquare($i_number1,$i_number2) means Num1=i_num1; Num2=i_num2
    Local $array[2]=[Sqrt($i_number1),Sqrt($i_number2)];Holding multiple results in an array
    Return $array;This is the key to return a result to a function, it means $array=$Result
EndFunc

Hope it's more clear.

Edited by niubbone

Share this post


Link to post
Share on other sites

Thanks for the examples. They were a lot clearer than those in Help; one script at a time.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

.....My example script will be able to "hurry" your main loop depending on how many times you have pressed the right arrow.

I thought I understood the example code but it does not work as I had thought. On "advance" it is not skipping the lower part of the loop. I added the hotkey and a short sound file to test in realtime.

Global $Advance = 0
HotKeySet("{RIGHT}", "Advance")
MainScript()

Func MainScript()
For $iSeq = 1 To 20
    If $Advance Then
        $Advance -= 1
        ContinueLoop
    EndIf
    Sleep(1000)
    For $k = 1 To 5 Step 1 ; 10 per sec
        Sleep(100)
    Next
    SoundPlay(@WindowsDir & "\media\ding.wav", 0)
;~     MsgBox(0, "main", "$k = "&$k &" $iSeq= "&$iSeq)
Next
EndFunc   ;==>MainScript

Func Advance()
    $Advance += 1
EndFunc   ;==>Advance

If the script is started running, you get a ding every 1.5 secs. If you repeatedly "advance" say every 1/2 sec then the sound file should not run until 1.5 secs after the last "advance" is pressed. What I am finding is that the sound file runs every 1.5 secs regardless. What am I missing?

(Edit) I think I have found the problem. After hitting "Advance" the script whips back through the loop and passes into the lower part of the loop. I moved the Sleep(1000) above the ContinueLoop statement which seemed to improve things by holding the script until the next "Advance" command, if within 1 sec. The commands don't do exactly what I'm looking for but if my latest interpretation is correct I should be able to figure things out.

(Edit2) Although the final resolution is OT for the thread title, I have finally sorted out a working loop:

Global $Advance = 0

HotKeySet("{RIGHT}", "Advance")
MainScript()

Func MainScript()
    For $iSeq = 1 To 20
        ;  a bunch of doing stuff in here based in $iSeq value
        MsgBox(0, "Sequence #", "$iSeq = " & $iSeq)
        For $k = 1 To 10
            If $Advance Then
                $Advance -= 1
                ContinueLoop 2 ;skip to "For $iSeq"
            EndIf
            Sleep(200)
        Next
    Next
EndFunc   ;==>MainScript

Func Advance()
    $Advance += 1
EndFunc   ;==>Advance

Normally the loop runs every 2 secs (10*200msecs). If "Advance" hit, the timing loop ($k counter) is broken and the script returns to the "For $iSeq" loop. $iSeq is incremented and the timing loop starts again (to be interrupted by the next "Advance" if applied).

Edited by JohnSAutoIt

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0