Welcome, guest | Sign In | My Account | Store | Cart

Quadratic can be used by students for solving quadratic equations ax^2+bx+c a!=0, which are given by the quadratic formula x = -b + SQUARE-ROOT(b^2-4ac)/2a and x = -b - SQUARE-ROOT(b^2-4ac)/2a However,if b^2-4ac is negative the solutions are not real but complex numbers of the form a+bj. Though, both real and complex solutions are called using Quadratic

Python, 104 lines
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
#On the name of ALLAH and may the blessing and peace of Allah 
#be upon the Messenger of Allah Mohamed Salla Allahu Aliahi Wassalam.
#Author : Fouad Teniou
#Date : 05/08/08
#Version : 2.4

import cmath as c
import math as m

################################################################## 
# x**2 = -1 an equation which does not have a solution in the real number field
# i = Square-Root (-1)  < -- > i**2 = -1 made it possible to develop the complex numbers
# of the form a + bj
################################################################### 

class Quadratic:
	def __call__(self,**args):
	      self.args = args
	      if (len(args) == 3 and self.args.has_key('a') and self.args.get('a') !=0 
                       and self.args.has_key('b') and self.args.has_key('c')):
       	            if ((self.args.get('b'))**2-(4*(self.args.get('a'))*(self.args.get('c'))))>=0:
		         self.compute1 = "%2.2f" % float(((self.args.get('b')*(-1))+(m.sqrt((self.args.get('b'))**
					2-(4*(self.args.get('a'))*(self.args.get('c'))))))/(2*self.args.get('a')))
		         self.compute2 = "%2.2f" % float(((self.args.get('b')*(-1))-(m.sqrt((self.args.get('b'))**
					2-(4*(self.args.get('a'))*(self.args.get('c'))))))/(2*self.args.get('a')))
                    elif ((self.args.get('b'))**2-(4*(self.args.get('a'))*(self.args.get('c'))))<0:
		         self.compute1 = "%2.2f" % float(((self.args.get('b')*(-1))+(c.sqrt((self.args.get('b'))**
					2-(4*(self.args.get('a'))*(self.args.get('c'))))))/(2*self.args.get('a')))
		         self.compute2 = "%2.2f" % float(((self.args.get('b')*(-1))-(c.sqrt((self.args.get('b'))**
					2-(4*(self.args.get('a'))*(self.args.get('c'))))))/(2*self.args.get('a')))
	       else:
		   self.args = 0
                
               return (self.compute1,self.compute2)

	def __str__(self):
	      if self.args == 0:
		return '\n<Quadratic : Equation should be of the form of ax%+bx+c (a=?,b=?,c=?) and a !=0' % chr(253)
	      else:
		   if self.compute1==self.compute2:
		        return ('\n<Quadratic : Equation of the form %sx%s +(%s)x+(%s) = 0 \n\n<Solutions : x = %s\n\t'
			% (self.args.get('a'),chr(253),self.args.get('b'),self.args.get('c'),self.compute1))
		   else:     
                        return ('\n<Quadratic : Equation of the form %sx%s +(%s)x+(%s) = 0 \n\n<Solutions : x = %s\n\t       x = %s'
			% (self.args.get('a'),chr(253),self.args.get('b'),self.args.get('c'),self.compute1,self.compute2))

if __name__ =='__main__':
	y = Quadratic()
	y(a=7,b=-2,c=-2)
	print y
	y(a=-1,b=4,c=-5)
	print y
	y(a=4,b=-4,c=1)
	print y
	y(a=0,b=3,c=3)
	print y
########################################################################################## 
#Version : Python 3.2
#import cmath as c
#import math as m

#class Quadratic:
#    def __call__(self,**args):
#        self.args = args
#        if (len(args)==3 and 'a' in self.args and self.args.get('a')!=0
#            and 'b' in self.args and 'c' in self.args):
#            if ((self.args.get('b'))**2-(4*(self.args.get('a'))*(self.args.get('c'))))#>=0:
#                self.compute1 = "%2.2f" % float(((self.args.get('b')*(-1))+( m.sqrt((self.args.get('b'))**
#                               2-(4*(self.args.get('a'))*(self.args.get('c'))))))/(2*self.args.get('a')))
#               self.compute2 = "%2.2f" % float(((self.args.get('b')*(-1))-( m.sqrt((self.args.get('b'))**
#                                2-(4*(self.args.get('a'))*(self.args.get('c'))))))/(2*self.args.get('a')))
#            elif ((self.args.get('b'))**2-(4*(self.args.get('a'))*(self.args.get('c'))))<0:
#                self.compute1 = ((self.args.get('b')*(-1))+( c.sqrt((self.args.get('b')**
#                                2-(4*(self.args.get('a'))*(self.args.get('c'))))))/(2*self.args.get('a'))
#                self.compute2 = ((self.args.get('b')*(-1))-(c.sqrt((self.args.get('b'))**
#                                2-(4*(self.args.get('a'))*(self.args.get('c'))))))/(2*self.args.get('a'))
#        else:
#            self.args = 0
            
#        return (self.compute1,self.compute2)
#    def __str__(self):
#        if self.args == 0:
#            return '\n<Quadratic : Equation should be of the form of ax%s+bx+c (a=?,b=?,c=?) and a != 0' % chr(178)
#        else:
#            if self.compute1==self.compute2:
#                return ('\n<Quadratic : Equation of the form %sx%s + (%s)x + (%s) = 0 #\n\n<Solutions : x = %s\n\t'
#                    % (self.args.get('a'),chr(178),self.args.get('b'),self.args.get('c'),self.compute1))
#            else:
#                return ('\n<Quadratic : Equation of the form %sx%s + (%s)x + (%s) = 0 #\n\n<Solutions : x = %s\n\t     x = %s'
#                    % (self.args.get('a'),chr(178),self.args.get('b'),self.args.get('c'),self.compute1,self.compute2))
         2)
#if __name__=='__main__':
#    y = Quadratic()
#    y(a=1,b=-0.2,c=-0.4)
#    print(y)
#    y(a=-1,b=4,c=-5)
#    print(y)
#    y(a=4,b=-4,c=1)
#    print(y)
#    y(a=0,b=3,c=3)
#    print(y)
#    y(a=-1900,b=177,c=333)
#    print(y)
#

11 comments

david decotigny 15 years, 7 months ago  # | flag

I don't understand why there are so many "args.get('X')". And this OOP-style __str__ is not consistent with the non-OOP-style __call__. Here is another version:

import math, cmath

def polynome2str(*factors): # Greatest power to smallest
    def lmonome(factor, degree):
        if not factor:
            return ()
        if factor > 0:
            sign = "+"
        else:
            sign = "-"
            factor = -factor            
        if degree == 0:
            x = ""
        elif degree == 1:
            x = "x"
        else:
            x = "x^%d" % degree
        if degree > 0 and factor in (-1, 1): factor = ""
        return (sign, "%s%s" % (factor, x))

    result = []
    for f, d in zip(factors, range(len(factors)-1, -1, -1)):
        result += list(lmonome(f, d))
    if len(result) > 1 and result[0] == "+": result = result[1:]
    return " ".join(result)


class Quadratic:
    a, b, c   = None, None, None
    degree    = None
    solutions = None

    def __init__(self, **args):
        self.a = a = args.get("a", 0)
        self.b = b = args.get("b", 0)
        self.c = c = args.get("c", 0)
        self.degree = 2
        delta = b**2 - 4.*a*c
        if a == 0:
            assert b != 0, "Not an equation: %s = 0" % c
            # Linear equation
            self.degree = 1
            self.solutions = (-c / b,)
        elif delta == 0:
            self.solutions = (-b / (2.*a),)
        elif delta > 0:
            s = math.sqrt(delta)
            self.solutions = ( (-b - s) / (2.*a), (-b + s) / (2.*a) )
        else: # delta < 0 => complex solution
            s = cmath.sqrt(delta)
            self.solutions = ( (-b - s) / (2.*a), (-b + s) / (2.*a) )

    def __str__(self):
        a, b, c = (self.a, self.b, self.c)
        if self.degree == 1:
            return "Linear equation %s = 0, solution is: %s" \
                   % (polynome2str(b, c), self.solutions[0])
        s = polynome2str(a, b, c)
        if len(self.solutions) == 1:
            return "Quadratic equation %s = %s.(%s)^2 = 0, unique solution is: %s"\
                   % (s, a, polynome2str(1, b/(2.*a)), self.solutions[0])
        else:
            t = (s,) + self.solutions
            return "Quadratic equation %s = 0, solutions are: %s and %s" % t


if __name__ =='__main__':
        y = Quadratic(a=7,b=-2,c=-2)
        print y
        y = Quadratic(a=-1,b=4,c=-5)
        print y
        y = Quadratic(a=4,b=-4,c=1)
        print y
        y = Quadratic(a=0,b=3,c=3)
        print y
Gary Eakins 15 years, 7 months ago  # | flag

What does "#On the name of ALLAH" have to do with Python?

Fouad Teniou (author) 15 years, 7 months ago  # | flag

Thank you for your comment David Decotiny However, the args.get('a'),('b'),('c')are calling the dictionary values by keys once the user input them to perform the quadratic operations solutions -b(+ -)square-root(b^2 - 4ac)/2a. and if you look at my Pycol program where I used the OOP style you can see that I used the __repr__ for printing but not in this program because it works better. However, you can use both, it will depend of the order you want the execution of your program and the outcome The __call__ is made for calling the class directly instead of defining it by other name say( eg if I defined it as equation : if __name__=='__main__' y=Quadratic() y.equation(a=?,b=?,c=?) print y I hope that you will see the difference and will realise why I called it directly.

Fouad Teniou (author) 15 years, 7 months ago  # | flag

I use on the name of ALLAH because I am a Muslim and that is the way we write or say before we start doing things such as ( studying or eating ) for God bounty and I hope you will do one day yourself and see the difference of performing any task in your life, thus, On the name of ALLAH does have nothing to do with python and as you can realise that is not part of the code.

Jack Trainor 15 years, 7 months ago  # | flag

Fixed a bug and normalized output to complex numbers.

import math
import cmath

def solve_quadratic_equation(a, b, c):
    roots = []
    try:
        if a != 0:
            discriminant = b**2 - 4*a*c
            neg_b_div_2a = -(b/(2*a))
            if discriminant > 0:
                sqrt_discriminant_div_2a = math.sqrt(discriminant)/2*a
                roots.append(complex(neg_b_div_2a + sqrt_discriminant_div_2a, 0))
                roots.append(complex(neg_b_div_2a - sqrt_discriminant_div_2a, 0))
            elif discriminant == 0:
                roots.append(complex(neg_b_div_2a, 0))
            else:
                sqrt_discriminant_div_2a = cmath.sqrt(-discriminant)/2*a
                roots.append(complex(neg_b_div_2a, sqrt_discriminant_div_2a))
                roots.append(complex(neg_b_div_2a, -sqrt_discriminant_div_2a))
        else:
            raise Exception, "a == 0"
    except Exception, e:
        print("%s: %s" % ("solve_quadratic_equation failed", e))
    return roots

if __name__ =='__main__':
    print solve_quadratic_equation(1, 0, -64)
    print solve_quadratic_equation(1, 0, 64)
    print solve_quadratic_equation(1, 4, 4)
    print solve_quadratic_equation(0, 0, 64)
Jack Trainor 15 years, 7 months ago  # | flag

Hmm...not sure why the comment editor switched my comments and timestamps around. #5 should be my second post.

Jack Trainor 15 years, 7 months ago  # | flag

This recipe is entirely unreadable and current version fails at line 20. (And it's revision 12.)

The intention here is to solve an equation. I don't see the need to get fancy and create a class, make it a callable object and override __str__. Plus the values of a, b, c should be extracted once to variables as David D. recommended.

If one wants to check the input or format the output, I suggest those be done separately. Here's my version which makes the math pretty clear.

import math
import cmath

def solve_quadratic_equation(a, b, c):
    roots = []
    try:
        if a != 0:
            discriminant = b**2 - 4*a*c
            neg_b_div_2a = -(b/(2*a))
            if discriminant > 0:
                sqrt_discriminant_div_2a = math.sqrt(discriminant)/2*a
                roots.append(neg_b_div_2a + sqrt_discriminant_div_2a)
                roots.append(neg_b_div_2a - sqrt_discriminant_div_2a)
            elif discriminant == 0:
                roots.append(neg_b_div_2a)
            else:
                sqrt_discriminant_div_2a = cmath.sqrt(-discriminant)/2*a
                roots.append(complex(neg_b_div_2a, sqrt_discriminant_div_2a))
                roots.append(complex(neg_b_div_2a, sqrt_discriminant_div_2a))
        else:
            print("%s: %s" % ("solve_quadratic_equation failed", "a == 0"))
    except Exception, e:
        print("%s: %s" % ("solve_quadratic_equation failed", e))
    return roots

if __name__ =='__main__':
    print solve_quadratic_equation(1, 0, -64)
    print solve_quadratic_equation(1, 0, 64)
Fouad Teniou (author) 15 years, 7 months ago  # | flag

You should know that I am using a Central Library for posting my programs and therefore I tried to use Word document, cut and pace from my original version, which I wrote and which is working perfectly and providing professional outcome, and which I tested on DOS before I posted it. However, I noticed there is a bracket missing on line 20 and 25 and I expect people as your self to be able to correct such anomalies since they are out of control sometimes while the Word cut and pace process is not working especially here at the Central Library which I do have to use for personal reasons. I used the Class method, because this is the way I do write my programs, ( Fancy ways) and people do have different style even in what they eat or the way they do it. Though people will import the class or use it as part of other programs, because this is the Mathematics branch, and people use for different purpose ( Finance ,Statistics, Accounting etc,etc………………………………. Quadratic is a superb program and is working perfectly and other students and Tutors will find it extremely useful whether to check or to rely on for their professional work. I realised that you used exceptions on your version and again this is up to people to choose their style, and I do not see the need of raising exceptions because Python raise exceptions automatically with their own wordings. I use the if statement which I believe is more professional and the is the best style, since it is based on logic which is a branch in Mathematics and which is the branch I did study and gain an International Baccalaureate in 1987

David Lambert 15 years, 5 months ago  # | flag

If 4 a c is much less than b squared then the formula, for roots while mathematically correct is numerically poor. See this link for better logic:

http://thornahawk.unitedti.org/

Fouad Teniou (author) 15 years, 4 months ago  # | flag

You should have read the comment on the top of the program ( if b^2-4ac is negative the solutions are not real but complex numbers of the form a+bj. Though, both real and complex solutions are called using Quadratic) we get the complex number solution. However, as you should be aware of the use of complex numbers in the mathematic field. And I even noticed in the web link you mentioned that there is a reference to people want to use the complex solutions which could be for higher levels in mathematics field

Try and stick with an __init__ method . . . I understand you have a degree in math but you should ALWAYS stick with defining classes that confine to the OOP paradigm. Also try and make your code more readable by making it more concise.

Created by Fouad Teniou on Tue, 5 Aug 2008 (MIT)
Python recipes (4591)
Fouad Teniou's recipes (37)

Required Modules

  • (none specified)

Other Information and Tasks