$$\newcommand{\id}{\mathrm{id}}$$ $$\newcommand{\Span}{\mathrm{span}}$$ $$\newcommand{\kernel}{\mathrm{null}\,}$$ $$\newcommand{\range}{\mathrm{range}\,}$$ $$\newcommand{\RealPart}{\mathrm{Re}}$$ $$\newcommand{\ImaginaryPart}{\mathrm{Im}}$$ $$\newcommand{\Argument}{\mathrm{Arg}}$$ $$\newcommand{\norm}[1]{\| #1 \|}$$ $$\newcommand{\inner}[2]{\langle #1, #2 \rangle}$$ $$\newcommand{\Span}{\mathrm{span}}$$

Partial Fraction Solver(not operational)

$$\newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} }$$ $$\newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}}$$$$\newcommand{\id}{\mathrm{id}}$$ $$\newcommand{\Span}{\mathrm{span}}$$ $$\newcommand{\kernel}{\mathrm{null}\,}$$ $$\newcommand{\range}{\mathrm{range}\,}$$ $$\newcommand{\RealPart}{\mathrm{Re}}$$ $$\newcommand{\ImaginaryPart}{\mathrm{Im}}$$ $$\newcommand{\Argument}{\mathrm{Arg}}$$ $$\newcommand{\norm}[1]{\| #1 \|}$$ $$\newcommand{\inner}[2]{\langle #1, #2 \rangle}$$ $$\newcommand{\Span}{\mathrm{span}}$$ $$\newcommand{\id}{\mathrm{id}}$$ $$\newcommand{\Span}{\mathrm{span}}$$ $$\newcommand{\kernel}{\mathrm{null}\,}$$ $$\newcommand{\range}{\mathrm{range}\,}$$ $$\newcommand{\RealPart}{\mathrm{Re}}$$ $$\newcommand{\ImaginaryPart}{\mathrm{Im}}$$ $$\newcommand{\Argument}{\mathrm{Arg}}$$ $$\newcommand{\norm}[1]{\| #1 \|}$$ $$\newcommand{\inner}[2]{\langle #1, #2 \rangle}$$ $$\newcommand{\Span}{\mathrm{span}}$$

import ipywidgets as widgets
from IPython.display import display, clear_output
import sympy as sp
from sympy.parsing.sympy_parser import parse_expr
from sympy import init_session
init_session(quiet=True)
sp.init_printing()

x = sp.symbols("x")
text = ["Numerator", "Denominator"]
box_layout = widgets.Layout(display="flex",
flex_flow="row",
align_items="stretch",
width="100%")

goBtn = widgets.Button(description="Run",
layout=widgets.Layout(width="10%"))
quitBtn = widgets.Button(description="Quit",
layout=widgets.Layout(width="10%"))
numerator = widgets.Text(
value = "",
placeholder = text[0] + " goes here.",
description = text[0] + " :",
disabled = False,
layout=widgets.Layout(width="40%"))
denominator = widgets.Text(
value = "",
placeholder = text[1] + " goes here.",
description = text[1] + " :",
disabled = False,
layout=widgets.Layout(width="40%"))
out = widgets.Output(layout=widgets.Layout(left="30%", border="1px solid blue", width="40%"))

def errMsg(message):
clear_output()
out.clear_output()
with out:
print(message)
display(out)
setUp()

def go_button_clicked(b):
fx = ""
gx = ""
partialFraction = ""
try:
fx = parse_expr(numerator.value)
gx = parse_expr(denominator.value)
except:
errMsg("Input Error - x^2=x**2, 2x=2*x, polynomials only")

if gx != "" and fx != "":
denomFactored = sp.factor(gx)
try:
partialFraction = sp.apart(fx/gx)
except:
errMsg("Polynomials only, no division by zero either!")

if partialFraction != "":
with out:
display(sp.Eq(fx/gx, partialFraction))
display(out)

def quitProgram(b):
quitBtn.close()
numerator.close()
denominator.close()
goBtn.close()
clear_output()

def setUp():
items = [numerator, denominator, goBtn, quitBtn]
display(widgets.Box(children=items, layout=box_layout))
goBtn.on_click(go_button_clicked)
quitBtn.on_click(quitProgram)

setUp()


Partial Fraction Solver(not operational) is shared under a not declared license and was authored, remixed, and/or curated by LibreTexts.