# Struggling To Test My Code For Keywords

``````from sympy import *
import random
lambda1 = Symbol('lambda_i')
kw3 = {"I","*I","I/2","*I/2","*I:","I:","sqrt"}
merror = bool
merror == True
n = random.randrange(2, 3, 1)
def mgenerator():
A = randMatrix(n,n,percent=100,min=0, max=3,symmetric=False)
B = randMatrix(n,n,percent=100,min=0, max=3,symmetric=False)
return (A,B)
mA, mB = mgenerator()
def matrices():
MC = mA*mB
eq55 = Eq(lambda1,(MC).eigenvals())
P, D = MC.diagonalize()
return (MC, eq55, P, D)
def mtest():
mC, mE, mP, mD = matrices()
if mC.is_diagonalizable() and not any(kw in str(mE) for kw in kw3):
merror == False
return merror
else:
mA, mB = mgenerator()
mC, mE, mP, mD = matrices()
return (mA, mB, mC, mE, mP, mD)
while merror == True:
mtest()
if merror == False:
#do stuff
``````

For some reason I am not able to test my code and run the rest of it. I do not want to generate eigenvectors that include any square roots or complex numbers. Right now, one version of the code works but requires me to execute it a few time to generate the whole problem set.

I am getting a headache from trying to understand the difference between static and dynamic generated variables in matrix forms. Passing these variables through defined functions is also mind-boggling.

I am trying to generate static matrices and test them for conditionals. If they fail the test I want to generate new matrices and test them continuously until they pass the test and I can run the rest of my code.

I accomplished working testing functinos for a similar project integrated in the full code which is the calculus problem generator above the linear algebra problem generator.

Working Code
Updating Working Code That Is Currently Broken
As you can see between the two, the lower half is getting revised and condensed with nicer testing but I am struggling to get the outputs I want that don’t include complex numbers or square roots.

This is two independent calls to `mgenerator`, which means that `n` is generated twice and could theoretically be different (but see below). You can unpack the result of a single call with `mA, mB = mgenerator()`

However this is not important right now, because you are generating `n = random.randrange(2, 3, 1)`. Because `randrange` does not include the upper bound (like `range` in general), this will always be 2.

It seems like you might want to review Python syntax, particularly how to unpack tuples.

I temporarily changed from `random.randrange(2, 4, 1)` to `random.randrange(2, 3, 1)`
as a debugging strategy (making it simpler to get the simple right). Eventually I want to generate both 2x2 and 3x3 matrices when I can get the test for 2x2 matrices right.

Exactly what do you expect should happen when these lines of code run?

Probably redundant, but adding `merror = bool` seemed to fix something while coding.

`merror = bool` creates a boolean variable.
`merror == True` specifies the truth value of the boolean variable `merror`

I used `=` for creating the variable and `==` for assigning it a numerical value (1,0) (i.e; True/False).

I will try deleting `merror == True`

No, it assigns the built-in function `bool` to the name `merror`.

No, it tests whether the variable `merror` (which is the function `bool`) is equal to `True`, and does nothing with the result.

This is not how Python works. `==` is a test for equality, it is not assignment.

Maybe it is better to then change `merror == False` to `merror = False` inside `def mtest():`

I will also try deleting `merror = bool` and `merror == True` and replace with `merror = True`

Current code I am working with (trying not to edit OP):

``````from sympy import *
import random
lambda1 = Symbol('lambda_i')
kw3 = {"I","*I","I/2","*I/2","*I:","I:","sqrt"}
merror = True
n = random.randrange(2, 3, 1)
def mgenerator():
A = randMatrix(n,n,percent=100,min=0, max=3,symmetric=False)
B = randMatrix(n,n,percent=100,min=0, max=3,symmetric=False)
return (A,B)
def matrices():
mA, mB = mgenerator()
MC = mA*mB
eq55 = Eq(lambda1,(MC).eigenvals())
if MC.is_diagonalizable():
P, D = MC.diagonalize()
return (MC, eq55, P, D)
def mtest():
mC, mE, mP, mD = matrices()
if mC.is_diagonalizable() and not any(kw in str(mE) for kw in kw3):
merror = False
return merror
else:
mA, mB = mgenerator()
mC, mE, mP, mD = matrices()
return (mA, mB, mC, mE, mP, mD)
while merror == True:
mtest()
print(merror)
if merror == False:
#do stuff
``````

Execution returns:

``````---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_17839/3028806082.py in <module>
186         display(Eq(P1,mP**-1,evaluate=False))
187         display(Eq(Eq(PD*P1,mP*mD*mP**-1,evaluate=False),C,evaluate=False))
--> 188 linear_algebra()
189 print("\n")
190 print("\n")

/tmp/ipykernel_17839/3028806082.py in linear_algebra()
146             return (mA, mB, mC, mE, mP, mD)
147     while merror == True:
--> 148         mtest()
149     print(merror)
150     if merror == False:

/tmp/ipykernel_17839/3028806082.py in mtest()
137             return (MC, eq55, P, D)
138     def mtest():
--> 139         mC, mE, mP, mD = matrices()
140         if mC.is_diagonalizable() and not any(kw in str(mE) for kw in kw3):
141                 merror = False

TypeError: cannot unpack non-iterable NoneType object
``````

Does this mean James’ reply is not a solution since these are `non-iterable NoneType objects`?

Maybe I am messing up in

``````    def matrices():
mA, mB = mgenerator()
MC = mA*mB
eq55 = Eq(lambda1,(MC).eigenvals())
if MC.is_diagonalizable():
P, D = MC.diagonalize()
return (MC, eq55, P, D)
``````

By failing to check if the matrix is diagonalizable. I will try to split the functions up so variables are not created before assignments.

Error free execution with

``````from sympy import *
import random
lambda1 = Symbol('lambda_i')
kw3 = {"I","*I","I/2","*I/2","*I:","I:","sqrt"}
merror = True
n = random.randrange(2, 3, 1)
def mgenerator():
A = randMatrix(n,n,percent=100,min=0, max=3,symmetric=False)
B = randMatrix(n,n,percent=100,min=0, max=3,symmetric=False)
return (A,B)
def matrices():
mA, mB = mgenerator()
MC = mA*mB
eq55 = Eq(lambda1,MC.eigenvals())
if MC.is_diagonalizable():
P, D = MC.diagonalize()
else:
P,D = MC, MC  #placeholder
return mA, mB, P, D
def mtest():
mC, mE, mP, mD = matrices()
if mC.is_diagonalizable() and not any(kw in str(mE) for kw in kw3):
merror = False
return merror
else:
mA, mB = mgenerator()
mC, mE, mP, mD = matrices()
return (mA, mB, mC, mE, mP, mD)
while merror == True:
mtest()
print(merror)
if merror == False:
# do stuff
``````

Still failing to pass the `mtest() ` and generate any outputs, though.

Splitting up functions is a good idea. I would also recommend that if you want to assume that the output of a function has a certain type (e.g. that it is a tuple of a given length), you should make sure that the function always returns that type. If a function completes execution without any return statement, it will return `None`, and this is the error you were seeing.

2 Likes

Making progress.

``````from sympy import *
import random
def linear_algebra():
lambda1 = Symbol('lambda_i')
kw3 = {"I","*I","I/2","*I/2","*I:","I:","sqrt"}
merror = True
n = random.randrange(2, 3, 1)
def Amgen():
A = randMatrix(n,n,percent=100,min=0, max=3,symmetric=False)
return A
def Bmgen():
B = randMatrix(n,n,percent=100,min=0, max=3,symmetric=False)
return B
def diagonalizer():
mA, mB = Amgen(),Bmgen()
C = mA*mB
P,D = [0,0]
eq55 = Eq(lambda1,C.eigenvals())
if C.is_diagonalizable():
P, D = C.diagonalize()
else:
mA, mB = Amgen(),Bmgen()
C = mA*mB
diagonalizer()
eq55 = Eq(lambda1,C.eigenvals())
return P, D,eq55
def mstest():
mE = diagonalizer()
if not any(kw in str(mE) for kw in kw3):
merror = False
return merror
else:
Amgen()
Bmgen()
diagonalizer()
mstest()
#while mtest() == True:
#    mtest()
print(mstest())
if mstest() == False:
# do stuff
print("yay!")
linear_algebra()
``````

returns several different outputs.
`None yay!`

or

`none`

or

`false`

or

`False yay!`

Will try to add a check for type `None` and `none`. Probably something like `if not type(None) or not type(none)`

This outputs either `False yay!` or `None`.

``````from sympy import *
import random
def linear_algebra():
lambda1 = Symbol('lambda_i')
kw3 = {"I","*I","I/2","*I/2","*I:","I:","sqrt"}
merror = True
#n = random.randrange(2, 3, 1)
n = 2
def Amgen():
A = randMatrix(n,n,percent=100,min=0, max=3,symmetric=False)
return A
def Bmgen():
B = randMatrix(n,n,percent=100,min=0, max=3,symmetric=False)
return B
def diagonalizer():
mA, mB = Amgen(),Bmgen()
C = mA*mB
P,D = [0,0]
eq55 = Eq(lambda1,C.eigenvals())
if C.is_diagonalizable():
P, D = C.diagonalize()
else:
mA, mB = Amgen(),Bmgen()
C = mA*mB
diagonalizer()
eq55 = Eq(lambda1,C.eigenvals())
return P, D,eq55
def mstest():
mE = diagonalizer()
if not any(kw in str(mE) for kw in kw3):
merror = False
return merror
else:
Amgen()
Bmgen()
diagonalizer()
mstest()
#while mtest() == True:
#    mtest()
merror2 = mstest()
print(merror2)
if merror2 == False :
# do stuff
print("yay!")

linear_algebra()
``````

This prints some amount of `None`s until a `False, yay!`. Might be a solution.

``````from sympy import *
import random
def linear_algebra():
lambda1 = Symbol('lambda_i')
kw3 = {"I","*I","I/2","*I/2","*I:","I:","sqrt"}
merror = True
#n = random.randrange(2, 3, 1)
n = 2
def Amgen():
A = randMatrix(n,n,percent=100,min=0, max=3,symmetric=False)
return A
def Bmgen():
B = randMatrix(n,n,percent=100,min=0, max=3,symmetric=False)
return B
def diagonalizer():
mA, mB = Amgen(),Bmgen()
C = mA*mB
P,D = [0,0]
eq55 = Eq(lambda1,C.eigenvals())
if C.is_diagonalizable():
P, D = C.diagonalize()
else:
mA, mB = Amgen(),Bmgen()
C = mA*mB
diagonalizer()
eq55 = Eq(lambda1,C.eigenvals())
return P, D,eq55
def mstest():
mE = diagonalizer()
if not any(kw in str(mE) for kw in kw3):
merror = False
return merror
else:
Amgen()
Bmgen()
diagonalizer()
mstest()
#while mtest() == True:
#    mtest()
merror2 = mstest()
print(merror2)
if merror2 == False and type(merror2) != None:
# do stuff
print("yay!")
else:
linear_algebra()
linear_algebra()
``````