Reputation: 1257
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
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
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
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
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
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
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