calculator / app.py
EngrMuhammadBilal's picture
Update app.py
3f2176f verified
import math
import streamlit as st
st.set_page_config(page_title="Calculator", page_icon="🧮", layout="centered")
# ---- Helpers ----
def safe_div(a, b):
if b == 0:
raise ZeroDivisionError("Cannot divide by zero")
return a / b
def fmt(x):
try:
# Show ints without .0
return int(x) if float(x).is_integer() else x
except Exception:
return x
def add_history(expr, result):
st.session_state.setdefault("history", [])
st.session_state.history.insert(0, f"{expr} = {result}")
# keep last 20
st.session_state.history = st.session_state.history[:20]
# ---- Sidebar ----
with st.sidebar:
st.header("⚙️ Options")
theme = st.radio("Mode", ["Basic", "Scientific"], horizontal=True)
show_history = st.checkbox("Show history", True)
st.markdown("---")
st.caption("Tip: Use the Basic tab for two number math. Use Scientific for single number functions and powers.")
st.title("🧮 Streamlit Calculator")
st.write("A simple calculator ready for Hugging Face Spaces.")
# ---- Basic Calculator ----
if theme == "Basic":
col1, col2 = st.columns(2)
with col1:
a = st.number_input("First number (a)", value=0.0, step=1.0, format="%.10f")
with col2:
b = st.number_input("Second number (b)", value=0.0, step=1.0, format="%.10f")
op = st.selectbox(
"Operation",
["+", "-", "×", "÷", "a^b (power)", "a % b (mod)"],
index=0
)
if st.button("Calculate", use_container_width=True):
try:
if op == "+":
result = a + b
expr = f"{a} + {b}"
elif op == "-":
result = a - b
expr = f"{a} - {b}"
elif op == "×":
result = a * b
expr = f"{a} × {b}"
elif op == "÷":
result = safe_div(a, b)
expr = f"{a} ÷ {b}"
elif op == "a^b (power)":
result = math.pow(a, b)
expr = f"{a}^{b}"
elif op == "a % b (mod)":
if b == 0:
raise ZeroDivisionError("Cannot mod by zero")
result = a % b
expr = f"{a} % {b}"
else:
raise ValueError("Unknown operation")
result_fmt = fmt(result)
st.success(f"Result: {result_fmt}")
add_history(expr, result_fmt)
except Exception as e:
st.error(f"Error: {e}")
# ---- Scientific Calculator ----
else:
col_a, col_b = st.columns([2, 1])
with col_a:
x = st.number_input("Value (x)", value=0.0, step=1.0, format="%.10f")
with col_b:
use_degrees = st.checkbox("Trig in degrees", True)
func = st.selectbox(
"Function",
[
"sin(x)", "cos(x)", "tan(x)",
"asin(x)", "acos(x)", "atan(x)",
"ln(x)", "log10(x)", "sqrt(x)",
"exp(x)", "abs(x)", "factorial(x) (non negative integer)",
"x^n (power)"
],
index=0
)
n = None
if func == "x^n (power)":
n = st.number_input("Exponent (n)", value=2.0, step=1.0, format="%.10f")
if st.button("Calculate", use_container_width=True):
try:
val = x
angle = math.radians(x) if use_degrees else x
if func == "sin(x)":
res = math.sin(angle)
expr = f"sin({x}{'°' if use_degrees else ''})"
elif func == "cos(x)":
res = math.cos(angle)
expr = f"cos({x}{'°' if use_degrees else ''})"
elif func == "tan(x)":
res = math.tan(angle)
expr = f"tan({x}{'°' if use_degrees else ''})"
elif func == "asin(x)":
if val < -1 or val > 1:
raise ValueError("asin domain is [-1, 1]")
ang = math.asin(val)
res = math.degrees(ang) if use_degrees else ang
expr = f"asin({x})"
elif func == "acos(x)":
if val < -1 or val > 1:
raise ValueError("acos domain is [-1, 1]")
ang = math.acos(val)
res = math.degrees(ang) if use_degrees else ang
expr = f"acos({x})"
elif func == "atan(x)":
ang = math.atan(val)
res = math.degrees(ang) if use_degrees else ang
expr = f"atan({x})"
elif func == "ln(x)":
if val <= 0:
raise ValueError("ln domain is x > 0")
res = math.log(val)
expr = f"ln({x})"
elif func == "log10(x)":
if val <= 0:
raise ValueError("log10 domain is x > 0")
res = math.log10(val)
expr = f"log10({x})"
elif func == "sqrt(x)":
if val < 0:
raise ValueError("sqrt domain is x >= 0")
res = math.sqrt(val)
expr = f"√({x})"
elif func == "exp(x)":
res = math.exp(val)
expr = f"exp({x})"
elif func == "abs(x)":
res = abs(val)
expr = f"|{x}|"
elif func == "factorial(x) (non negative integer)":
if val < 0 or not float(val).is_integer():
raise ValueError("factorial requires a non negative integer")
res = math.factorial(int(val))
expr = f"{int(val)}!"
elif func == "x^n (power)":
res = math.pow(val, n)
expr = f"{val}^{n}"
else:
raise ValueError("Unknown function")
res_fmt = fmt(res)
st.success(f"Result: {res_fmt}")
add_history(expr, res_fmt)
except OverflowError:
st.error("Result overflowed for given input")
except Exception as e:
st.error(f"Error: {e}")
# ---- History ----
if show_history:
st.markdown("### 📝 History")
if st.session_state.get("history"):
for i, line in enumerate(st.session_state.history, 1):
st.code(f"{i}. {line}")
if st.button("Clear history"):
st.session_state.history = []
st.toast("History cleared")
else:
st.caption("No calculations yet")
# ---- Footer ----
st.markdown("---")
st.caption("Built with Streamlit. Ready for Hugging Face Spaces.")