9Algorithm
9Algorithm

Reputation: 1257

How to give a function a value from another function in Python

I have a function that solves a quadratic equation:

class QuadEq(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def solve_quad_eq(self):
        D = self.b**2-4*self.a*self.c
        if D >= 0:
            x1 = (-self.b-math.sqrt(D))/2*self.a
            x2 = (-self.b+math.sqrt(D))/2*self.a
            answer = [x1, x2]
            return answer
        else:
            return 0

And then in the same Class I have function:

 def show_result(self):
    print answer

that to print the answer of the quadratic equation if we need.

How can I give this function the answer list from the function above it to print?

Upvotes: 1

Views: 445

Answers (6)

Sylvain Leroux
Sylvain Leroux

Reputation: 51980

The short answer has already been posted. Use an instance variable (self.answer):

class QuadEq(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def solve_quad_eq(self):
        self.answer = ("this", "that")
        return self.answer

    def show_result(self):
        print self.answer


eq = QuadEq(1,2,3)

eq.solve_quad_eq()
eq.show_result()

Loosely speaking, an instance variable (data member) is just a variable whom lifespan is the same as the one of its "owner" (in the example, the object referenced by eq).


And now, for the long -- and slightly more pedantic - answer: when designing a class, you have to think about its responsibilities and its state. Simply said, what is the purpose of your class? Is it just a container for various more-or-less related functions? In that case, the above answer is perfectly acceptable. But usually, you have to be a little bit more rigorous -- at the very least in order to improve understandability/maintainability of your code.

Here you have a QuadEq class. By its name, I understand an instance of this class models one equation. Since the roots of such an equation are a properties of that equation, I think it is acceptable to have the method solve_quad_eq to be a method of that class. With the slight change I would use the more generic name solve. Why? Because that make provision for future classes for different equations providing the same semantic. In addition, both returning the result and storing it in an instance variable might be confusing. You should make a choice here. Not mentioning the fact your function sometimes returns the roots, other time the number of roots (0).

Now, printing. I am more skeptical about this one. Displaying itself is not a "native" property of an equation. And if you go that way, you'll soon have to deal in your(s) equation class(es) with problems totally unrelated with "equations": how to write in a file? Binary or text? Which encoding should I use? How to deal with I/O errors? and so on...

So, if I were you, I would push toward separation of concern, providing just an "accessor" method to return the roots -- and display them from the outside. Since this seems to be important, I keep here the separation between that accessor and the solve method (potentially computationally intensive for some kinds of equations). Using the instance variable self.answer merely as a cache (memoization)

Here is a full example:

class Eq(object):
    def __init__(self):
        self.answer = None # this should be calles "roots", no?

    def roots(self):
        if self.answer is None:
            self.solve()

        return self.answer

class QuadEq(Eq):
    def __init__(self, a, b, c):
        Eq.__init__(self)

        self.a = a
        self.b = b
        self.c = c

    def solve(self):
        self.answer = ("this", "that")
        return 2

eq = QuadEq(1,2,3)
print(eq.roots())

Please note how easy it is now to add an other kind of equation to solve in the program ...

class OtherEq(Eq):
    def __init__(self, a, b, c):
        Eq.__init__(self)

        self.a = a
        self.b = b
        self.c = c

    def solve(self):
        self.answer = ( "it", )
        return 1

... and more important, the code to use that new kind of equation is almost the same as the previous one:

eq = OtherEq(1,2,3)
print(eq.roots())

Upvotes: 2

suspectus
suspectus

Reputation: 17258

Make the answer a member of the class. and reference it by self.answer.

class QuadEq(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c
        self.answer = []


    def solve_quad_eq(self):
        D = self.b**2-4*self.a*self.c
        if D >= 0:
            x1 = (-self.b-math.sqrt(D))/2*self.a
            x2 = (-self.b+math.sqrt(D))/2*self.a
            self.answer = [x1, x2]
            return self.answer
        else:
            return 0

    def show_result(self):
        print self.answer

Upvotes: 3

Petter TB
Petter TB

Reputation: 147

You could throw an exception if the functions are run in the wrong order:

class QuadEq(object):
def __init__(self, a, b, c):
    self.answer = None

    #Rest of program...

def show_result(self):
    if self.answer is None:
        raise RuntimeError('Error in QuadEq, tried to print result before solving equation')
    print self.answer

Upvotes: 1

freakish
freakish

Reputation: 56467

Store it in the object itself:

class QuadEq(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c
        self.solution = None

    def solve_quad_eq(self):
        if self.solution is None:
            D = self.b**2-4*self.a*self.c
            if D >= 0:
                x1 = (-self.b-math.sqrt(D))/2*self.a
                x2 = (-self.b+math.sqrt(D))/2*self.a
                self.solution = [x1, x2]
            else:
                self.solution = 0
        return self.solution

    def show_result(self): # <--- just an alias to solve_quad_eq
        return self.solve_quad_eq()

Upvotes: 1

Verma
Verma

Reputation: 966

You cannot really; unless you make answer a member of the class like this

class QuadEq(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def solve_quad_eq(self):
        D = self.b**2-4*self.a*self.c
        if D >= 0:
            x1 = (-self.b-math.sqrt(D))/2*self.a
            x2 = (-self.b+math.sqrt(D))/2*self.a
            answer = [x1, x2]
            return answer
        else:
            return 0

    def show_result(self):
        if self.answer is None:
            self.answer =  solve_quad_eq()
        print self.answer

or do something simpler like this...

def show_result(self):
    print self.solve_quad_eq()

Upvotes: 0

vivek
vivek

Reputation: 5219

Keep answer as a member variable.

def solve_quad_eq(self):
    D = self.b**2-4*self.a*self.c
    if D >= 0:
        x1 = (-self.b-math.sqrt(D))/2*self.a
        x2 = (-self.b+math.sqrt(D))/2*self.a
        self.answer = [x1, x2]
        return self.answer
    else:
        return 0

def show_result(self):
    print self.answer

Upvotes: 0

Related Questions