Moeer/streamlit-calculator
0
1import streamlit as st2import math3import re4 5# Session state for history6if 'history' not in st.session_state:7 st.session_state.history = []8 9# Title and description10st.title("๐งฎ Multi-Mode Calculator")11st.markdown("Switch between different calculator modes using the tabs below.")12 13# Helper function for safe evaluation14def safe_eval(expr, mode):15 try:16 # Only allow math functions in scientific mode17 allowed_names = {18 **{k: v for k, v in math.__dict__.items() if not k.startswith("__")},19 "abs": abs,20 "round": round21 } if mode == "Scientific" else {}22 return eval(expr, {"__builtins__": {}}, allowed_names)23 except Exception as e:24 return f"Error: {e}"25 26# Tabs for calculator modes27tab1, tab2, tab3, tab4 = st.tabs(["Basic", "Scientific", "Programmer", "Custom"])28 29with tab1:30 st.subheader("๐งพ Basic Calculator")31 num1 = st.number_input("First number", key="basic_num1")32 num2 = st.number_input("Second number", key="basic_num2")33 operation = st.selectbox("Operation", ["Add", "Subtract", "Multiply", "Divide"])34 35 if st.button("Calculate", key="basic_calc"):36 with st.spinner("Calculating..."):37 if operation == "Add":38 result = num1 + num239 elif operation == "Subtract":40 result = num1 - num241 elif operation == "Multiply":42 result = num1 * num243 elif operation == "Divide":44 result = "Error: Division by zero" if num2 == 0 else num1 / num245 st.session_state.history.append(f"{num1} {operation} {num2} = {result}")46 st.success(f"Result: {result}")47 48with tab2:49 st.subheader("๐ Scientific Calculator")50 expr = st.text_input("Enter expression (e.g., sin(1), log(10), 2**3)", key="sci_expr")51 52 if expr:53 with st.spinner("Evaluating..."):54 result = safe_eval(expr, mode="Scientific")55 st.session_state.history.append(f"{expr} = {result}")56 if isinstance(result, str) and result.startswith("Error"):57 st.error(result)58 else:59 st.success(f"Result: {result}")60 61with tab3:62 st.subheader("๐งโ๐ป Programmer Calculator")63 number = st.text_input("Enter number", key="prog_input")64 base = st.selectbox("Convert from", ["Binary", "Decimal", "Hexadecimal"])65 66 def convert_programmer(num_str, base):67 try:68 if base == "Binary":69 dec = int(num_str, 2)70 elif base == "Hexadecimal":71 dec = int(num_str, 16)72 else:73 dec = int(num_str)74 return {75 "Binary": bin(dec),76 "Decimal": dec,77 "Hexadecimal": hex(dec)78 }79 except ValueError:80 return {"Error": "Invalid number format."}81 82 if number:83 with st.spinner("Converting..."):84 result = convert_programmer(number, base)85 if "Error" in result:86 st.error(result["Error"])87 else:88 st.session_state.history.append(f"{number} ({base}) => {result}")89 st.code(result, language="json")90 91with tab4:92 st.subheader("๐งฉ Custom Mode")93 st.markdown("Input any mathematical formula using standard Python syntax.")94 user_expr = st.text_area("Formula input", placeholder="e.g., 3 * (2 + 5) / sqrt(9)")95 96 if user_expr:97 with st.spinner("Processing..."):98 result = safe_eval(user_expr, mode="Scientific")99 st.session_state.history.append(f"{user_expr} = {result}")100 if isinstance(result, str) and result.startswith("Error"):101 st.error(result)102 else:103 st.success(f"Result: {result}")104 105# Calculation History106with st.expander("๐ Calculation History"):107 for entry in st.session_state.history:108 st.write(entry)109 if st.button("Clear History"):110 st.session_state.history.clear()111 st.success("History cleared.")112 113# Footer114st.caption("๐น Built with Streamlit โ Responsive and lightweight calculator app.")115 