import streamlit as st
import math
import statistics
from datetime import datetime
# Page configuration
st.set_page_config(
page_title="Advanced Scientific Calculator",
page_icon="🧮",
layout="wide",
initial_sidebar_state="expanded"
)
# Custom CSS
st.markdown("""
""", unsafe_allow_html=True)
# Initialize session state
if 'history' not in st.session_state:
st.session_state.history = []
if 'memory' not in st.session_state:
st.session_state.memory = 0
if 'last_result' not in st.session_state:
st.session_state.last_result = 0
def add_to_history(expression, result):
"""Add calculation to history"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
st.session_state.history.append({
'time': timestamp,
'expression': expression,
'result': result
})
st.session_state.last_result = result
# Main title
st.title("🧮 Advanced Scientific Calculator")
st.markdown("---")
# Sidebar for calculator selection
st.sidebar.title("Calculator Modes")
mode = st.sidebar.selectbox(
"Select Mode:",
["Basic Operations", "Scientific Functions", "Statistical Operations",
"Unit Conversions", "Equation Solver", "Number System Conversion",
"Memory & History"]
)
st.sidebar.markdown("---")
st.sidebar.markdown(f"**Last Result:** `{st.session_state.last_result}`")
st.sidebar.markdown(f"**Memory:** `{st.session_state.memory}`")
# ============================================
# BASIC OPERATIONS
# ============================================
if mode == "Basic Operations":
st.header("➕ Basic Operations")
col1, col2, col3 = st.columns(3)
with col1:
num1 = st.number_input("First Number", value=0.0, format="%.6f", key="basic_num1")
with col2:
operation = st.selectbox(
"Operation",
["+", "-", "*", "/", "**", "%", "//"],
key="basic_op"
)
with col3:
num2 = st.number_input("Second Number", value=0.0, format="%.6f", key="basic_num2")
if st.button("Calculate", key="basic_calc"):
try:
if operation == "+":
result = num1 + num2
elif operation == "-":
result = num1 - num2
elif operation == "*":
result = num1 * num2
elif operation == "/":
if num2 == 0:
st.error("❌ Cannot divide by zero!")
result = None
else:
result = num1 / num2
elif operation == "**":
result = num1 ** num2
elif operation == "%":
if num2 == 0:
st.error("❌ Cannot perform modulus with zero!")
result = None
else:
result = num1 % num2
elif operation == "//":
if num2 == 0:
st.error("❌ Cannot divide by zero!")
result = None
else:
result = num1 // num2
if result is not None:
st.markdown(f'
Result: {result}
', unsafe_allow_html=True)
add_to_history(f"{num1} {operation} {num2}", result)
st.success("✅ Calculation complete!")
except Exception as e:
st.error(f"❌ Error: {e}")
# ============================================
# SCIENTIFIC FUNCTIONS
# ============================================
elif mode == "Scientific Functions":
st.header("🔬 Scientific Functions")
col1, col2 = st.columns(2)
with col1:
func = st.selectbox(
"Select Function",
["Square Root (√)", "Sine (sin)", "Cosine (cos)", "Tangent (tan)",
"Logarithm (log10)", "Natural Log (ln)", "Exponential (e^x)",
"Factorial (!)", "Absolute Value (|x|)", "Round", "Ceiling", "Floor"],
key="sci_func"
)
with col2:
num = st.number_input("Enter Number", value=0.0, format="%.6f", key="sci_num")
if st.button("Calculate", key="sci_calc"):
try:
if func == "Square Root (√)":
if num >= 0:
result = math.sqrt(num)
st.markdown(f'√{num} = {result}
', unsafe_allow_html=True)
add_to_history(f"√{num}", result)
else:
st.error("❌ Cannot calculate square root of negative number!")
elif func == "Sine (sin)":
result = math.sin(math.radians(num))
st.markdown(f'sin({num}°) = {result}
', unsafe_allow_html=True)
add_to_history(f"sin({num}°)", result)
elif func == "Cosine (cos)":
result = math.cos(math.radians(num))
st.markdown(f'cos({num}°) = {result}
', unsafe_allow_html=True)
add_to_history(f"cos({num}°)", result)
elif func == "Tangent (tan)":
result = math.tan(math.radians(num))
st.markdown(f'tan({num}°) = {result}
', unsafe_allow_html=True)
add_to_history(f"tan({num}°)", result)
elif func == "Logarithm (log10)":
if num > 0:
result = math.log10(num)
st.markdown(f'log₁₀({num}) = {result}
', unsafe_allow_html=True)
add_to_history(f"log₁₀({num})", result)
else:
st.error("❌ Logarithm requires positive number!")
elif func == "Natural Log (ln)":
if num > 0:
result = math.log(num)
st.markdown(f'ln({num}) = {result}
', unsafe_allow_html=True)
add_to_history(f"ln({num})", result)
else:
st.error("❌ Natural log requires positive number!")
elif func == "Exponential (e^x)":
result = math.exp(num)
st.markdown(f'e^{num} = {result}
', unsafe_allow_html=True)
add_to_history(f"e^{num}", result)
elif func == "Factorial (!)":
if num >= 0 and num == int(num):
result = math.factorial(int(num))
st.markdown(f'{int(num)}! = {result}
', unsafe_allow_html=True)
add_to_history(f"{int(num)}!", result)
else:
st.error("❌ Factorial requires non-negative integer!")
elif func == "Absolute Value (|x|)":
result = abs(num)
st.markdown(f'|{num}| = {result}
', unsafe_allow_html=True)
add_to_history(f"|{num}|", result)
elif func == "Round":
result = round(num)
st.markdown(f'Round({num}) = {result}
', unsafe_allow_html=True)
add_to_history(f"Round({num})", result)
elif func == "Ceiling":
result = math.ceil(num)
st.markdown(f'Ceil({num}) = {result}
', unsafe_allow_html=True)
add_to_history(f"Ceil({num})", result)
elif func == "Floor":
result = math.floor(num)
st.markdown(f'Floor({num}) = {result}
', unsafe_allow_html=True)
add_to_history(f"Floor({num})", result)
st.success("✅ Calculation complete!")
except Exception as e:
st.error(f"❌ Error: {e}")
# ============================================
# STATISTICAL OPERATIONS
# ============================================
elif mode == "Statistical Operations":
st.header("📊 Statistical Operations")
numbers_input = st.text_input(
"Enter numbers (separated by spaces or commas)",
value="1 2 3 4 5",
key="stat_input"
)
func = st.selectbox(
"Select Function",
["Mean", "Median", "Mode", "Standard Deviation", "Variance", "Sum", "Min", "Max", "Range"],
key="stat_func"
)
if st.button("Calculate", key="stat_calc"):
try:
# Parse numbers
numbers = [float(x.strip()) for x in numbers_input.replace(',', ' ').split() if x.strip()]
if not numbers:
st.error("❌ Please enter at least one number!")
else:
st.info(f"📝 Data: {numbers}")
st.info(f"📊 Count: {len(numbers)} numbers")
if func == "Mean":
result = statistics.mean(numbers)
st.markdown(f'Mean: {result}
', unsafe_allow_html=True)
add_to_history(f"Mean of {len(numbers)} numbers", result)
elif func == "Median":
result = statistics.median(numbers)
st.markdown(f'Median: {result}
', unsafe_allow_html=True)
add_to_history(f"Median of {len(numbers)} numbers", result)
elif func == "Mode":
try:
result = statistics.mode(numbers)
st.markdown(f'Mode: {result}
', unsafe_allow_html=True)
add_to_history(f"Mode of {len(numbers)} numbers", result)
except statistics.StatisticsError:
st.warning("⚠️ No unique mode found!")
elif func == "Standard Deviation":
if len(numbers) > 1:
result = statistics.stdev(numbers)
st.markdown(f'Standard Deviation: {result}
', unsafe_allow_html=True)
add_to_history(f"StdDev of {len(numbers)} numbers", result)
else:
st.error("❌ Need at least 2 numbers!")
elif func == "Variance":
if len(numbers) > 1:
result = statistics.variance(numbers)
st.markdown(f'Variance: {result}
', unsafe_allow_html=True)
add_to_history(f"Variance of {len(numbers)} numbers", result)
else:
st.error("❌ Need at least 2 numbers!")
elif func == "Sum":
result = sum(numbers)
st.markdown(f'Sum: {result}
', unsafe_allow_html=True)
add_to_history(f"Sum of {len(numbers)} numbers", result)
elif func == "Min":
result = min(numbers)
st.markdown(f'Minimum: {result}
', unsafe_allow_html=True)
add_to_history(f"Min of {len(numbers)} numbers", result)
elif func == "Max":
result = max(numbers)
st.markdown(f'Maximum: {result}
', unsafe_allow_html=True)
add_to_history(f"Max of {len(numbers)} numbers", result)
elif func == "Range":
result = max(numbers) - min(numbers)
st.markdown(f'Range: {result}
Min: {min(numbers)}, Max: {max(numbers)}
', unsafe_allow_html=True)
add_to_history(f"Range of {len(numbers)} numbers", result)
st.success("✅ Calculation complete!")
except ValueError:
st.error("❌ Invalid input! Please enter valid numbers.")
except Exception as e:
st.error(f"❌ Error: {e}")
# ============================================
# UNIT CONVERSIONS
# ============================================
elif mode == "Unit Conversions":
st.header("🔄 Unit Conversions")
conversion_type = st.selectbox(
"Select Conversion Type",
["Temperature", "Length", "Weight", "Speed", "Area"],
key="conv_type"
)
col1, col2 = st.columns(2)
with col1:
value = st.number_input("Enter Value", value=0.0, format="%.6f", key="conv_value")
with col2:
if conversion_type == "Temperature":
conversion = st.selectbox(
"Conversion",
["Celsius to Fahrenheit", "Fahrenheit to Celsius",
"Celsius to Kelvin", "Kelvin to Celsius",
"Fahrenheit to Kelvin", "Kelvin to Fahrenheit"],
key="temp_conv"
)
elif conversion_type == "Length":
conversion = st.selectbox(
"Conversion",
["Meters to Feet", "Feet to Meters", "Miles to Kilometers",
"Kilometers to Miles", "Inches to Centimeters", "Centimeters to Inches"],
key="length_conv"
)
elif conversion_type == "Weight":
conversion = st.selectbox(
"Conversion",
["Kilograms to Pounds", "Pounds to Kilograms", "Pounds to Ounces", "Ounces to Pounds"],
key="weight_conv"
)
elif conversion_type == "Speed":
conversion = st.selectbox(
"Conversion",
["km/h to mph", "mph to km/h", "m/s to km/h", "km/h to m/s"],
key="speed_conv"
)
elif conversion_type == "Area":
conversion = st.selectbox(
"Conversion",
["Square Meters to Square Feet", "Square Feet to Square Meters",
"Acres to Square Meters", "Square Meters to Acres"],
key="area_conv"
)
if st.button("Convert", key="conv_calc"):
try:
# Temperature conversions
if conversion == "Celsius to Fahrenheit":
result = (value * 9/5) + 32
st.markdown(f'{value}°C = {result}°F
', unsafe_allow_html=True)
elif conversion == "Fahrenheit to Celsius":
result = (value - 32) * 5/9
st.markdown(f'{value}°F = {result}°C
', unsafe_allow_html=True)
elif conversion == "Celsius to Kelvin":
result = value + 273.15
st.markdown(f'{value}°C = {result}K
', unsafe_allow_html=True)
elif conversion == "Kelvin to Celsius":
result = value - 273.15
st.markdown(f'{value}K = {result}°C
', unsafe_allow_html=True)
elif conversion == "Fahrenheit to Kelvin":
result = (value - 32) * 5/9 + 273.15
st.markdown(f'{value}°F = {result}K
', unsafe_allow_html=True)
elif conversion == "Kelvin to Fahrenheit":
result = (value - 273.15) * 9/5 + 32
st.markdown(f'{value}K = {result}°F
', unsafe_allow_html=True)
# Length conversions
elif conversion == "Meters to Feet":
result = value * 3.28084
st.markdown(f'{value} m = {result} ft
', unsafe_allow_html=True)
elif conversion == "Feet to Meters":
result = value / 3.28084
st.markdown(f'{value} ft = {result} m
', unsafe_allow_html=True)
elif conversion == "Miles to Kilometers":
result = value * 1.60934
st.markdown(f'{value} mi = {result} km
', unsafe_allow_html=True)
elif conversion == "Kilometers to Miles":
result = value / 1.60934
st.markdown(f'{value} km = {result} mi
', unsafe_allow_html=True)
elif conversion == "Inches to Centimeters":
result = value * 2.54
st.markdown(f'{value} in = {result} cm
', unsafe_allow_html=True)
elif conversion == "Centimeters to Inches":
result = value / 2.54
st.markdown(f'{value} cm = {result} in
', unsafe_allow_html=True)
# Weight conversions
elif conversion == "Kilograms to Pounds":
result = value * 2.20462
st.markdown(f'{value} kg = {result} lb
', unsafe_allow_html=True)
elif conversion == "Pounds to Kilograms":
result = value / 2.20462
st.markdown(f'{value} lb = {result} kg
', unsafe_allow_html=True)
elif conversion == "Pounds to Ounces":
result = value * 16
st.markdown(f'{value} lb = {result} oz
', unsafe_allow_html=True)
elif conversion == "Ounces to Pounds":
result = value / 16
st.markdown(f'{value} oz = {result} lb
', unsafe_allow_html=True)
# Speed conversions
elif conversion == "km/h to mph":
result = value / 1.60934
st.markdown(f'{value} km/h = {result} mph
', unsafe_allow_html=True)
elif conversion == "mph to km/h":
result = value * 1.60934
st.markdown(f'{value} mph = {result} km/h
', unsafe_allow_html=True)
elif conversion == "m/s to km/h":
result = value * 3.6
st.markdown(f'{value} m/s = {result} km/h
', unsafe_allow_html=True)
elif conversion == "km/h to m/s":
result = value / 3.6
st.markdown(f'{value} km/h = {result} m/s
', unsafe_allow_html=True)
# Area conversions
elif conversion == "Square Meters to Square Feet":
result = value * 10.7639
st.markdown(f'{value} m² = {result} ft²
', unsafe_allow_html=True)
elif conversion == "Square Feet to Square Meters":
result = value / 10.7639
st.markdown(f'{value} ft² = {result} m²
', unsafe_allow_html=True)
elif conversion == "Acres to Square Meters":
result = value * 4046.86
st.markdown(f'{value} acres = {result} m²
', unsafe_allow_html=True)
elif conversion == "Square Meters to Acres":
result = value / 4046.86
st.markdown(f'{value} m² = {result} acres
', unsafe_allow_html=True)
add_to_history(conversion, result)
st.success("✅ Conversion complete!")
except Exception as e:
st.error(f"❌ Error: {e}")
# ============================================
# EQUATION SOLVER
# ============================================
elif mode == "Equation Solver":
st.header("📐 Quadratic Equation Solver")
st.markdown("**Equation form:** ax² + bx + c = 0")
col1, col2, col3 = st.columns(3)
with col1:
a = st.number_input("Coefficient a", value=1.0, format="%.6f", key="eq_a")
with col2:
b = st.number_input("Coefficient b", value=0.0, format="%.6f", key="eq_b")
with col3:
c = st.number_input("Coefficient c", value=0.0, format="%.6f", key="eq_c")
if st.button("Solve Equation", key="eq_solve"):
if a == 0:
st.error("❌ Coefficient 'a' cannot be zero for quadratic equation!")
else:
try:
discriminant = b**2 - 4*a*c
st.markdown(f'', unsafe_allow_html=True)
st.markdown(f"**Equation:** {a}x² + {b}x + {c} = 0")
st.markdown(f"**Discriminant:** {discriminant}")
if discriminant > 0:
x1 = (-b + math.sqrt(discriminant)) / (2*a)
x2 = (-b - math.sqrt(discriminant)) / (2*a)
st.markdown(f"**Two real solutions:**")
st.markdown(f"- x₁ = {x1}")
st.markdown(f"- x₂ = {x2}")
result = x1
elif discriminant == 0:
x = -b / (2*a)
st.markdown(f"**One real solution:**")
st.markdown(f"- x = {x}")
result = x
else:
real_part = -b / (2*a)
imag_part = math.sqrt(abs(discriminant)) / (2*a)
st.markdown(f"**Two complex solutions:**")
st.markdown(f"- x₁ = {real_part} + {imag_part}i")
st.markdown(f"- x₂ = {real_part} - {imag_part}i")
result = real_part
st.markdown('
', unsafe_allow_html=True)
add_to_history(f"Quadratic: {a}x² + {b}x + {c} = 0", result)
st.success("✅ Equation solved!")
except Exception as e:
st.error(f"❌ Error: {e}")
# ============================================
# NUMBER SYSTEM CONVERSION
# ============================================
elif mode == "Number System Conversion":
st.header("🔢 Number System Conversion")
col1, col2 = st.columns(2)
with col1:
conversion = st.selectbox(
"Select Conversion",
["Decimal to Binary", "Decimal to Hexadecimal", "Decimal to Octal",
"Binary to Decimal", "Hexadecimal to Decimal", "Octal to Decimal"],
key="num_conv"
)
with col2:
if "Decimal to" in conversion:
num_input = st.number_input("Enter Decimal Number", value=0, step=1, key="num_dec")
else:
num_input = st.text_input("Enter Number", value="0", key="num_other")
if st.button("Convert", key="num_calc"):
try:
if conversion == "Decimal to Binary":
result = bin(int(num_input))
st.markdown(f'Binary: {result}
({result[2:]})
', unsafe_allow_html=True)
elif conversion == "Decimal to Hexadecimal":
result = hex(int(num_input))
st.markdown(f'Hexadecimal: {result}
({result[2:].upper()})
', unsafe_allow_html=True)
elif conversion == "Decimal to Octal":
result = oct(int(num_input))
st.markdown(f'Octal: {result}
({result[2:]})
', unsafe_allow_html=True)
elif conversion == "Binary to Decimal":
result = int(num_input, 2)
st.markdown(f'Decimal: {result}
', unsafe_allow_html=True)
st.session_state.last_result = result
elif conversion == "Hexadecimal to Decimal":
result = int(num_input, 16)
st.markdown(f'Decimal: {result}
', unsafe_allow_html=True)
st.session_state.last_result = result
elif conversion == "Octal to Decimal":
result = int(num_input, 8)
st.markdown(f'Decimal: {result}
', unsafe_allow_html=True)
st.session_state.last_result = result
st.success("✅ Conversion complete!")
except ValueError:
st.error("❌ Invalid input for selected number system!")
except Exception as e:
st.error(f"❌ Error: {e}")
# ============================================
# MEMORY & HISTORY
# ============================================
elif mode == "Memory & History":
st.header("💾 Memory & History")
# Memory Operations
st.subheader("Memory Operations")
col1, col2, col3, col4 = st.columns(4)
with col1:
mem_value = st.number_input("Value", value=0.0, key="mem_val")
if st.button("Store (MS)", key="mem_store"):
st.session_state.memory = mem_value
st.success(f"✅ Stored: {mem_value}")
with col2:
st.write("")
st.write("")
if st.button("Recall (MR)", key="mem_recall"):
st.info(f"Memory: {st.session_state.memory}")
with col3:
st.write("")
st.write("")
if st.button("Clear (MC)", key="mem_clear"):
st.session_state.memory = 0
st.success("✅ Memory cleared!")
with col4:
add_val = st.number_input("Add Value", value=0.0, key="mem_add_val")
if st.button("Add (M+)", key="mem_add"):
st.session_state.memory += add_val
st.success(f"✅ New memory: {st.session_state.memory}")
st.markdown("---")
# History
st.subheader("Calculation History")
col1, col2 = st.columns([3, 1])
with col2:
if st.button("Clear History", key="hist_clear"):
st.session_state.history = []
st.success("✅ History cleared!")
if st.session_state.history:
st.markdown(f"**Total Calculations:** {len(st.session_state.history)}")
# Show last 20 calculations
for i, item in enumerate(reversed(st.session_state.history[-20:]), 1):
st.markdown(f"""
#{len(st.session_state.history) - i + 1}
[{item['time']}]
{item['expression']} = {item['result']}
""", unsafe_allow_html=True)
else:
st.info("📝 No calculation history yet. Start calculating!")
# Footer
st.markdown("---")
st.markdown("""
🧮 Advanced Scientific Calculator | Built with Streamlit
Created for Hugging Face Spaces
""", unsafe_allow_html=True)