Sign in to follow this  
Followers 0
malu05

Avoid Recursion level Overflow

13 posts in this topic

#1 ·  Posted (edited)

Hi, im kinda a noob at coding and have sofar only made one finished app for Autoit.

But its like, every scripts i make have Recursion level Overflow error and i do see why.. but i just don't know how to solve it.

I have seen on these forums that you have to close the functions and not let them loop too many times without closing themselves... but i just don't know how to close them without ruining my code.

Eks (note this is just example code i propaly wouldnt work)

dim $mouse = 0
dim $Mpos = 0
dim $attempts = 0
dim $cmdtabel = 0

func Cmdtable()
    Switch $cmdtabel
        Case 0
        Look()
        Case 1
        GetColor()
        Case 2
        Final()
        Case 3
        Terminate()
    EndSwitch
Endfunc


Func Look()
while $mouse = 0 
    Mpos = GetMousePos
        if $mpos > 800
        $mouse = 1
        $cmdtabel = 1
        Cmdtable()
        end if
    $attempts = $attempts + 1
    if $attempts = 10 then
    msgbox Over
    $cmdtabel = 3
    Cmdtable()
    endif
wend
Endfunc

func GetColor()
$Color = getpixelcolor(mouseX, MouseY, 0)
$cmdtabel = 2
Cmdtable()
EndFunc


Func Final()
msgbox(mouseX & mouseY & $Color)
$cmdtabel = 0
Cmdtable()
Endfunc

Func Terminate()
End
Endfunc

So, this is a example of the way i would do it.

I make functions so that i can call them anytime.

But i never close my functions since they loop over and over again.

How do i fix this?

I think my main problem is that i use the functions as a Goto (like in dos batch file commands) command.

I could put most of my code in one function but i think its easier to keep track of the code with these "goto" commands.

Edited by malu05

[center][u]WoW Machinima Tool[/u] (Tool for Machinima Artists) [/center]

Share this post


Link to post
Share on other sites



-Should i just keep it in one function?

-How do i close a function (

i know you close it with endfunc but what happens if you do

dim $run = 0

Func func1()
if $run = 0 then
func2()
endif
endfunc

Func Func2()
$run = 1
Func1()
Endfunc

then i do close the functoion but also the program....


[center][u]WoW Machinima Tool[/u] (Tool for Machinima Artists) [/center]

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I always make sure my functions serve a "specific" purpose individually. If I'm going to use a lot of the same stuff over and over, there is no need to call outside functions when I can just build them into the core itself.

On another note, when your function is supposed to return something (where your's just looks like it's doing "Global" commands), you should look at Return in the help file.

Edited by SmOke_N

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

I always make sure my functions serve a "specific" purpose individually. If I'm going to use a lot of the same stuff over and over, there is no need to call outside functions when I can just build them into the core itself.

On another note, when your function is supposed to return something (where your's just looks like it's doing "Global" commands), you should look at Return in the help file.

Ok thx...

So i should keep all this in one functions enstead of serval?

Can you give me an example of how to close a function without ending the code?


[center][u]WoW Machinima Tool[/u] (Tool for Machinima Artists) [/center]

Share this post


Link to post
Share on other sites

Ok thx...

So i should keep all this in one functions enstead of serval?

Can you give me an example of how to close a function without ending the code?

No idea what you mean by "closing" a function. As I stated, you may want to look at Return in the help file.

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

So, this is a example of the way i would do it.

I make functions so that i can call them anytime.

But i never close my functions since they loop over and over again.

How do i fix this?

I think my main problem is that i use the functions as a Goto (like in dos batch file commands) command.

I could put most of my code in one function but i think its easier to keep track of the code with these "goto" commands.

Your use of recursion is a bug generator mode.

You have functions calling themselves so the code is extremely complicated to understand

I assume your exemple is pseudo-code

if your mouse coordinate is >800 then you have the calling sequence

look() has begun >>> commandTable() >>> getColor() >>> commandTable() >>> Final >>>> commandTable() >>> look() begin once more

and the loop continue with all the look() functions opened creating a stack overflow

Share this post


Link to post
Share on other sites

Is this what you're trying to do?

dim $mouse = 0
dim $Mpos = 0
dim $attempts = 0
dim $cmdtabel = 0

func Cmdtable()
  Switch $cmdtabel
    Case 0
      Look()
    Case 1
      GetColor()
    Case 2
      Final()
    Case 3
      Terminate()
  EndSwitch
Endfunc

Func Look()
while $mouse = 0 
  Mpos = GetMousePos
  if $mpos > 800
    $mouse = 1
    $cmdtabel = 1
    Return
  endif
  $attempts = $attempts + 1
  if $attempts = 10 then
    msgbox Over
    $cmdtabel = 3
    Return
  endif
wend
Endfunc

func GetColor()
  $Color = getpixelcolor(mouseX, MouseY, 0)
  $cmdtabel = 2
EndFunc


Func Final()
  msgbox(mouseX & mouseY & $Color)
  $cmdtabel = 0
Endfunc

Func Terminate()
  Exit
End
Endfunc

Auto3Lib: A library of over 1200 functions for AutoIt

Share this post


Link to post
Share on other sites

Your look funtion has the main test you're willing to do

pseudo-code

Func Look()
while $mouse = 0
    Mpos = GetMousePos
    if $mpos > 800 then
        doThings()
    endif
    $attempts = $attempts + 1
    if $attempts = 10 then
         msgbox Over
         return  ;  this is the End
    endif
    sleep(100) ; just to have the time to move the mouse
wend
Endfunc
 

Func doThings()
   getColor()
   FinalizeThings()
endFunc

Share this post


Link to post
Share on other sites

Thx for all this help!

No idea what you mean by "closing" a function. As I stated, you may want to look at Return in the help file.

I did when you said it first time, but;

"Defines a user-defined function that takes zero or more arguments and optionally returns a result."

My noobism does play a role here as i dont get what it really does.

I do understand that it takes my function that takes zero or more arguents, but the thing that it returns a result?

when i think if return i think of Commandore's way to "Echo (message)".

can you try to clear things out for me?


[center][u]WoW Machinima Tool[/u] (Tool for Machinima Artists) [/center]

Share this post


Link to post
Share on other sites

Thx for all this help!

I did when you said it first time, but;

My noobism does play a role here as i dont get what it really does.

I do understand that it takes my function that takes zero or more arguents, but the thing that it returns a result?

when i think if return i think of Commandore's way to "Echo (message)".

can you try to clear things out for me?

How can I explain it without murdering it :whistle:

It returns an argument ... ie... Return 0 | Return "help" | Return SetError(1, 0, 0) | Return "" | Return | the argument can be whatever you need it to be... but it returns to the original point that it was called from, basically ending that function call, making it ok to call it again.

I don't know how else to explain it really.


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Why would you Return SetError(1, 0, 0)?

Make an infinite while loop instead of calling recursive functions.

Share this post


Link to post
Share on other sites

Why would you Return SetError(1, 0, 0)?

Make an infinite while loop instead of calling recursive functions.

Why not?

Instead of

SetError(1)

Return 0

Plus you get a whole other opportunity to add extended info.


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Hi, im kinda a noob at coding and have sofar only made one finished app for Autoit.

But its like, every scripts i make have Recursion level Overflow error and i do see why.. but i just don't know how to solve it.

But i never close my functions since they loop over and over again.

How do i fix this?

I think my main problem is that i use the functions as a Goto (like in dos batch file commands) command.

I could put most of my code in one function but i think its easier to keep track of the code with these "goto" commands.

Your use of recursion is what I would call a "Moebius bandage" coding practice

It include recursion and "reflexive" calls between 2 functions

VERY DIFFICULT >>> BUG RISKY

Recursion must be used within the function itself like the calculation of factorial(5)=5*4*3*2*1

Caution factorial becomes very large when the number is increasing generating not a stack overflow but a number larger than the variable can contain.

Func factorial($num)
    dim $number
    if $num>1 then
         $number = factorial($num-1)
    else
         $number=1
    endif
    return $num*$number
EndFunc

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