import logging

logger = logging.getLogger(__name__)

# Global variable to lookup computed Fibonnaci numbers.
fibs = [0, 1]

def fib_lookup(idx):
    """Compute Fibonacci number, looked up from an array.

    Parameters
    ----------
    idx : int
        Index of Fibonacci number, >= 0.

    Returns
    -------
    fn : int
        Fibonacci number at given index.
    
    Notes
    -----
    From [1]_: 
    F_n = F_n-1 + F_n-2
    Time complexity is O(1) for in-memory lookup.
    Space complexity is O(phi^n), where phi is golden ratio, ~1.6.
    
    References
    ----------
    .. [1] http://en.wikipedia.org/wiki/Fibonacci_number

    """
    if len(fibs) - 1 < idx:
        if not idx > 1:
            raise AssertionError(("Program error. Global `fibs` array must\n" +
                                  "contain at least [0, 1]:\n" +
                                  "fibs = {fibs}").format(fibs=fibs))
        # Note: Lookup F_n-1 before F_n-2 to ensure `fibs` array is filled
        # sequentially (densly with respect to index).
        fn = fib_lookup(idx-1) + fib_lookup(idx-2)
        fibs.append(fn)
    else:
        fn = fibs[idx]
    logger.debug(("F{idx} = {fn}").format(idx=idx, fn=fn))
    logger.debug(("fibs = {fibs}").format(fibs=fibs))
    return fn


def fib_recur(idx):
    """Compute Fibonacci number, recursively.

    Parameters
    ----------
    idx : int
         Index of Fibonacci number, >= 0.

    Returns
    -------
    fn : int
        Fibonacci number at given index.

    Notes
    -----
    From [1]_: 
    F_n = F_n-1 + F_n-2
    Time complexity is O(phi^n), where phi is golden ratio, ~1.6.
    Space complexity is O(2), for 2 ints.
    
    References
    ----------
    .. [1] http://en.wikipedia.org/wiki/Fibonacci_number

    """
    if idx == 0:
        fn = 0
    elif idx == 1:
        fn = 1
    elif idx > 1:
        fn = fib_recur(idx-1) + fib_recur(idx-2)
    logger.debug(("F{idx} = {fn}").format(idx=idx, fn=fn))
    return fn

@@ -107,16 +107,65 @@
 rs.%0A
+# Using a class requires extra code maintenance.%0A
 fibs = %5B
 0, 1
@@ -160,20 +160,16 @@
 fibs = %5B
-0, 1
 %5D%0A%0Adef f
@@ -698,401 +698,494 @@
     
-if len(fibs) - 1 %3C idx:%0A        if not idx %3E 1:%0A            raise AssertionError((%22Program error. Global %60fibs%60 array must%5Cn%22 +%0A                                  %22contain at least %5B0, 1%5D:%5Cn%22 +%0A                                  %22fibs = %7Bfibs%7D%22).format(fibs=fibs))%0A        # Note: Lookup F_n-1 before F_n-2 to ensure %60fibs%60 array is filled%0A        # sequentially (densly with respect to index).%0A
+# Check input.%0A    if not isinstance(idx, int):%0A        idx = int(idx)%0A    if idx %3C 0:%0A        raise ValueError((%22%60idx%60 must be an %60%60int%60%60 %3E= 0:%5Cn%22 +%0A                          %22idx = %7Bidx%7D%22).format(idx=idx))%0A    # Initialize fibs array and compute Fibonacci number.%0A    if len(fibs) %3C 2:%0A        fibs = %5B0, 1%5D%0A    if len(fibs) - 1 %3C idx:%0A        if idx %3E 1:%0A            # Note: Lookup F_n-1 before F_n-2 for easier trace.%0A            # Computations and memory access is equivalent.%0A    
     
@@ -1235,24 +1235,28 @@
 -2)%0A        
+    
 fibs.append(
@@ -1259,16 +1259,194 @@
 end(fn)%0A
+        else:%0A            raise AssertionError((%22Program error. %60fibs%60 must be initialized with %5B0,1%5D:%5Cn%22 +%0A                                  %22fibs = %7Bfibs%7D%22).format(fibs=fibs))%0A
     else
@@ -2109,135 +2109,649 @@
     
-if idx == 0:%0A        fn = 0%0A    elif idx == 1:%0A        fn = 1%0A    elif idx %3E 1:%0A        fn = fib_recur(idx-1) + fib_recur(idx-2
+# Check input.%0A    if not isinstance(idx, int):%0A        idx = int(idx)%0A    if idx %3C 0:%0A        raise ValueError((%22%60idx%60 must be an %60%60int%60%60 %3E= 0:%5Cn%22 +%0A                          %22idx = %7Bidx%7D%22).format(idx=idx))%0A    # Compute Fibonacci number.%0A    if idx == 0:%0A        fn = 0%0A    elif idx == 1:%0A        fn = 1%0A    elif idx %3E 1:%0A        # Note: Lookup F_n-1 before F_n-2 for easier trace.%0A        # Computations and memory access is equivalent.%0A        fn = fib_recur(idx-1) + fib_recur(idx-2)%0A    else:%0A        raise AssertionError((%22Program error. %60idx%60 must be an %60%60int%60%60 %3E= 0:%5Cn%22 +%0A                              %22idx = %7Bidx%7D%22).format(idx=idx)
 )%0A  

initialize fibs as needed