TheRauchster101 Posted July 31, 2011 Share Posted July 31, 2011 After creating a large program, I'm getting a recursion level exceeded error. I know that this means I have a logical loop in the function, but the line that it's giving me the error for doesn't make sense: If $BCPixelCheck1 = 0 AND $BCPixelCheck2 = 0 AND $BCPixelCheck3 = 0 Then I was wondering how to implement a some sort of trace into the program to see where the code is actually looping, and method's to bypass it, as I want it to loop if certain circumstances are met. Link to comment Share on other sites More sharing options...
Developers Jos Posted July 31, 2011 Developers Share Posted July 31, 2011 (edited) After creating a large program, I'm getting a recursion level exceeded error. I know that this means I have a logical loop in the function, but the line that it's giving me the error for doesn't make sense: If $BCPixelCheck1 = 0 AND $BCPixelCheck2 = 0 AND $BCPixelCheck3 = 0 Then I was wondering how to implement a some sort of trace into the program to see where the code is actually looping, and method's to bypass it, as I want it to loop if certain circumstances are met. Its not this code that will give that error. It has to be the call to an internal Function (FUNC). Jos Edited July 31, 2011 by Jos SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
jvanegmond Posted July 31, 2011 Share Posted July 31, 2011 Like Jos said, this gives a recursion exceeded error: Hi() Func Hi() Hi() EndFunc Recursion like this is tricky and you can only use it if you know the limits of what you are trying to implement. If your loop can occur once every 1-1000 times, then recursion is fine. If your loop can be called anywhere between 1 and 1 billion, but probably/maybe only just between 1-1000, then recursion will probably fail you eventually. In many cases, recursion is a nice solution to a recursive problem. But even more cases, recursion is used inappropriately. github.com/jvanegmond Link to comment Share on other sites More sharing options...
TheRauchster101 Posted July 31, 2011 Author Share Posted July 31, 2011 Like Jos said, this gives a recursion exceeded error: Hi() Func Hi() Hi() EndFunc Recursion like this is tricky and you can only use it if you know the limits of what you are trying to implement. If your loop can occur once every 1-1000 times, then recursion is fine. If your loop can be called anywhere between 1 and 1 billion, but probably/maybe only just between 1-1000, then recursion will probably fail you eventually. In many cases, recursion is a nice solution to a recursive problem. But even more cases, recursion is used inappropriately. Thanks for the responses. The line I quoted is the line error that it gave me in the error message box. Is there a way to trace where the recursive error is coming from. That particular PixelCheck I have limited to only run once every 5 seconds for 300 seconds total, which is why having the error code there doesn't make sense. Link to comment Share on other sites More sharing options...
jvanegmond Posted July 31, 2011 Share Posted July 31, 2011 Thanks for the responses. The line I quoted is the line error that it gave me in the error message box. Is there a way to trace where the recursive error is coming from. That particular PixelCheck I have limited to only run once every 5 seconds for 300 seconds total, which is why having the error code there doesn't make sense. A loop of PixelCheck does not sound like a recursive problem, so I'm curious why you opted for a recursive solution. A rewrite of code like: Hi() Func Hi() Hi() EndFunc into this is the best solution, because you'll never have to worry about recursion limits ever again. While 1 Hi() WEnd Func Hi() EndFunc As for tracing, etc., you'll have to write debug-level logging in your program (ConsoleWrite) or maybe a debugger like: . The easiest solution is probably take a very close look at your code. On another note, this also causes recursion limits: A() Func A() B() EndFunc Func B() A() EndFunc Add Func C, Func D, Func E, etc. as necessary. github.com/jvanegmond Link to comment Share on other sites More sharing options...
TheRauchster101 Posted July 31, 2011 Author Share Posted July 31, 2011 (edited) A loop of PixelCheck does not sound like a recursive problem, so I'm curious why you opted for a recursive solution. A rewrite of code like: Hi() Func Hi() Hi() EndFunc into this is the best solution, because you'll never have to worry about recursion limits ever again. While 1 Hi() WEnd Func Hi() EndFunc As for tracing, etc., you'll have to write debug-level logging in your program (ConsoleWrite) or maybe a debugger like: . The easiest solution is probably take a very close look at your code. On another note, this also causes recursion limits: A() Func A() B() EndFunc Func B() A() EndFunc Add Func C, Func D, Func E, etc. as necessary. Well, the pixelcheck isn't a recursive problem, but I don't know that many other ways around writing it. I'll admit I'm still a beginner level coder. While my coding can impressed the uninformed, to an expert I'm sure it'll look like child's play. I do want the program to loop if certain conditions are met, and I guess that is the problem. It functions fine for upwards of 3-4 hours. But extensive periods of use have always resulted in this error. If someone is willing to look at my code and let me know of another solution for writing it, I'd be happy to learn from a pro. It's far too big to paste into here. Here's a snippet of the code where the error seems to appear most frequently, though. Func 1() If $XCounter > 0 Then Sleep($XTime) $XCounter = $XCounter - 1 $PixelCheck1 = PixelGetColor($PixelCheck1X,$BCPixelCheck1Y) $PixelCheck2 = PixelGetColor($PixelCheck2X,$BCPixelCheck2Y) $PixelCheck3 = PixelGetColor($PixelCheck3X,$BCPixelCheck3Y) If $PixelCheck1 = 0 AND $PixelCheck2 = 0 AND $PixelCheck3 = 0 Then $XCounter = 36 Call("2") Else Call("1") EndIf Else $XCounter = 36 Call("Error") Call("Forfeit") Call("Exit") EndIf EndFunc Functions and variables are renamed, but you get the idea. And yes eventually the "2" function will loop through about 20 other functions then end back up at "1". Edited July 31, 2011 by TheRauchster101 Link to comment Share on other sites More sharing options...
UEZ Posted July 31, 2011 Share Posted July 31, 2011 (edited) The term recursion is for me something like this:MsgBox(0, "Fibonacci Numer", Fibonacci_r(10)) Func Fibonacci_r($f) If $f < 2 Then Return $f Return Fibonacci_r($f - 1) + Fibonacci_r($f - 2) EndFuncEach recursion function needs a termination condition otherwise the recursion stack will overflow.Here If $f < 2 Then Return $f is the termination condition.Br,UEZ Edited July 31, 2011 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
BrewManNH Posted July 31, 2011 Share Posted July 31, 2011 Your recursion problem is here: Else Call("1") EndIf Your If ... else statement calls the Function 1() inside itself if it doesn't find the pixel color you're looking for. It's probably not finding the colors over and over again and eventually the recursion level is reached. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
TheRauchster101 Posted July 31, 2011 Author Share Posted July 31, 2011 Your recursion problem is here: Else Call("1") EndIf Your If ... else statement calls the Function 1() inside itself if it doesn't find the pixel color you're looking for. It's probably not finding the colors over and over again and eventually the recursion level is reached. That why I put in the $XCounter - which is a Variable set at 36. The timer is set at 5000 (5 seconds) so that after 3 minutes (3 min = 180 seconds = 36*5). Each time it runs through and fails the pixel check, it should subtract one from the $XCounter. Once the $Xcounter hits 0 - It calls the error and exit functions. So, while there is a loop, it's not infinite. Should only happen for those 3 minutes. That was my intent in that section anyway. Have I done something wrong? Link to comment Share on other sites More sharing options...
BrewManNH Posted July 31, 2011 Share Posted July 31, 2011 It appears to work correctly, unless somewhere else you're calling the function 1() and not returning from it correctly. Or, you're resetting the $Xcounter variable somewhere else. This part appears to be coded so that you'll avoid the recursion level from being reached, but it's not the right way to do it because you're not ending the Function and returning from it to unwind the recursion. I'm guessing that the other functions you're calling aren't returning correctly either, but have no way to verify this without more code. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
TheRauchster101 Posted July 31, 2011 Author Share Posted July 31, 2011 It appears to work correctly, unless somewhere else you're calling the function 1() and not returning from it correctly. Or, you're resetting the $Xcounter variable somewhere else. This part appears to be coded so that you'll avoid the recursion level from being reached, but it's not the right way to do it because you're not ending the Function and returning from it to unwind the recursion. I'm guessing that the other functions you're calling aren't returning correctly either, but have no way to verify this without more code.Well, I can send the entire code to a person if they want to look it over, but I doubt the entire thing would fit in a forum post here, as it's well over 25000 characters and nearly 900 lines. Link to comment Share on other sites More sharing options...
TheRauchster101 Posted August 29, 2011 Author Share Posted August 29, 2011 (edited) Alrighty, it's been a while since I looked at this, and while I have a bit more knowledge in the AutoIT language now, I'm still getting stuck with the recursion error. After reviewing the code, I removed all occurrences of any Func calling itself, and it is still giving me recursion errors at random time periods.I believe it's as Manadal says:On another note, this also causes recursion limits: A() Func A() B() EndFunc Func B() A() EndFunc Obviously way more complex than that, as I actually have about 50 different functions called, but the overall effect generated is a loop. So, my question is, how do I break the loop and return to the main part of the script, then re-activate the start of the loop? I have a counter built in already that counts the number of full complete loops the program has made, ingeniously named $Counter. Since the recursion error seems to happen after 250+ repeats, I can make the script stop at 200, but have no clue how to make it re-launch itself so that it can keep going. And, are there other sites beyond the AutoIT forums that work with this sort of stuff? I'm willing to learn, but I'm struggling with some concepts. Like Return is one that I get but don't get at the same time. Edited August 29, 2011 by TheRauchster101 Link to comment Share on other sites More sharing options...
BrewManNH Posted August 29, 2011 Share Posted August 29, 2011 (edited) You would do it this way: While 1 A() Wend Func A() ; do something here B() EndFunc Func B() ; do something else here EndFunc This is only one way of doing it. The While...Wend loop will constantly call the A() function, the A() function will call B(), B() will return to A() when it's done, A() will finish doing what it needs and then returns back to the loop which will then loop around and call A() again. No recursions will happen because the functions are ending normally and not calling each other. This is just a simplistic demo of how to do something like this. Edit: correcting the new board code screwups with code tags. Edited August 29, 2011 by BrewManNH If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
TheRauchster101 Posted August 29, 2011 Author Share Posted August 29, 2011 (edited) Alrighty, that makes sense. However, a quick monkey wrench being thrown in is that the script is activated by a HotKeySet, which calls a function that starts the entire thing. I.E: HotKeySet("{INS}", "Start") Where Start calls everything else, and eventually loops back to Start. Edited August 29, 2011 by TheRauchster101 Link to comment Share on other sites More sharing options...
BrewManNH Posted August 29, 2011 Share Posted August 29, 2011 (edited) Func Start() While $Counter < 1000 A() Wend endfunc Edited August 29, 2011 by BrewManNH If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
TheRauchster101 Posted August 29, 2011 Author Share Posted August 29, 2011 Func Start() While $Counter < 1000 A() Wend endfunc Awesome. I will give it a try and let you know. If it works, is there a thanks or rep button I can click to +1 you? Link to comment Share on other sites More sharing options...
TheRauchster101 Posted August 29, 2011 Author Share Posted August 29, 2011 Alrighty.... I've rewritten the code to look like this. HotKeySet("{INS}", "First") Func First() While $RunCounter<5 If $Starting=True Then $Starting=False Call("Start") ElseIf $Starting=False Then Call("Launch") EndIf WEnd EndFunc Since I only want Start to run once, and Launch is the real looping point. I removed all references to Launch being called from any function as well, just to make sure that it can't loop outside of the While.But what I don't understand is this.Shouldn't that snippet of code END once $RunCounter is 5?Because I just tested it, and it's still going at $RunCounter = 10.... Obviously I don't understand something.I'm not complaining as I actually WANT it to keep looping.But I like to understand my script too. Link to comment Share on other sites More sharing options...
MvGulik Posted August 29, 2011 Share Posted August 29, 2011 (edited) Shouldn't that snippet of code END once $RunCounter is 5?Not according to the actual data that's in that snippet. (No $RunCounter += 1 code)But if $RunCounter is a Global variable, and its increased somewhere in the called code ... Yep.Suggest you try dropping some ConsoleWrite()'s to see what actually happens. (Code flow and/or variable content changes.) Edited August 29, 2011 by iEvKI3gv9Wrkd41u "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ... Link to comment Share on other sites More sharing options...
TheRauchster101 Posted August 29, 2011 Author Share Posted August 29, 2011 (edited) Not according to the actual data that's in that snippet. (No $RunCounter += 1 code)But if $RunCounter is a Global variable, and its increased somewhere in the called code ... Yep.Suggest you try dropping some ConsoleWrite()'s to see what actually happens. (Code flow and/or variable content changes.) I actually have it written longhand as:$RunCounter=$RunCounter+1Later on in the script, under a different call function.But yes, the $RunCounter is increasing with each consecutive run like it should.And yet again, this is still going on another test run where $RunCounter is currently at 7. --EDIT--Alrighty, I figured out why that was doing what it was doing. I had made a change in a #included script too, but hadn't saved it when I compiled the main file.So now it's stopped when $RunCounter = 5. So, now the question is. How do I automatically restart it without user input? Edited August 29, 2011 by TheRauchster101 Link to comment Share on other sites More sharing options...
MvGulik Posted August 29, 2011 Share Posted August 29, 2011 I had made a change in a #included script too, but hadn't saved it when I compiled the main file.Just in case, Optional Scite setting: save.all.for.build=1 So, now the question is. How do I automatically restart it without user input?mmm, Think in that case your better of by not directly calling that function from a HotKeySet() call. Alternative example: global $HK_fIns = false HotKeySet("{INS}", "_HK_INS") func _HK_INS() $HK_fIns = true endfunc func wait() ;; some loop if $HK_fIns then $HK_fIns = false ;; do this endif ;; some other code. endfunc "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ... Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now