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)