Sign in to follow this  
Followers 0
ojef1

Recursion/Stack overflow error

16 posts in this topic

This is a portion of code I'm using to delay my script until the color of a certain field changes

Func loadTime($left, $top, $right, $bottom, $color)

$loadTimePix = PixelSearch($left, $top, $right, $bottom, $color)

If @error Then ;color not found yet

sleep(100 + $delay/10)

loadTime($left, $top, $right, $bottom, $color)

ElseIf Not @error Then ;color found

sleep(200) ;extra buffer time

Return

EndIf

EndFunc

Does anyone know how long it would take before I would get a recursion/stack overflow error?

and if it doesn't take much time (less than about 30 seconds) before failing how can I make it break out and give an error code of my own?

Thanks

Share this post


Link to post
Share on other sites



sorry i just now figured out how to post the code snippet properly

Func loadTime($left, $top, $right, $bottom, $color)
    $loadTimePix = PixelSearch($left, $top, $right, $bottom, $color)
    If @error Then    ;color not found yet
        sleep(100 + $delay/10)
        loadTime($left, $top, $right, $bottom, $color)
    ElseIf Not @error Then    ;color found
        sleep(200)  ;extra buffer time
        Return
    EndIf
EndFunc

Share this post


Link to post
Share on other sites

That logic makes no sense at all. Why are you calling your function recursively at all? All you need is a simple loop:

Func loadTime($left, $top, $right, $bottom, $color)
    While 1
        $loadTimePix = PixelSearch($left, $top, $right, $bottom, $color)
        If @error Then
            ; color not found yet
            Sleep(100 + $delay / 10)
        ElseIf Not @error Then
            ; color found
            Sleep(200)
            Return
        EndIf
    WEnd
EndFunc   ;==>loadTime

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Thanks for the reply....I just went with the first way I could think to do it. I trust that that will work even though it doesn't seem intuitive to me (I'm new to this). The way I'm recursively calling it has worked fine so far but I'm just nervous about how long it is capable of running before getting a stack overflow error. I assume you recommend doing it this way...would this format be more efficient in terms of memory usage?

Share this post


Link to post
Share on other sites

I see what you did now that makes a lot of sense I'll definitely use that instead...but I'm still not sure how long it is capable of staying in that loop? It seems like there shouldn't be a limit. I haven't duplicated the recursion error in awhile but I know that it has happened before. Possibly unrelated?

Share this post


Link to post
Share on other sites

Recursion (as defined by a function calling itself) is risky, complicated, and error prone. It can be done, and it can be useful, but should only be employed after less-risky, simpler, and easier to maintain methods have been explored.

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Ok I understand now, that parts working like a charm now thanks for the help

Share this post


Link to post
Share on other sites

I realise PsaltyDS explained the problem and you understand as well, but Melba23 did a great Wiki entry on the subject too >> http://www.autoitscript.com/wiki/Recursion


_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Hi,

I have been running a script with an infinite recursive loop for a while now and I had several Overflow error messages.

I read this thread and understood what this was about and I simply want to ask something concerning my overflow code :

Func sauvegarde7 ()
   $Search = _ImageSearchArea('screen1.png', 1, 1680, 218, 1760, 280, $x8, $y8, 75)
   If $Search = 1 Then
      sleep(200)
Sauvegarde8 ()
Else
   sleep(500)
   sauvegarde7 ()
   EndIf
EndFunc

sauvegarde7 ()

My script basicly makes a long saving data process (every day) and it uses imagesearch to validate another keypoint in this process.

Ie the save process include many "Ok" windows which just confirm 1 part has been terminated successfully and another should begin and I use ImgSearch to detect the Ok window.

However if an incident occurs there will be no OK and it will overloop with overflow window. I read the excellent wiki pages and I want to ask this :

IF i add this part from wiki in my function :

$i += 1
 
     If $i = 100 Then Return

1. If i replace 100 by XX number, will the function run XX times before it gets canceled ? This would be incredible.

2. Should i define the variable i locally or globally ?

Consider this code : 

Func sauvegarde8 ()
   $Search = _ImageSearchArea('screen2.png', 1, 1680, 218, 1760, 280, $x8, $y8, 75)
   If $Search = 1 Then
      sleep(200)
sauvegarde7 ()
Else
   sleep(500)
   sauvegarde8 ()
   EndIf
EndFunc


Func sauvegarde7 ()
   $Search = _ImageSearchArea('screen1.png', 1, 1680, 218, 1760, 280, $x8, $y8, 75)
   If $Search = 1 Then
      sleep(200)
sauvegarde8 ()
Else
   sleep(500)
   sauvegarde7 ()
   EndIf
EndFunc

Sauvegarde7 () 

3. If i understood properly when autoit goes from function savegarde 7 to 8 and vice versa it deletes the past version from cache, avoiding overflow ?

So even tho Autoit keeps running for a long time he is able to clean his cache and do the job as long as it doesn't stay in the same function for a long time ?

Thanks!

Edited by Ulysse31

Share this post


Link to post
Share on other sites

Several things. Firstly: don't bump a four year old thread like this: next time start a new topic. Secondly: there is no need to use recursion at all for this. Thirdly: why are you using image search instead of waiting for the window to appear?

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

1. Ok.

2. I guess you're right, I am inexperienced with this and this kind of recursion is the first way the script came to my mind with.

3. If i wait for the window to appear I need to set a Sleep(xxxx) command that will be long enough so that I am 100% sure the process finished.

But some days depending on data and other applications currently opened and so on, some days the process is significantly longer than other days, ImageSearch is great in this case because it allows the script to pass check points "as soon as" each process is finished.

If i use a sleep time that for every process is long enough so that I know it's finished, the script running time might end up being 4 times longer than it is now, I guess.

We have many, many process, this is running for a small drugstore in Paris and we need to send the doctor prescriptions to our health care system, we need to sync many things including mail (I guess the weight in MB is not big, but it takes some time (probably poorly optimised)), in total there are about 8 different process that can only be launched one after another, it ends with some virtual printings etc.

If for 3. you intended another way than sleep(xxxx) (or merely a better way), then i simply did not think of it, yet.

I did not know anything about scripts 1 month ago and there are so many functions in autoit that I simply do not know half of 1% of what this can do :/

However right now what would occupy a member of the staff 30 mins per day is done by 1 double click. Sometimes something pops up, the imagesearch fails and there is an overflow but I think I can work around that with the information i found on this thread.

Edited by Ulysse31

Share this post


Link to post
Share on other sites

Okay, I have to attend to something myself right now. Here are my suggestions. Take a look at the following functions in the help file. WinWait, WinWaiActive, While...WEnd (loop can be infinite), Do...Until, ControlClick. Try to see if you can make use of any of these functions. If you have problems with understanding something in the help file ask, perhaps start a new topic.

Share this post


Link to post
Share on other sites

Alright, thanks, i had checked a few of them already but i didn't know not of Do...Until which seems great ! 

Also only this question remains if anyone reading this can answer it :

Func sauvegarde8 ()
   $Search = _ImageSearchArea('screen2.png', 1, 1680, 218, 1760, 280, $x8, $y8, 75)
   If $Search = 1 Then
      sleep(200)
sauvegarde7 ()
Else
   sleep(500)
   sauvegarde8 ()
   EndIf
EndFunc


Func sauvegarde7 ()
   $Search = _ImageSearchArea('screen1.png', 1, 1680, 218, 1760, 280, $x8, $y8, 75)
   If $Search = 1 Then
      sleep(200)
sauvegarde8 ()
Else
   sleep(500)
   sauvegarde7 ()
   EndIf
EndFunc

Sauvegarde7 ()

"3. If i understood properly when autoit goes from function savegarde 7 to 8 and vice versa it deletes the past version from cache, avoiding overflow ?

So even tho Autoit keeps running for a long time he is able to clean his cache and do the job as long as it doesn't stay in the same function for a long time ?"

(I read the wiki page and from my understanding when autoit leaves 7 to 8 it cleans 7 and vice versa.. but i have a doubt)

Thanks!

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

There is absolutly no need for a function, when you only do one action.

While True
    If _ImageSearchArea('screen2.png', 1, 1680, 218, 1760, 280, $x8, $y8, 75) Then
        Sleep(200)
    ElseIf _ImageSearchArea('screen1.png', 1, 1680, 218, 1760, 280, $x8, $y8, 75) Then
        Sleep(200)
    Else
        Sleep(500)
    EndIf
WEnd



Because a function is not recursivly calling another, no recurssion errors.

Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

I had read the While [number] Wend but I missed the possibility to use "true".

Time to play with all the new toys !

It's really great to  have a free tool like autoit and being able to get help from the community on sites like this one.

Thank you both very much.

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