Python Coding Exercise #28: Solving a Quadratic Equation
Part of the series Python Practice Exercise — part 28
Before you start: Know input() and int() · Know arithmetic operators, ** and sqrt()
The question
In the Python
mathmodule there is the functionsqrt, which calculates the square root of a number. You can use it like so:
from math import sqrt
print(sqrt(9))
3.0
Please write a program for solving a quadratic equation of the form ax² + bx + c. The program asks for values a, b and c. It should then use the quadratic formula to solve the equation. The quadratic formula expressed with the Python
sqrtfunction is as follows:x = (-b ± sqrt(b² - 4ac)) / (2a)
You can assume the equation will always have two real roots, so the above formula will always work.
An example of expected behaviour:
Value of a: 1
Value of b: 2
Value of c: -8
The roots are 2.0 and -4.0
My Solution
from math import sqrt
a = int(input("Value of a: "))
b = int(input("Value of b: "))
c = int(input("Value of c: "))
discriminant = b**2 - 4*a*c
x1 = (-b + sqrt(discriminant)) / (2*a)
x2 = (-b - sqrt(discriminant)) / (2*a)
print(f"The roots are {x1} and {x2}")
How My Solution Works
1. What the exercise is asking
A quadratic equation has the form ax² + bx + c = 0, where a, b and c are numbers. Its roots are the values of x that make the equation true. For the example x² + 2x - 8 = 0, we have a = 1, b = 2 and c = -8.
The quadratic formula gives the roots directly:
x = (-b ± √(b² - 4ac)) / (2a)
The ± sign means “plus or minus”, which is why there are two roots: one uses + and the other uses -.
2. The discriminant
The part under the square root, b² - 4ac, is called the discriminant. It tells you how many real roots the equation has:
| Discriminant | Number of real roots |
|---|---|
| positive | two different roots |
| zero | one root, repeated |
| negative | no real roots |
The exercise says you can assume there are always two real roots, so the discriminant is always positive. The program stores it in its own variable, discriminant, so the formula is easier to read and the same value is used twice.
3. Turning the formula into code
x1 = (-b + sqrt(discriminant)) / (2*a)
x2 = (-b - sqrt(discriminant)) / (2*a)
Each root is the formula with + or - in the middle. Here is the example a = 1, b = 2, c = -8 worked through step by step:
| Step | Calculation | Result |
|---|---|---|
| Discriminant | b**2 - 4*a*c = 4 - 4*1*(-8) = 4 + 32 | 36 |
| Square root | sqrt(36) | 6.0 |
| First root | (-2 + 6.0) / (2*1) | 2.0 |
| Second root | (-2 - 6.0) / (2*1) | -4.0 |
The roots print as 2.0 and -4.0, with a decimal point, because sqrt() returns a float and / always returns a float.
4. Check the answer
A good habit with maths programs is to check the result by putting it back into the equation. If x is a root, then a*x**2 + b*x + c should be 0:
a, b, c = 1, 2, -8
print(a * 2.0**2 + b * 2.0 + c) # 0.0
print(a * (-4.0)**2 + b * (-4.0) + c) # 0.0
Both roots give 0.0, so they are correct. For roots that aren’t tidy, the check can show a tiny leftover such as 1e-16 instead of exactly 0. That’s floating-point rounding, as in Data Types in Python and Exercise #31.
Here are some more equations and their roots:
| Equation | a, b, c | Roots printed |
|---|---|---|
| x² - 3x + 2 | 1, -3, 2 | 2.0 and 1.0 |
| 2x² - 4x - 6 | 2, -4, -6 | 3.0 and -1.0 |
| x² - 9 | 1, 0, -9 | 3.0 and -3.0 |
| x² + x - 1 | 1, 1, -1 | 0.6180339887498949 and -1.618033988749895 |
Brackets matter
The brackets around 2*a are essential. Division and multiplication have the same priority in Python, and they are done from left to right. So without the brackets, this line:
x1 = (-b + sqrt(discriminant)) / 2*a
means “divide by 2, then multiply by a”, which isn’t the same as “divide by 2a”. Here’s the dangerous part: for the example in the exercise, a is 1, so multiplying by a changes nothing, and the wrong code still prints the right answer. With a = 2, for the equation 2x² - 4x - 6, the wrong version prints:
The roots are 12.0 and -4.0
The correct roots are 3.0 and -1.0. The lesson: a program that passes the example in the exercise isn’t necessarily correct. Test it on an equation where a is not 1.
The brackets around (-b + sqrt(discriminant)) matter for the same reason: they make sure the whole top part is divided.
University Solution
The University Solution is almost identical to My Solution. It uses different variable names (root1 and root2 instead of x1 and x2) and a few extra brackets:
discriminant = b**2 - (4 * a * c)
root1 = (-b + sqrt(discriminant)) / (2 * a)
root2 = (-b - sqrt(discriminant)) / (2 * a)
The extra brackets in (4 * a * c) aren’t needed, because ** and * are calculated before -, but they make the formula easier to read. The extra spaces in (2 * a) are just style. The output is exactly the same.
The University Solution also contains a useful note: a square root can be written as a power of one half. In other words, sqrt(9) is equivalent to 9 ** 0.5, and both give 3.0.
Things to notice
No real roots. If the discriminant is negative, there are no real roots, and sqrt() stops the program with a ValueError. The message depends on your Python version. Python 3.14 says expected a nonnegative input, got -16.0, and older versions say math domain error. The exercise promises this won’t happen.
a can’t be zero. If a is 0, the equation isn’t quadratic any more, and the program would divide by zero. It stops with a ZeroDivisionError.
Repeated root. If the discriminant is exactly 0, both roots are the same. For x² - 2x + 1, the program prints The roots are 1.0 and 1.0.
Key takeaways
- A quadratic equation
ax² + bx + c = 0has roots given byx = (-b ± √(b² - 4ac)) / (2a). - The discriminant
b² - 4actells you how many real roots there are. - Calculate the two roots separately, one with
+and one with-. - Use brackets to make sure the whole top part is divided by
2a:(...) / (2*a), not(...) / 2*a. - Test with more than the example. A program can pass the example by luck, as it does here when
ais 1. sqrt(x)is the same asx ** 0.5.- You can check a root by substituting it back into the equation. The result should be 0.
✦ This is part of my Python Practice Exercise series, where I work through exercises while learning Python and explain each answer in plain language. ✦
Practice Source: This exercise is taken from the Python Programming MOOC 2026 by the University of Helsinki. I’m working through the exercises as part of my Python learning journey and documenting my answers and explanations here.