3
\$\begingroup\$

I've tagged this as homework because it was originally a school project, it was accepted but I'm not satisfied with the code.

I've used cramers rule to find the intersection of 3 lines in three dimensional space given the x, y and z coefficients but the code is hideous.

def trinomial():

       print "Trinomials require 3 equations with three variables each."
       firstX = input ("Please enter the coeficcient of X in the first equation: ")
       firstY = input ("Please enter the coefficient of Y in the first equation: ")
       firstZ = input ("Please enter the coefficient of Z in the first equation: ")
       firstA = input ("and what's after the = sign?")
       secondX = input ("Please enter the coefficient of X in the second equation: ")
       secondY = input ("Please enter the coefficient of Y in the second equation: ")
       secondZ = input ("Please enter the coefficient of Z in the second equation: ")
       secondA = input ("And what's after the = sign?")
       thirdX = input ("Please enter the coefficient of X in the third equation: ")
       thirdY = input ("Please enter the coefficient of Y in the third equation: ")
       thirdZ = input ("Please enter the coefficient of Z in the third equation: ")
       thirdA = input ("And what's after the = sign?")
       D= firstX*secondY*thirdZ+firstY*secondZ*thirdX+firstZ*secondX*thirdY-thirdX*secondY*firstZ-  thirdY*secondZ*firstX-thirdZ*secondX*firstY
       DX = firstA*secondY*thirdZ+firstY*secondZ*thirdA+firstZ*secondA*thirdY-thirdA*secondY*firstZ-thirdY*secondZ*firstA-thirdZ*secondA*firstY
       DY = firstX*secondA*thirdZ+firstA*secondZ*thirdX+firstZ*secondX*thirdA-thirdX*secondA*firstZ-thirdA*secondZ*firstX-thirdZ*secondX*firstA
       DZ = firstX*secondY*thirdA+firstY*secondA*thirdX+firstA*secondX*thirdY-thirdX*secondY*firstA-thirdY*secondA*firstX-thirdA*secondX*firstY
       #the next two if statements evaluate the D's, or determinants, to see if it's an inconsistant or identical systerm
       #if it's not, then it does the math to solve the equation
       if D == 0:
           print "Determinant is 0 evaluate for identical or inconsistant systems."
           if DX ==0 and DY == 0 and DZ == 0:
               print "System is dependant, there are infinite solutions"
               print
           else:
               print "System is inconsistant, there are no solutions"
               print
       if D != 0:
           AX = DX/D
           AY = DY/D
           AZ= DZ/D
       print "the solution to the set of equations is ("+str(AX)+","+str(AY)+","+str(AZ)+")."
       print

I'm sorry for the huge wall of text, the code works, and the solutions are correct, I'd just like to know if there's a neater way of doing this.

\$\endgroup\$

migrated from stackoverflow.com Jun 9 '11 at 22:25

This question came from our site for professional and enthusiast programmers.

  • \$\begingroup\$ Definitely there is a cleaner way. This way, it is not extensible to higher numbers without modification. Check out the determinant algorithms using recursion. (See wiki.tcl.tk/11095) \$\endgroup\$ – anirudh4444 Jun 9 '11 at 22:16
  • \$\begingroup\$ is it actually possible to make an inconsistent system in this program? The number of variables = the number of unknowns. \$\endgroup\$ – Winston Ewert Jun 9 '11 at 23:09
4
\$\begingroup\$
  1. Instead of having variables firstX, secondX, thirdX, replace them with a list X
  2. Don't put input and calculations in the same function, separate them
  3. You do:

    if D == 0: some stuff if D != 0: other stuff

use else instead

  1. Your three lines calculating D, DX, DY, DZ are very similar. Make it a function.
  2. The terms being subtractd parallel the ones being added. Extract the pair into a function.

Here is my result:

DEPENDENT = 0
INCONSISTENT = 1
GOOD = 2

def determinant(X, Y, Z):
    def term(x, y, z):
        return X[x]*Y[y]*Z[z] - X[z]*Y[y]*Z[z]
    return term(0, 1, 2) + term(2, 0, 1) + term(1,2,0)

def trinomial(X, Y, Z, A):

    D  = determinant(X, Y, Z)
    DX = determinant(A, Y, Z)
    DY = determinant(X, A, Z)
    DZ = determinant(X, Y, A)
#the next two if statements evaluate the D's, or determinants, to see if it's an inconsistant or identical systerm
#if it's not, then it does the math to solve the equation
    if D == 0:
       if DX == 0 and DY == 0 and DZ == 0:
           return DEPENDENT, None
       else:
           return INCONSISTENT, None
    else:
       return GOOD, [DX/D, DY/D, DZ/D]


def main():
    print "Trinomials require 3 equations with three variables each."
    X.append( input ("Please enter the coeficcient of X in the first equation: ") )
    Y.append( input ("Please enter the coefficient of Y in the first equation: ") )
    Z.append( input ("Please enter the coefficient of Z in the first equation: ") )
    A.append( = input ("and what's after the = sign?") )

    X.append( input ("Please enter the coeficcient of X in the second equation: ") )
    Y.append( input ("Please enter the coefficient of Y in the second equation: ") )
    Z.append( input ("Please enter the coefficient of Z in the second equation: ") )
    A.append( = input ("and what's after the = sign?") )

    X.append( input ("Please enter the coeficcient of X in the third equation: ") )
    Y.append( input ("Please enter the coefficient of Y in the third equation: ") )
    Z.append( input ("Please enter the coefficient of Z in the third equation: ") )
    A.append( = input ("and what's after the = sign?") )

    result, answer = trinomial(X, Y, Z, A)
    if result == DEPENDENT:
        print "System is dependant, there are infinite solutions"
        print
    elif result == INCONSISTENT:
        print "System is inconsistant, there are no solutions"
        print
    else:
        print "the solution to the set of equations is ("+ ",".join(map(str, answer)) + ")."
        print

But if you do any amount of python programming with this stuff you'll want to learn how to use numpy, which make your code:

def trinomial(X, Y, Z, A):
    system = numpy.array([X, Y, Z]).T
    unknowns = numpy.array([A])

    return numpy.linalg.solve(system, unknowns)
\$\endgroup\$
  • 1
    \$\begingroup\$ solve probably has better numerical stability. \$\endgroup\$ – Neil G Jun 14 '11 at 6:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy