Vivekananda1010's picture
Update app.py
6e172bb verified
Raw
History Blame Contribute Delete
7.91 kB
import streamlit as st
import joblib, json, pandas as pd, time
from datetime import datetime
from io import BytesIO
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.pagesizes import letter
st.set_page_config(page_title="Stroke Risk Predictor", page_icon="icon2.png", layout="centered")
# ---------- SESSION ----------
if "show_reset" not in st.session_state:
st.session_state.show_reset = False
# ---------- STYLE ----------
st.markdown("""
<style>
body { background: linear-gradient(135deg,#0f172a,#020617); }
.card {
background:#0b1220;
border-radius:18px;
padding:20px 22px;
box-shadow:0 16px 28px rgba(0,0,0,.45);
margin-bottom:14px;
color:#e5ecff;
}
/* Primary (Check Risk) */
.stButton>button {
width:100%;
border-radius:12px;
background:linear-gradient(135deg,#3b82f6,#06b6d4);
color:#ffffff;
padding:12px 16px;
font-weight:700;
border:0;
box-shadow:0 10px 22px rgba(59,130,246,.25);
transition:.2s ease-in-out;
}
.stButton>button:hover {
transform:translateY(-2px);
box-shadow:0 14px 28px rgba(59,130,246,.35);
}
/* Better secondary button (Reset) */
.reset-btn button{
width:100%;
border-radius:14px;
background:#111827 !important;
color:#e5e7eb !important;
border:1px solid #2a2f3a !important;
padding:12px 16px;
font-weight:600;
box-shadow:0 6px 16px rgba(0,0,0,.25);
}
.reset-btn button:hover{
background:#1f2937 !important;
border-color:#3b4251 !important;
}
.result-box {
background:#020617;
border-radius:20px;
padding:22px;
border:1px solid #1f2937;
text-align:center;
}
</style>
""", unsafe_allow_html=True)
# ---------- HEADER ----------
st.markdown("""
<div class="card">
<h3 style="text-align:center;">🧠 Stroke Risk Predictor</h3>
<p style="text-align:center;color:#9ca3af;">This tool estimates possible stroke risk — not a diagnosis.</p>
</div>
""", unsafe_allow_html=True)
# ---------- MODEL ----------
model = joblib.load("stroke_model.pkl")
thr = json.load(open("threshold.json"))["threshold"]
MODEL_COLUMNS = [
"gender","age","hypertension","heart_disease",
"ever_married","work_type","Residence_type",
"avg_glucose_level","bmi","smoking_status"
]
def predict(data):
df = pd.DataFrame([data])[MODEL_COLUMNS]
prob = model.predict_proba(df)[0][1]
return prob, int(prob >= thr)
# ===============================
# INPUTS
# ===============================
st.markdown('<div class="card">', unsafe_allow_html=True)
st.subheader("🧑 Personal Details")
gender = st.selectbox("Gender", ["Male","Female","Other"])
age = st.slider("Age", 1, 100, 45)
ever_married = st.checkbox("Married")
st.markdown('</div>', unsafe_allow_html=True)
st.markdown('<div class="card">', unsafe_allow_html=True)
st.subheader("🩺 Health Info")
hypertension = st.checkbox("Hypertension")
heart_disease = st.checkbox("Heart Disease")
avg_glucose = st.slider("Average Glucose", 40.0, 300.0, 100.0)
bmi = st.slider("BMI", 10.0, 60.0, 24.0)
st.markdown('</div>', unsafe_allow_html=True)
st.markdown('<div class="card">', unsafe_allow_html=True)
st.subheader("🏡 Lifestyle")
work_type = st.radio("Work", ["Private","Self-employed","Govt_job","child","Never_worked"], horizontal=True)
res_type = st.radio("Residence", ["Urban","Rural"], horizontal=True)
smoking = st.radio("Smoking", ["never smoked","formerly smoked","smokes","Unknown"], horizontal=True)
colA, colB = st.columns(2)
with colA:
predict_btn = st.button("✨ Check Risk")
# show reset as soon as prediction is attempted
if predict_btn:
st.session_state.show_reset = True
with colB:
reset_btn = None
if st.session_state.show_reset:
st.markdown('<div class="reset-btn">', unsafe_allow_html=True)
reset_btn = st.button(" Reset ", key="reset", help="Clear all inputs")
st.markdown('</div>', unsafe_allow_html=True)
# ---------- RESET ----------
if reset_btn:
st.session_state.clear()
st.rerun()
# ---------- CONVERT ----------
ever_married = "Yes" if ever_married else "No"
hypertension = 1 if hypertension else 0
heart_disease = 1 if heart_disease else 0
# ===============================
# RESULT
# ===============================
if predict_btn:
data = {
"gender": gender,
"age": age,
"hypertension": hypertension,
"heart_disease": heart_disease,
"ever_married": ever_married,
"work_type": work_type,
"Residence_type": res_type,
"avg_glucose_level": avg_glucose,
"bmi": bmi,
"smoking_status": smoking
}
prob, pred = predict(data)
percent = round(prob * 100, 1)
with st.spinner("Analyzing…"):
time.sleep(0.8)
st.divider()
st.markdown('<div class="card"><h4>📝 Summary</h4></div>', unsafe_allow_html=True)
c1, c2 = st.columns(2)
with c1:
st.write(f"**Gender:** {gender}")
st.write(f"**Age:** {age}")
st.write(f"**Married:** {ever_married}")
st.write(f"**Residence:** {res_type}")
with c2:
st.write(f"**Hypertension:** {hypertension}")
st.write(f"**Heart Disease:** {heart_disease}")
st.write(f"**Glucose:** {avg_glucose}")
st.write(f"**BMI:** {bmi}")
st.markdown(f"""
<div class="result-box">
<h4>Estimated Risk</h4>
<h1>{percent}%</h1>
</div>
""", unsafe_allow_html=True)
bar = st.progress(0)
for i in range(int(percent)):
time.sleep(0.01)
bar.progress(i + 1)
# ---------- SMART SUGGESTIONS ----------
reasons, tips = [], []
if avg_glucose > 125: reasons.append("High glucose increases stroke risk"); tips.append("Reduce sugar and walk daily.")
if bmi >= 30: reasons.append("High BMI strains the heart"); tips.append("Aim gradual weight loss.")
if hypertension: reasons.append("Blood pressure increases stroke risk"); tips.append("Reduce salt — monitor BP.")
if heart_disease: reasons.append("Heart disease increases clot risk"); tips.append("Follow cardiac treatment regularly.")
if smoking == "smokes": reasons.append("Smoking damages blood vessels"); tips.append("Quitting sharply reduces risk.")
if not reasons: reasons.append("Fewer major risk factors detected"); tips.append("Maintain activity, diet, and checkups.")
st.markdown('<div class="card"><h4>🧪 Why this score?</h4></div>', unsafe_allow_html=True)
for r in reasons:
st.write("🔎 " + r)
st.markdown('<div class="card"><h4>💡 Suggestions</h4></div>', unsafe_allow_html=True)
for t in tips:
st.write("✅ " + t)
if pred:
st.warning("⚠️ Higher risk — please consult a medical professional.")
else:
st.success("💚 Lower risk — keep following healthy habits.")
# ---------- PDF ----------
def create_pdf():
buffer = BytesIO()
styles = getSampleStyleSheet()
doc = SimpleDocTemplate(buffer, pagesize=letter)
content = [
Paragraph("<b>Stroke Risk Report</b>", styles["Title"]),
Spacer(1, 10),
Paragraph(f"Risk: {percent}%", styles["Normal"]),
Paragraph(f"Gender: {gender}", styles["Normal"]),
Paragraph(f"Age: {age}", styles["Normal"]),
Paragraph(f"Glucose: {avg_glucose}", styles["Normal"]),
Paragraph(f"BMI: {bmi}", styles["Normal"]),
Spacer(1, 10),
Paragraph("<b>Recommendations:</b>", styles["Heading2"]),
]
for t in tips:
content.append(Paragraph("• " + t, styles["Normal"]))
doc.build(content)
buffer.seek(0)
return buffer
st.download_button(
"📄 Download Report (PDF)",
create_pdf(),
file_name="stroke_report.pdf",
mime="application/pdf"
)