calculator / app.py
asif-coder's picture
Update app.py
c69baa3 verified
Raw
History Blame Contribute Delete
4.75 kB
import streamlit as st
import numpy as np
import math
import pandas as pd
import matplotlib.pyplot as plt
st.set_page_config(page_title="Advanced Calculator", layout="centered")
st.title("🧮 Advanced Calculator")
st.markdown("Multi-feature calculator for Hugging Face Streamlit deployment")
# -------------------------------
# Safe Expression Evaluation
# -------------------------------
allowed_names = {
k: getattr(math, k) for k in dir(math) if not k.startswith("_")
}
allowed_names.update({
"np": np,
"abs": abs,
"round": round
})
def safe_eval(expr):
try:
return eval(expr, {"__builtins__": {}}, allowed_names)
except Exception as e:
return f"Error: {e}"
# -------------------------------
# Sidebar Navigation
# -------------------------------
option = st.sidebar.selectbox(
"Select Calculator Mode",
["Basic / Scientific", "Unit Converter", "Function Plotter", "History"]
)
# Session history
if "history" not in st.session_state:
st.session_state.history = []
# -------------------------------
# BASIC & SCIENTIFIC CALCULATOR
# -------------------------------
if option == "Basic / Scientific":
st.subheader("Basic & Scientific Calculator")
expr = st.text_input(
"Enter mathematical expression",
placeholder="Example: sin(pi/2) + log(10)"
)
if st.button("Calculate"):
result = safe_eval(expr)
st.write("### Result:", result)
st.session_state.history.append({
"Expression": expr,
"Result": result
})
# -------------------------------
# UNIT CONVERTER
# -------------------------------
elif option == "Unit Converter":
st.subheader("Unit Converter")
conversion_type = st.selectbox(
"Select Conversion Type",
["Length", "Weight", "Temperature"]
)
value = st.number_input("Enter Value")
if conversion_type == "Length":
units = st.selectbox("Convert From", ["Meters", "Kilometers", "Miles"])
target = st.selectbox("Convert To", ["Meters", "Kilometers", "Miles"])
conversion = {
"Meters": 1,
"Kilometers": 1000,
"Miles": 1609.34
}
result = value * conversion[units] / conversion[target]
st.write("### Result:", result)
elif conversion_type == "Weight":
units = st.selectbox("Convert From", ["Grams", "Kilograms", "Pounds"])
target = st.selectbox("Convert To", ["Grams", "Kilograms", "Pounds"])
conversion = {
"Grams": 1,
"Kilograms": 1000,
"Pounds": 453.592
}
result = value * conversion[units] / conversion[target]
st.write("### Result:", result)
elif conversion_type == "Temperature":
units = st.selectbox("Convert From", ["Celsius", "Fahrenheit", "Kelvin"])
target = st.selectbox("Convert To", ["Celsius", "Fahrenheit", "Kelvin"])
def temp_convert(val, u, t):
if u == t:
return val
# Convert to Celsius first
if u == "Fahrenheit":
val = (val - 32) * 5/9
elif u == "Kelvin":
val = val - 273.15
# Convert from Celsius to target
if t == "Fahrenheit":
return val * 9/5 + 32
elif t == "Kelvin":
return val + 273.15
return val
st.write("### Result:", temp_convert(value, units, target))
# -------------------------------
# FUNCTION PLOTTER
# -------------------------------
elif option == "Function Plotter":
st.subheader("Function Plotter")
func_expr = st.text_input(
"Enter function in terms of x",
placeholder="Example: sin(x) or x**2 + 3*x"
)
x_min = st.number_input("X min", value=-10.0)
x_max = st.number_input("X max", value=10.0)
if st.button("Plot Function"):
try:
x = np.linspace(x_min, x_max, 400)
y = eval(func_expr, {"__builtins__": {}}, {**allowed_names, "x": x})
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_title(f"Plot of {func_expr}")
ax.grid(True)
st.pyplot(fig)
except Exception as e:
st.error(f"Plot Error: {e}")
# -------------------------------
# HISTORY
# -------------------------------
elif option == "History":
st.subheader("Calculation History")
if st.session_state.history:
df = pd.DataFrame(st.session_state.history)
st.dataframe(df, use_container_width=True)
if st.button("Clear History"):
st.session_state.history = []
else:
st.info("No calculations yet.")