# Factoring and solving a quadratic polynomial

So i code stuff for my fx-cg50 calculator's micropython as I'm an a level student and a python beginner, and i need help pointing out the bugs and some programming tips to further improve my code, and i can't use sympy or numpy since they cant fit in my calculator's measly 16 MB so i have to make everything from scratch: disclaimer, my code can't factor expressions by completing the square, so if you guys have any idea about how i could get started tell me, i was planning on using my program to begin with to get a factored quadratic expression anyways, and move on from there.

and can anyone tell me what level my code is at, relatively for reference sake.

from math import sqrt, pi, isclose, gcd

print("ax+by+c=0")

def gcd_2(a, b):
while b:
a, b = b, a % b
return a

def fraction(a):
factor = 0
while True:
factor += 1
a_rounded = int(round(a*factor))
if isclose(a*factor, a_rounded, abs_tol=0.01):
text = ("{}/{}".format(a_rounded, factor))
return text

def simplify_fraction(numer, denom):
if denom == 0:
return "Division by 0 - result undefined"

# Remove greatest common divisor:
common_divisor = gcd_2(numer, denom)
(reduced_num, reduced_den) = (numer / common_divisor, denom / common_divisor)
# Note that reduced_den > 0 as documented in the gcd function.

if common_divisor == 1:
return (numer, denom)
else:
# Bunch of nonsense to make sure denominator is negative if possible
if (reduced_den > denom):
if (reduced_den * reduced_num < 0):
return (-reduced_num, -reduced_den)
else:
return (reduced_num, reduced_den)
else:
return (reduced_num, reduced_den)

a_original, b_original, c_original = a, b, c
if b ** 2 - 4 * a * c >= 0:
negative_factor = False
if a < 0:
negative_factor = True
#  checks if gcf can be applied to simplify the quadratic expression
b_divisible_by_a = (b % a == 0)
c_divisible_by_a = (c % a == 0)
check_divisible = (b_divisible_by_a and c_divisible_by_a)
a_is_one = (a == (a/a))
if negative_factor:
gcf = -int(gcd(int(-a), gcd(int(-b), int(-c))))
b, c, a = -b, -c, -a
if a_is_one or (check_divisible is False):
gcf = ""
elif check_divisible and (a_is_one is False):
if negative_factor is False:
gcf = int(gcd(int(-a), gcd(int(-b), int(-c))))
b, c, a = b/a, c/a, a/a
x1 = (-b + sqrt(b ** 2 - 4 * a * c)) / (2 * a)
x2 = (-b - sqrt(b ** 2 - 4 * a * c)) / (2 * a)
# Added a "-" to these next 2 values because they would be moved to the other side of the equation
mult1 = -x1 * a
mult2 = -x2 * a
(num1, den1) = simplify_fraction(a, mult1)
(num2, den2) = simplify_fraction(a, mult2)
if (num1 > a) or (num2 > a):
# simplify fraction will make too large of num and denom to try to make a sqrt work
print("No factorization")
c =(b/2)**2

else:
# Getting ready to make the print look nice
if (den1 > 0):
sign1 = "+"
else:
sign1 = ""
if (den2 > 0):
sign2 = "+"
else:
sign2 = ""
print("The Factored Form is:\n{}({}x{}{})({}x{}{})".format(gcf, int(num1), sign1, int(den1), int(num2), sign2,int(den2)))
else:
# if the part under the sqrt is negative, you have a solution with i
print("Solutions are imaginary")
return

while True:
try:
stop_flag = 0
stop_or_continue = ""
a = float(eval(input("insert a: ").replace("pi", str(pi))))
b = float(eval(input("insert b: ").replace("pi", str(pi))))
c = float(eval(input("insert c: ").replace("pi", str(pi))))

discriminant = b ** 2 - 4 * a * c

if discriminant == 0:
x_one = (-b + sqrt(b ** 2 - 4 * a * c)) / (2 * a)   # x_one
if eval(fraction(x_one)) % 1 == 0:
print("x1 is : ", x_one)
else:
print("x1 is : ", fraction(x_one))
if discriminant > 0:
x_one = (-b + sqrt(b ** 2 - 4 * a * c)) / (2 * a)  # x_one
if eval(fraction(x_one)) % 1 == 0:
print("x1 is : ", x_one)
else:
print("x1 is : ", fraction(x_one))
x_two = (-b - sqrt(b ** 2 - 4 * a * c)) / (2 * a)  # x_two
if eval(fraction(x_two)) % 1 == 0:
print("x2 is : ", x_two)
else:
print("x2 is : ", fraction(x_two))
if discriminant < 0:
pass

while stop_or_continue != "a" or "b":
stop_or_continue = input("Stop?: ")
if stop_or_continue == "a":
stop_flag = 1
break
if stop_or_continue == "b":
stop_flag = 0
break
if stop_flag == 1:
break

except ValueError:
pass

• You say quadratic, but the expression you print ax + by + c = 0 is linear. Commented Feb 22, 2020 at 0:04
• @AJNeufeld ahh sorry thats a small mistake but the code is for quadratic really Commented Feb 22, 2020 at 9:49

# Repetition

You write:

discriminant = b ** 2 - 4 * a * c


followed by:

    if discriminant == 0:
x_one = (-b + sqrt(b ** 2 - 4 * a * c)) / (2 * a)   # x_one
...
if discriminant > 0:
x_one = (-b + sqrt(b ** 2 - 4 * a * c)) / (2 * a)  # x_one
...
x_two = (-b - sqrt(b ** 2 - 4 * a * c)) / (2 * a)  # x_two
...


Any reason why you don't use sort(discriminant)?

This continues in quadratic_function, with:

if b ** 2 - 4 * a * c >= 0:
...
x1 = (-b + sqrt(b ** 2 - 4 * a * c)) / (2 * a)
x2 = (-b - sqrt(b ** 2 - 4 * a * c)) / (2 * a)


# Repetition (reprise)

    a = float(eval(input("insert a: ").replace("pi", str(pi))))
b = float(eval(input("insert b: ").replace("pi", str(pi))))
c = float(eval(input("insert c: ").replace("pi", str(pi))))


Looks like you could use a common function here:

def query_float(prompt):
return float(eval(input(prompt).replace("pi", str(pi))))

a = query_float("insert a: ")
b = query_float("insert b: ")
c = query_float("insert c: ")


# Repetition (reprise, reprised)

        if eval(fraction(x_one)) % 1 == 0:
print("x1 is : ", x_one)
else:
print("x1 is : ", fraction(x_one))


This block of code appears 3 times (once with x_two). In the process of executing the block, it calls fraction(x_one), which is a time-consuming search function, looping through up to 100 divisors, trying to find one that works. Then, the resulting fraction expression is evaluated, and if it is not an integer, fraction(x_one) is again called, despite having been already computed moments earlier!

If fraction() simply returned the "value", instead of "value/1", when factor == 1, then the caller would simply:

        print("x1 is : ", fraction(x_one))


# Stop or Continue

It is unclear why the user would answer "a" or "b" to the question input("Stop?: ").

• ahh its because ill be inputting everything from a calculator and a and b are right beside each other. Commented Feb 25, 2020 at 23:44

This type of program, can really use OOP, it will help maintain it much better, by making classes for designated functions, and the pi replacer function can be a part of it.

• I would be helpful if you could show some examples of how this might be transformed to OOP. Commented Jul 3, 2020 at 17:36