CoolFace
Apppublic

HouseofElectricalEngineers/QuadraticEquationSolver

sourceHugging Facemitupdated 1y agoView on Hugging Face
0likes
app.py142 linesDownload Raw Back to root
1import io2import numpy as np3import matplotlib.pyplot as plt4import gradio as gr5from PIL import Image6 7# ----- Solver logic -----8def solve_quadratic(a, b, c):9    if a == 0:10        if b == 0:11            return None, None, "degenerate", "No solution" if c != 0 else "Infinite solutions"12        root = -c / b13        return [root], None, "linear", f"Single root x = {root:.6f}"14    discriminant = b**2 - 4 * a * c15    sqrt_disc = np.sqrt(abs(discriminant))16    if discriminant > 0:17        r1 = (-b + sqrt_disc) / (2 * a)18        r2 = (-b - sqrt_disc) / (2 * a)19        nature = "real and distinct"20        roots = [r1, r2]21    elif discriminant == 0:22        r = -b / (2 * a)23        nature = "real and equal"24        roots = [r, r]25    else:26        real_part = -b / (2 * a)27        imag_part = sqrt_disc / (2 * a)28        r1 = complex(real_part, imag_part)29        r2 = complex(real_part, -imag_part)30        nature = "complex conjugates"31        roots = [r1, r2]32    return roots, discriminant, nature, None33 34def format_solution_text(a, b, c, show_steps):35    roots, discriminant, nature, message = solve_quadratic(a, b, c)36    lines = []37    if a == 0:38        if nature == "degenerate":39            lines.append(f"⚠️ {message}")40        elif nature == "linear":41            root = -c / b if b != 0 else None42            lines.append("**Linear equation (a=0):**")43            lines.append(f"{b:.6f}x + {c:.6f} = 0")44            if root is not None:45                lines.append(f"Solution: x = {root:.6f}")46        return "\n".join(lines)47 48    lines.append(f"**Discriminant:** Δ = b² - 4ac = {discriminant:.6f}")49    lines.append(f"**Nature of roots:** {nature.capitalize()}")50    if isinstance(roots, list):51        def fmt(x):52            if isinstance(x, complex):53                return f"{x.real:.6f} {'+' if x.imag >= 0 else '-'} {abs(x.imag):.6f}i"54            else:55                return f"{x:.6f}"56        if len(roots) == 2:57            lines.append(f"**Root 1:** {fmt(roots[0])}")58            lines.append(f"**Root 2:** {fmt(roots[1])}")59        elif len(roots) == 1:60            lines.append(f"**Root:** {fmt(roots[0])}")61 62    if show_steps:63        lines.append("\n**Solution steps:**")64        lines.append(f"1. Compute discriminant: Δ = ({b:.6f})² - 4×({a:.6f})×({c:.6f}) = {discriminant:.6f}")65        lines.append("2. Apply quadratic formula:")66        if discriminant >= 0:67            lines.append(f"   x = [ -{b:.6f} ± sqrt({discriminant:.6f}) ] / (2×{a:.6f})")68        else:69            lines.append(f"   x = [ -{b:.6f} ± i·sqrt({abs(discriminant):.6f}) ] / (2×{a:.6f})")70        if isinstance(roots, list) and len(roots) == 2:71            if discriminant >= 0:72                lines.append(f"3. Final: x₁ = {roots[0]:.6f}, x₂ = {roots[1]:.6f}")73            else:74                real_part = -b / (2 * a)75                imag_part = np.sqrt(abs(discriminant)) / (2 * a)76                lines.append(f"3. Final: x₁ = {real_part:.6f} + {imag_part:.6f}i, x₂ = {real_part:.6f} - {imag_part:.6f}i")77    return "\n".join(lines)78 79def make_plot(a, b, c, discriminant, roots):80    x = np.linspace(-10, 10, 800)81    y = a * x**2 + b * x + c82    fig, ax = plt.subplots()83    ax.plot(x, y)84    ax.axhline(0, linewidth=0.8)85    ax.set_xlabel("x")86    ax.set_ylabel("f(x)")87    ax.set_title(f"{a}x² + {b}x + {c}")88    if discriminant is not None and discriminant >= 0 and isinstance(roots, list) and len(roots) == 2:89        r1, r2 = roots90        ax.scatter([r1, r2], [0, 0], marker="o")91        ax.annotate(f"x₁={r1:.2f}", (r1, 0), textcoords="offset points", xytext=(0,10), ha="center")92        ax.annotate(f"x₂={r2:.2f}", (r2, 0), textcoords="offset points", xytext=(0,-15), ha="center")93    if a != 0:94        xv = -b / (2 * a)95        yv = a * xv**2 + b * xv + c96        ax.scatter([xv], [yv], marker="x")97        ax.annotate(f"vertex ({xv:.2f}, {yv:.2f})", (xv, yv), textcoords="offset points", xytext=(10,10))98    ax.grid(True)99    fig.tight_layout()100    return fig101 102# ----- Gradio app -----103def gradio_interface(a, b, c, show_steps):104    try:105        roots, discriminant, nature, message = solve_quadratic(a, b, c)106        text = format_solution_text(a, b, c, show_steps)107        disc_for_plot = discriminant if discriminant is not None else 0108        roots_for_plot = roots if roots is not None else []109        fig = make_plot(a, b, c, disc_for_plot, roots_for_plot)110        buf = io.BytesIO()111        fig.savefig(buf, format="png", bbox_inches="tight")112        buf.seek(0)113        img = Image.open(buf).convert("RGB")  # convert to PIL image for gradio114        return text, img115    except Exception as e:116        return f"Error computing solution: {e}", None117 118with gr.Blocks(title="Quadratic Equation Solver") as demo:119    gr.Markdown("# Quadratic Equation Solver")120    gr.Markdown(121        "Solve \(ax^2 + bx + c = 0\); shows discriminant, nature of roots, solution steps, and plot."122    )123    with gr.Row():124        with gr.Column():125            a_in = gr.Number(label="Coefficient a", value=1.0)126            b_in = gr.Number(label="Coefficient b", value=0.0)127            c_in = gr.Number(label="Coefficient c", value=0.0)128            show_steps = gr.Checkbox(label="Show solution steps", value=True)129            solve_btn = gr.Button("Solve")130        with gr.Column():131            output_md = gr.Markdown()132            plot_img = gr.Image(type="pil", label="Plot")133 134    solve_btn.click(135        fn=gradio_interface,136        inputs=[a_in, b_in, c_in, show_steps],137        outputs=[output_md, plot_img],138    )139 140if __name__ == "__main__":141    demo.launch(share=False)142