Kamil-Ejaz's picture
Create app.py
a2e80a0 verified
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("""
<style>
.main {
padding: 0rem 1rem;
}
.stButton>button {
width: 100%;
background-color: #4CAF50;
color: white;
padding: 10px;
border-radius: 5px;
border: none;
font-size: 16px;
}
.stButton>button:hover {
background-color: #45a049;
}
.result-box {
background-color: #f0f2f6;
padding: 20px;
border-radius: 10px;
border-left: 5px solid #4CAF50;
margin: 10px 0;
}
.history-item {
background-color: #e8f4f8;
padding: 10px;
border-radius: 5px;
margin: 5px 0;
}
</style>
""", 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'<div class="result-box"><h2>Result: {result}</h2></div>', 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'<div class="result-box"><h2>โˆš{num} = {result}</h2></div>', 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'<div class="result-box"><h2>sin({num}ยฐ) = {result}</h2></div>', unsafe_allow_html=True)
add_to_history(f"sin({num}ยฐ)", result)
elif func == "Cosine (cos)":
result = math.cos(math.radians(num))
st.markdown(f'<div class="result-box"><h2>cos({num}ยฐ) = {result}</h2></div>', unsafe_allow_html=True)
add_to_history(f"cos({num}ยฐ)", result)
elif func == "Tangent (tan)":
result = math.tan(math.radians(num))
st.markdown(f'<div class="result-box"><h2>tan({num}ยฐ) = {result}</h2></div>', 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'<div class="result-box"><h2>logโ‚โ‚€({num}) = {result}</h2></div>', 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'<div class="result-box"><h2>ln({num}) = {result}</h2></div>', 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'<div class="result-box"><h2>e^{num} = {result}</h2></div>', 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'<div class="result-box"><h2>{int(num)}! = {result}</h2></div>', 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'<div class="result-box"><h2>|{num}| = {result}</h2></div>', unsafe_allow_html=True)
add_to_history(f"|{num}|", result)
elif func == "Round":
result = round(num)
st.markdown(f'<div class="result-box"><h2>Round({num}) = {result}</h2></div>', unsafe_allow_html=True)
add_to_history(f"Round({num})", result)
elif func == "Ceiling":
result = math.ceil(num)
st.markdown(f'<div class="result-box"><h2>Ceil({num}) = {result}</h2></div>', unsafe_allow_html=True)
add_to_history(f"Ceil({num})", result)
elif func == "Floor":
result = math.floor(num)
st.markdown(f'<div class="result-box"><h2>Floor({num}) = {result}</h2></div>', 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'<div class="result-box"><h2>Mean: {result}</h2></div>', unsafe_allow_html=True)
add_to_history(f"Mean of {len(numbers)} numbers", result)
elif func == "Median":
result = statistics.median(numbers)
st.markdown(f'<div class="result-box"><h2>Median: {result}</h2></div>', 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'<div class="result-box"><h2>Mode: {result}</h2></div>', 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'<div class="result-box"><h2>Standard Deviation: {result}</h2></div>', 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'<div class="result-box"><h2>Variance: {result}</h2></div>', 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'<div class="result-box"><h2>Sum: {result}</h2></div>', unsafe_allow_html=True)
add_to_history(f"Sum of {len(numbers)} numbers", result)
elif func == "Min":
result = min(numbers)
st.markdown(f'<div class="result-box"><h2>Minimum: {result}</h2></div>', unsafe_allow_html=True)
add_to_history(f"Min of {len(numbers)} numbers", result)
elif func == "Max":
result = max(numbers)
st.markdown(f'<div class="result-box"><h2>Maximum: {result}</h2></div>', 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'<div class="result-box"><h2>Range: {result}</h2><p>Min: {min(numbers)}, Max: {max(numbers)}</p></div>', 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'<div class="result-box"><h2>{value}ยฐC = {result}ยฐF</h2></div>', unsafe_allow_html=True)
elif conversion == "Fahrenheit to Celsius":
result = (value - 32) * 5/9
st.markdown(f'<div class="result-box"><h2>{value}ยฐF = {result}ยฐC</h2></div>', unsafe_allow_html=True)
elif conversion == "Celsius to Kelvin":
result = value + 273.15
st.markdown(f'<div class="result-box"><h2>{value}ยฐC = {result}K</h2></div>', unsafe_allow_html=True)
elif conversion == "Kelvin to Celsius":
result = value - 273.15
st.markdown(f'<div class="result-box"><h2>{value}K = {result}ยฐC</h2></div>', unsafe_allow_html=True)
elif conversion == "Fahrenheit to Kelvin":
result = (value - 32) * 5/9 + 273.15
st.markdown(f'<div class="result-box"><h2>{value}ยฐF = {result}K</h2></div>', unsafe_allow_html=True)
elif conversion == "Kelvin to Fahrenheit":
result = (value - 273.15) * 9/5 + 32
st.markdown(f'<div class="result-box"><h2>{value}K = {result}ยฐF</h2></div>', unsafe_allow_html=True)
# Length conversions
elif conversion == "Meters to Feet":
result = value * 3.28084
st.markdown(f'<div class="result-box"><h2>{value} m = {result} ft</h2></div>', unsafe_allow_html=True)
elif conversion == "Feet to Meters":
result = value / 3.28084
st.markdown(f'<div class="result-box"><h2>{value} ft = {result} m</h2></div>', unsafe_allow_html=True)
elif conversion == "Miles to Kilometers":
result = value * 1.60934
st.markdown(f'<div class="result-box"><h2>{value} mi = {result} km</h2></div>', unsafe_allow_html=True)
elif conversion == "Kilometers to Miles":
result = value / 1.60934
st.markdown(f'<div class="result-box"><h2>{value} km = {result} mi</h2></div>', unsafe_allow_html=True)
elif conversion == "Inches to Centimeters":
result = value * 2.54
st.markdown(f'<div class="result-box"><h2>{value} in = {result} cm</h2></div>', unsafe_allow_html=True)
elif conversion == "Centimeters to Inches":
result = value / 2.54
st.markdown(f'<div class="result-box"><h2>{value} cm = {result} in</h2></div>', unsafe_allow_html=True)
# Weight conversions
elif conversion == "Kilograms to Pounds":
result = value * 2.20462
st.markdown(f'<div class="result-box"><h2>{value} kg = {result} lb</h2></div>', unsafe_allow_html=True)
elif conversion == "Pounds to Kilograms":
result = value / 2.20462
st.markdown(f'<div class="result-box"><h2>{value} lb = {result} kg</h2></div>', unsafe_allow_html=True)
elif conversion == "Pounds to Ounces":
result = value * 16
st.markdown(f'<div class="result-box"><h2>{value} lb = {result} oz</h2></div>', unsafe_allow_html=True)
elif conversion == "Ounces to Pounds":
result = value / 16
st.markdown(f'<div class="result-box"><h2>{value} oz = {result} lb</h2></div>', unsafe_allow_html=True)
# Speed conversions
elif conversion == "km/h to mph":
result = value / 1.60934
st.markdown(f'<div class="result-box"><h2>{value} km/h = {result} mph</h2></div>', unsafe_allow_html=True)
elif conversion == "mph to km/h":
result = value * 1.60934
st.markdown(f'<div class="result-box"><h2>{value} mph = {result} km/h</h2></div>', unsafe_allow_html=True)
elif conversion == "m/s to km/h":
result = value * 3.6
st.markdown(f'<div class="result-box"><h2>{value} m/s = {result} km/h</h2></div>', unsafe_allow_html=True)
elif conversion == "km/h to m/s":
result = value / 3.6
st.markdown(f'<div class="result-box"><h2>{value} km/h = {result} m/s</h2></div>', unsafe_allow_html=True)
# Area conversions
elif conversion == "Square Meters to Square Feet":
result = value * 10.7639
st.markdown(f'<div class="result-box"><h2>{value} mยฒ = {result} ftยฒ</h2></div>', unsafe_allow_html=True)
elif conversion == "Square Feet to Square Meters":
result = value / 10.7639
st.markdown(f'<div class="result-box"><h2>{value} ftยฒ = {result} mยฒ</h2></div>', unsafe_allow_html=True)
elif conversion == "Acres to Square Meters":
result = value * 4046.86
st.markdown(f'<div class="result-box"><h2>{value} acres = {result} mยฒ</h2></div>', unsafe_allow_html=True)
elif conversion == "Square Meters to Acres":
result = value / 4046.86
st.markdown(f'<div class="result-box"><h2>{value} mยฒ = {result} acres</h2></div>', 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'<div class="result-box">', 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('</div>', 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'<div class="result-box"><h2>Binary: {result}</h2><p>({result[2:]})</p></div>', unsafe_allow_html=True)
elif conversion == "Decimal to Hexadecimal":
result = hex(int(num_input))
st.markdown(f'<div class="result-box"><h2>Hexadecimal: {result}</h2><p>({result[2:].upper()})</p></div>', unsafe_allow_html=True)
elif conversion == "Decimal to Octal":
result = oct(int(num_input))
st.markdown(f'<div class="result-box"><h2>Octal: {result}</h2><p>({result[2:]})</p></div>', unsafe_allow_html=True)
elif conversion == "Binary to Decimal":
result = int(num_input, 2)
st.markdown(f'<div class="result-box"><h2>Decimal: {result}</h2></div>', unsafe_allow_html=True)
st.session_state.last_result = result
elif conversion == "Hexadecimal to Decimal":
result = int(num_input, 16)
st.markdown(f'<div class="result-box"><h2>Decimal: {result}</h2></div>', unsafe_allow_html=True)
st.session_state.last_result = result
elif conversion == "Octal to Decimal":
result = int(num_input, 8)
st.markdown(f'<div class="result-box"><h2>Decimal: {result}</h2></div>', 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"""
<div class="history-item">
<strong>#{len(st.session_state.history) - i + 1}</strong>
[{item['time']}]<br>
<code>{item['expression']} = {item['result']}</code>
</div>
""", unsafe_allow_html=True)
else:
st.info("๐Ÿ“ No calculation history yet. Start calculating!")
# Footer
st.markdown("---")
st.markdown("""
<div style='text-align: center; color: gray;'>
<p>๐Ÿงฎ Advanced Scientific Calculator | Built with Streamlit</p>
<p>Created for Hugging Face Spaces</p>
</div>
""", unsafe_allow_html=True)