Sign in to follow this  
Followers 0
Angel

How to access a global array of unknown size

5 posts in this topic

Hi,

I am making a small AutoIt example program which calculates the Fibonnacci numbers. To make it faster I am using 2 global arrays to keep track of the numbers that have already been calculated.

My problem comes when I use Global to declare these arrats within the fibonacci function. When I do so, if I check the size (Ubound) of the array, I get a size of 0, even if the arrays have been initialized to a size of 2:

MsgBox(0,"Debug", Fibonacci(10))

Global $vFiboValues[2] = [1, 1]
Global $vFiboIndexes[2] = [0, 1]

; Function to calculate the $n-th Fibonacci number
; First check if the number has been calculated before. Otherwise use a recursion to calculate it,
; then add it to the global list of fibonacci numbers which is used to avoid recalculation. This "list"
; is made out of 2 global arrays, one holding the numbers that have been calculated, the other 
; holding the indexes of those numbers
Func Fibonacci($n)
  Local $newFibo = FindInFibonacciArray($n)
  If $newFibo = False Then
    ; The fibonacci number is unknown, calculate it!
    $newFibo = Fibonacci($n-2) + Fibonacci($n-1)
    ; Add the $newFibo to the fibonacci memory
    ReDim $vFiboValues[UBound($vFiboValues)+1]
    ReDim $vFiboIndexes[UBound($vFiboIndexes)+1]
    $vFiboValues[UBound($vFiboValues)] = $newFibo
    $vFiboIndexes[UBound($vFiboIndexes)] = $n
  EndIf
  Return $newFibo
EndFunc


; This function checks if the $index-th fibonacci number has been previously calculated
; If it has, it simply returns its value. If not, it returns False
Func FindInFibonacciArray($index)
  Global $vFiboIndexes, $vFiboValues
  For $n = 0 To UBound($vFiboIndexes)-1
    MsgBox(0,"Debug",$n & " " & $vFiboIndexes[$n])
    If $index = $vFiboIndexes[$n] Then
      Return $vFiboValues[$n]
    EndIf
  Next
  ; If we get this far, return False to indicate that the $index was not found
  ; Note how we can return a bool or an integer, as the basic AutoIt variable is a VARIANT
  Return False
EndFunc

I know that I can calculate the fibonacci numbers with a For loop. That is not the point. I just want to show that autoIt can use recursion and just show some other features of the language (such as working with arrays, If/Else constructs, function declarations, etc).

So, is there a way to declare a function as global to access it from within a function? I had never tried to do this before (which may say something about how useful my example will be! ;-))

Thanks,

Angel

Share this post


Link to post
Share on other sites



I didn't really run it... The below stood out though:

Func Fibonacci($n)
  Local $newFibo = FindInFibonacciArray($n)
  If $newFibo = False Then
    ; The fibonacci number is unknown, calculate it!
    $newFibo = Fibonacci($n-2) + Fibonacci($n-1)
    ; Add the $newFibo to the fibonacci memory
    ReDim $vFiboValues[UBound($vFiboValues)+1]
    ReDim $vFiboIndexes[UBound($vFiboIndexes)+1]
    $vFiboValues[UBound($vFiboValues)] = $newFibo;You just Redimmed it... and your making the ubound value the $newFibo... you never get to that value... maybe try $vFiboValues[UBound($vFiboValues) - 1] , same for the one below this example
    $vFiboIndexes[UBound($vFiboIndexes)] = $n
  EndIf
  Return $newFibo
EndFunc


[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 didn't really run it... The below stood out though:

Func Fibonacci($n)
  Local $newFibo = FindInFibonacciArray($n)
  If $newFibo = False Then
    ; The fibonacci number is unknown, calculate it!
    $newFibo = Fibonacci($n-2) + Fibonacci($n-1)
    ; Add the $newFibo to the fibonacci memory
    ReDim $vFiboValues[UBound($vFiboValues)+1]
    ReDim $vFiboIndexes[UBound($vFiboIndexes)+1]
    $vFiboValues[UBound($vFiboValues)] = $newFibo;You just Redimmed it... and your making the ubound value the $newFibo... you never get to that value... maybe try $vFiboValues[UBound($vFiboValues) - 1] , same for the one below this example
    $vFiboIndexes[UBound($vFiboIndexes)] = $n
  EndIf
  Return $newFibo
EndFunc
Nice catch. Actually I didn't see that because there is a problem even before that. When FindInFibonacciArray is called, when the Global arrays are declared, their sizes are 0!

So how can I make reference to a global array without knowing its size?

Angel

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

You are calling the function before the globals are even declared. :P

Global $vFiboValues[2] = [1, 1]
Global $vFiboIndexes[2] = [0, 1]

MsgBox(0,"Debug", Fibonacci(10)) ;; moved after globals


; Function to calculate the $n-th Fibonacci number
; First check if the number has been calculated before. Otherwise use a recursion to calculate it,
; then add it to the global list of fibonacci numbers which is used to avoid recalculation. This "list"
; is made out of 2 global arrays, one holding the numbers that have been calculated, the other
; holding the indexes of those numbers
Func Fibonacci($n)
  Local $newFibo = FindInFibonacciArray($n)
  If $newFibo = False Then
    ; The fibonacci number is unknown, calculate it!
    $newFibo = Fibonacci($n-2) + Fibonacci($n-1)
    ; Add the $newFibo to the fibonacci memory
    ReDim $vFiboValues[UBound($vFiboValues)+1]
    ReDim $vFiboIndexes[UBound($vFiboIndexes)+1]
    $vFiboValues[UBound($vFiboValues)-1] = $newFibo 
    $vFiboIndexes[UBound($vFiboIndexes)-1] = $n
  EndIf
  Return $newFibo
EndFunc


; This function checks if the $index-th fibonacci number has been previously calculated
; If it has, it simply returns its value. If not, it returns False
Func FindInFibonacciArray($index)
  For $n = 0 To UBound($vFiboIndexes)-1
    MsgBox(0,"Debug",$n & " " & $vFiboIndexes[$n])
    If $index = $vFiboIndexes[$n] Then
      Return $vFiboValues[$n]
    EndIf
  Next
  ; If we get this far, return False to indicate that the $index was not found
  ; Note how we can return a bool or an integer, as the basic AutoIt variable is a VARIANT
  Return False
EndFunc

Changes:

1. MsgBox() moved

2. Ubound() to Ubound()-1 (as smoke said)

3. Removed Globals in FindInFibonacciArray()

Edited by Grineyfase

Share this post


Link to post
Share on other sites

You are calling the function before the globals are even declared. :P

Wow! That is a silly mistake! I was getting an error saying that the globals where being used before being declared and instead of looking at the obvious thing, I thought that I had to declare the globals inside the function as well, and then I did not understand what syntax should I use for that (which should have made me think back and realize my original mistake)...

Thanks a lot for your help! :-)

Angel

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