FaiyazAzam's picture
Upload app.py with huggingface_hub
930062b verified
import json
import pandas as pd
import gradio as gr
from transformers import pipeline, set_seed
SCOPE = """
**Scope:** DC, steady-state Ohm's Law.
**Assumptions:** Ideal components; temperature effects ignored.
**Units:** V (volts), I (amps), R (ohms).
**Valid ranges:** 0 ≤ V ≤ 1000, 0 ≤ I ≤ 100, 0.1 ≤ R ≤ 1e6.
"""
set_seed(42)
try:
explain_llm = pipeline("text2text-generation", model="google/flan-t5-small")
except Exception as e:
print("LLM pipeline init failed; using fallback text only.", e)
explain_llm = None
def validate(target, V, I, R):
errs = []
if target != "Voltage (V)" and not (0 <= V <= 1000): errs.append("V must be 0–1000 V.")
if target != "Current (I)" and not (0 <= I <= 100): errs.append("I must be 0–100 A.")
if target != "Resistance (R)"and not (0.1 <= R <= 1e6):errs.append("R must be 0.1–1e6 Ω.")
if target == "Current (I)" and R == 0: errs.append("R cannot be 0 for I = V/R.")
if target == "Resistance (R)"and I == 0: errs.append("I cannot be 0 for R = V/I.")
return errs
def compute_structured(target, V, I, R):
if target == "Voltage (V)":
value = I * R
steps = [f"Use V = I·R", f"V = {I} A × {R} Ω = {value} V"]
out = {"quantity":"V","value":value,"units":"V"}
elif target == "Current (I)":
value = V / R
steps = [f"Use I = V/R", f"I = {V} V ÷ {R} Ω = {value} A"]
out = {"quantity":"I","value":value,"units":"A"}
else:
value = V / I
steps = [f"Use R = V/I", f"R = {V} V ÷ {I} A = {value} Ω"]
out = {"quantity":"R","value":value,"units":"Ω"}
return {
"calculation":"Ohm's Law",
"equations":{"V":"V=I·R","I":"I=V/R","R":"R=V/I"},
"target":target,
"inputs":{"V":V,"I":I,"R":R,"units":{"V":"V","I":"A","R":"Ω"}},
"steps":steps,
"output":out
}
def explain(_data: dict) -> str:
"""
Always ask the LLM to explain what Ohm's Law is; fallback if unavailable.
"""
prompt = (
"Explain Ohm’s Law for a non-expert in <=80 words. "
"Use symbols ×, ·, and Ω (no Unicode escapes). "
"Include the three forms (V = I·R, I = V/R, R = V/I) and list the units."
)
if explain_llm is not None:
try:
txt = explain_llm(prompt, do_sample=False, num_beams=1, max_new_tokens=120)[0]["generated_text"].strip()
if txt:
return (txt.replace("\u00b7","·")
.replace("\u00D7","×").replace("\u00d7","×")
.replace("\u03a9","Ω").replace("\u03A9","Ω"))
except Exception as e:
print("LLM explanation failed:", e)
return ("Ohm’s Law relates voltage (V), current (I), and resistance (R): "
"V = I·R, I = V/R, R = V/I. Units: V (volts), A (amps), Ω (ohms).")
def run(target, V, I, R):
errs = validate(target, V, I, R)
if errs: raise gr.Error("\n".join(errs))
data = compute_structured(target, V, I, R)
df = pd.DataFrame([{
"Target": data["target"],
"V (V)": data["inputs"]["V"],
"I (A)": data["inputs"]["I"],
"R (Ω)": data["inputs"]["R"],
"Result": f'{data["output"]["quantity"]} = {data["output"]["value"]} {data["output"]["units"]}'
}])
return df, json.dumps(data, indent=2), explain(data)
with gr.Blocks(title="Ohm's Law — see the math") as demo:
gr.Markdown("# 🔌 Ohm's Law — Deterministic Calculator")
gr.Markdown(SCOPE)
with gr.Row():
with gr.Column():
target = gr.Radio(["Voltage (V)","Current (I)","Resistance (R)"], value="Voltage (V)", label="Compute")
V = gr.Number(value=12.0, label="Voltage V (V) [ignored if computing V]")
I = gr.Number(value=2.0, label="Current I (A) [ignored if computing I]")
R = gr.Number(value=6.0, label="Resistance R (Ω) [ignored if computing R]")
btn = gr.Button("Compute", variant="primary")
with gr.Column():
with gr.Tabs():
with gr.Tab("Results"):
out_table = gr.Dataframe(label="Results", interactive=False)
with gr.Tab("Explanation"):
out_expl = gr.Markdown(value="_Explanation will appear here after you click **Compute**._")
with gr.Tab("Structured JSON"):
out_json = gr.Code(label="Structured output (JSON)", language="json")
inputs = [target, V, I, R]
btn.click(run, inputs=inputs, outputs=[out_table, out_json, out_expl])
gr.Examples(
inputs=inputs,
examples=[
["Voltage (V)", 0.0, 2.0, 50.0],
["Current (I)", 12.0, 0.0, 6.0],
["Resistance (R)", 5.0, 0.01, 0.0]
],
label="Examples"
)
if __name__ == "__main__":
demo.launch()