Checking that array doesn't contain negative numbers, and running function again if it does
Question: My task today is to create a way for checking if a function's output contains
negative numbers, and if it does, then I must run the function until it
contains no negative numbers.

I'll post the full code later in the post, but this is my attempt at a
solution:

    
    
    def evecs(matrixTranspose):
         evectors = numpy.linalg.eig(matrixTranspose)[1][:,0]
         return evectors
    
    
    if any(x<0 for x in evectors) == False:
        print(evectors)
    

evecs() is my function, and evectors is the output array, but I only want to
print evectors if there are no negative entries in it. I also want to later
add that if there _are_ negative entries in it, the code should run the evecs
function again until it finds an evectors that has no negative entries.

However, whenever I run it I get the error:

> global name evectors is not defined

Here's a link to my code, and the full output from the iPython console.
<http://pastebin.com/3Bk9h1gq>

Thanks!


Answer: You have not declared the variable `evectors` other than within the scope of
your function `evecs`.

    
    
    evectors = evecs(matrixTranspose)
    
    if any(x<0 for x in evectors) == False:
        print(evectors)
    

**EDIT**

There are several issues:

  1. Indentation is VERY important in Python. `MarkovChain` and `evecs` are two seperate functions. You had your `evacs` function indented an extra level in, embeddeding it within `MarkovChain`. 

  2. `MarkovChain` should return `matrixTransponse` if you plan to use it in another function call. 

  3. As a result of the above issue, your function call to `MarkovChain` needs to be assigned to a variable, `matrixTranponse`, otherwise you will get an error stating that `matrixTranspose` is not defined when you make your function call to `evecs` with it.

  4. Since the initialization of the variable `matrixTranspose` isn't set until the function call to `MarkovChain` is completed, the remainder of your logic will need to be re-ordered.

I have applied all the above changes below and added comments to the changed
areas:

    
    
    def MarkovChain(n,s) :
        """
    
        """
        matrix = []
        for l in range(n) :
            lineLst = []
            sum = 0
            crtPrec = precision
            for i in range(n-1) :
                val = random.randrange(crtPrec)
                sum += val
                lineLst.append(float(val)/precision)
                crtPrec -= val
            lineLst.append(float(precision - sum)/precision)
            matrix2 = matrix.append(lineLst)
        print("The intial probability matrix.")    
        print(tabulate(matrix))
        matrix_n = numpy.linalg.matrix_power(matrix, s)  
        print("The final probability matrix.")
        print(tabulate(matrix_n))
        matrixTranspose = zip(*matrix_n)
    
        return matrixTransponse    # issue 2
    
    # issue 1
    def evecs(matrixTranspose):
        evectors = numpy.linalg.eig(matrixTranspose)[1][:,0]
        return evectors
    
    matrixTranponse = MarkovChain(4, 10000000000)     # issue 3
    
    # issue 4
    evectors = evecs(matrixTranspose)
    
    if any(x<0 for x in evectors) == False:
        print(evectors)
    

