Spaces:
Sleeping
Sleeping
import streamlit as st | |
import pandas as pd | |
import numpy as np | |
import matplotlib.pyplot as plt | |
import plotly.express as px | |
import plotly.graph_objects as go | |
from plotly.subplots import make_subplots | |
# Set page config | |
st.set_page_config( | |
page_title="HealthPredict AI", | |
page_icon="🏥", | |
layout="wide" | |
) | |
# Initialize session state variables if they don't exist | |
if 'current_step' not in st.session_state: | |
st.session_state.current_step = 0 | |
if 'assessment_data' not in st.session_state: | |
st.session_state.assessment_data = {} | |
if 'results_calculated' not in st.session_state: | |
st.session_state.results_calculated = False | |
if 'risk_data' not in st.session_state: | |
st.session_state.risk_data = [] | |
if 'health_score' not in st.session_state: | |
st.session_state.health_score = 0 | |
if 'recommendations' not in st.session_state: | |
st.session_state.recommendations = [] | |
# Define steps for the assessment | |
steps = [ | |
{"title": "Basic Information", "fields": ["age", "gender", "height", "weight"]}, | |
{"title": "Lifestyle", "fields": ["smoking_status", "alcohol_consumption", "physical_activity", "diet_type"]}, | |
{"title": "Medical History", "fields": ["family_history_diabetes", "family_history_heart_disease", | |
"family_history_hypertension", "previous_diagnoses"]}, | |
{"title": "Vital Signs", "fields": ["systolic_bp", "diastolic_bp", "resting_heart_rate"]}, | |
{"title": "Mental Health", "fields": ["stress_level", "sleep_quality", "sleep_duration"]}, | |
{"title": "Nutrition", "fields": ["daily_water_intake", "daily_fruit_veg_servings"]}, | |
{"title": "Additional Metrics", "fields": ["waist_circumference", "body_fat_percentage"]}, | |
{"title": "Additional Health Information", "fields": ["family_history_asthma", "family_history_obesity", | |
"family_history_depression", "allergies", | |
"chronic_pain", "mental_health_history"]} | |
] | |
# Function to calculate risk for different diseases | |
def calculate_risk(disease, data): | |
risk = 0 | |
if disease == "Diabetes": | |
if data.get("age", 0) > 45: risk += 10 | |
if float(data.get("bmi", 0)) > 30: risk += 15 | |
if data.get("family_history_diabetes", False): risk += 15 | |
if data.get("physical_activity", "") == "sedentary": risk += 10 | |
elif disease == "Heart Disease": | |
if data.get("age", 0) > 55: risk += 10 | |
if data.get("systolic_bp", 0) > 140 or data.get("diastolic_bp", 0) > 90: risk += 15 | |
if data.get("family_history_heart_disease", False): risk += 15 | |
if data.get("smoking_status", "") == "current": risk += 15 | |
elif disease == "Hypertension": | |
if data.get("systolic_bp", 0) > 140 or data.get("diastolic_bp", 0) > 90: risk += 20 | |
if data.get("family_history_hypertension", False): risk += 15 | |
if data.get("alcohol_consumption", "") == "heavy": risk += 10 | |
elif disease == "Obesity": | |
if float(data.get("bmi", 0)) > 30: risk += 30 | |
if data.get("physical_activity", "") == "sedentary": risk += 15 | |
if data.get("family_history_obesity", False): risk += 10 | |
elif disease == "Asthma": | |
if data.get("family_history_asthma", False): risk += 20 | |
if data.get("smoking_status", "") == "current": risk += 15 | |
allergies = data.get("allergies", "").lower() | |
if "pollen" in allergies or "dust" in allergies: risk += 10 | |
elif disease == "Depression": | |
if data.get("family_history_depression", False): risk += 15 | |
if data.get("stress_level", 0) > 7: risk += 15 | |
if data.get("sleep_quality", "") == "poor": risk += 10 | |
mental_health = data.get("mental_health_history", "").lower() | |
if "depression" in mental_health or "anxiety" in mental_health: risk += 20 | |
return min(risk, 100) | |
# Function to generate recommendations | |
def generate_recommendations(data): | |
recommendations = [] | |
if data.get("physical_activity", "") in ["sedentary", "light"]: | |
recommendations.append("Increase your daily physical activity to at least 30 minutes of moderate exercise.") | |
if data.get("daily_fruit_veg_servings", 0) < 5: | |
recommendations.append("Increase your daily intake of fruits and vegetables to at least 5 servings.") | |
if data.get("daily_water_intake", 0) < 2000: | |
recommendations.append("Increase your daily water intake to at least 2 liters (2000ml).") | |
if data.get("sleep_duration", 0) < 7 or data.get("sleep_quality", "") in ["poor", "fair"]: | |
recommendations.append("Aim for 7-9 hours of quality sleep per night to improve overall health.") | |
if data.get("stress_level", 0) > 7: | |
recommendations.append("Practice stress-reduction techniques such as meditation or deep breathing exercises.") | |
if data.get("smoking_status", "") == "current": | |
recommendations.append("Consider quitting smoking to significantly reduce your risk of heart disease and other health problems.") | |
if data.get("alcohol_consumption", "") == "heavy": | |
recommendations.append("Reduce alcohol consumption to moderate levels or consider abstaining completely.") | |
if float(data.get("bmi", 0)) > 25: | |
recommendations.append("Work on maintaining a healthy weight through a balanced diet and regular exercise.") | |
if data.get("chronic_pain", "") != "none": | |
recommendations.append("Consult with a healthcare professional about managing your chronic pain and consider physical therapy or pain management techniques.") | |
if data.get("mental_health_history", "") != "": | |
recommendations.append("Continue to prioritize your mental health. Consider regular check-ins with a mental health professional.") | |
return recommendations | |
# Function to calculate results | |
def calculate_results(): | |
# Calculate BMI if not already done | |
if "bmi" not in st.session_state.assessment_data: | |
height_m = st.session_state.assessment_data.get("height", 170) / 100 | |
weight = st.session_state.assessment_data.get("weight", 70) | |
bmi = weight / (height_m * height_m) | |
st.session_state.assessment_data["bmi"] = round(bmi, 1) | |
# Calculate risk for each disease | |
diseases = ["Diabetes", "Heart Disease", "Hypertension", "Obesity", "Asthma", "Depression"] | |
risk_data = [] | |
for disease in diseases: | |
risk = calculate_risk(disease, st.session_state.assessment_data) | |
risk_data.append({"disease": disease, "risk": risk}) | |
st.session_state.risk_data = risk_data | |
# Calculate overall health score (scaled to 0-100) | |
total_risk = sum(item["risk"] for item in risk_data) | |
health_score = round(100 * (1 - total_risk / (len(diseases) * 100))) | |
st.session_state.health_score = health_score | |
# Generate recommendations | |
st.session_state.recommendations = generate_recommendations(st.session_state.assessment_data) | |
st.session_state.results_calculated = True | |
# Function to handle form submission for each step | |
def process_step(step_index): | |
# Save form data to session state | |
for field in steps[step_index]["fields"]: | |
if field in st.session_state: | |
st.session_state.assessment_data[field] = st.session_state[field] | |
# Move to next step or calculate results | |
if step_index < len(steps) - 1: | |
st.session_state.current_step += 1 | |
else: | |
calculate_results() | |
# Function to go back to previous step | |
def go_back(): | |
if st.session_state.current_step > 0: | |
st.session_state.current_step -= 1 | |
# Function to restart assessment | |
def restart_assessment(): | |
st.session_state.current_step = 0 | |
st.session_state.assessment_data = {} | |
st.session_state.results_calculated = False | |
st.session_state.risk_data = [] | |
st.session_state.health_score = 0 | |
st.session_state.recommendations = [] | |
# Main app | |
def main(): | |
st.title("HealthPredict AI") | |
# Display results if calculated | |
if st.session_state.results_calculated: | |
st.header("Your Health Assessment Results") | |
# Create columns for layout | |
col1, col2 = st.columns(2) | |
with col1: | |
# Bar chart for disease risks | |
risk_df = pd.DataFrame(st.session_state.risk_data) | |
fig = px.bar( | |
risk_df, | |
x='disease', | |
y='risk', | |
title='Disease Risk Assessment', | |
labels={'disease': 'Disease', 'risk': 'Risk Score'}, | |
color='risk', | |
color_continuous_scale=[(0, 'green'), (0.5, 'yellow'), (1, 'red')] | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
with col2: | |
# Radar chart for disease risks | |
fig = go.Figure() | |
fig.add_trace(go.Scatterpolar( | |
r=[item["risk"] for item in st.session_state.risk_data], | |
theta=[item["disease"] for item in st.session_state.risk_data], | |
fill='toself', | |
name='Risk Profile' | |
)) | |
fig.update_layout( | |
polar=dict( | |
radialaxis=dict( | |
visible=True, | |
range=[0, 100] | |
) | |
), | |
title="Health Risk Radar" | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
# Health score gauge | |
fig = go.Figure(go.Indicator( | |
mode="gauge+number", | |
value=st.session_state.health_score, | |
domain={'x': [0, 1], 'y': [0, 1]}, | |
title={'text': "Overall Health Score"}, | |
gauge={ | |
'axis': {'range': [0, 100]}, | |
'bar': {'color': "darkblue"}, | |
'steps': [ | |
{'range': [0, 30], 'color': "red"}, | |
{'range': [30, 70], 'color': "yellow"}, | |
{'range': [70, 100], 'color': "green"} | |
] | |
} | |
)) | |
st.plotly_chart(fig, use_container_width=True) | |
# Recommendations | |
st.subheader("Recommendations") | |
for i, recommendation in enumerate(st.session_state.recommendations): | |
st.markdown(f"- {recommendation}") | |
# Button to restart assessment | |
if st.button("Retake Assessment"): | |
restart_assessment() | |
# Display assessment form if results not calculated | |
else: | |
current_step = st.session_state.current_step | |
step = steps[current_step] | |
st.header(f"Comprehensive Health Assessment") | |
st.subheader(f"{step['title']} (Step {current_step + 1} of {len(steps)})") | |
# Create a centered container with smaller width | |
col1, form_col, col3 = st.columns([1, 2, 1]) | |
with form_col: | |
with st.form(f"step_{current_step}_form"): | |
# Basic Information | |
if "age" in step["fields"]: | |
st.session_state.age = st.number_input("Age", 0, 120, st.session_state.assessment_data.get("age", 30)) | |
if "gender" in step["fields"]: | |
st.session_state.gender = st.selectbox("Gender", | |
["male", "female", "other"], | |
["male", "female", "other"].index(st.session_state.assessment_data.get("gender", "male"))) | |
if "height" in step["fields"]: | |
st.session_state.height = st.number_input("Height (cm)", 100, 250, st.session_state.assessment_data.get("height", 170)) | |
if "weight" in step["fields"]: | |
st.session_state.weight = st.number_input("Weight (kg)", 30, 300, st.session_state.assessment_data.get("weight", 70)) | |
# Lifestyle | |
if "smoking_status" in step["fields"]: | |
st.session_state.smoking_status = st.selectbox("Smoking Status", | |
["never", "former", "current"], | |
["never", "former", "current"].index(st.session_state.assessment_data.get("smoking_status", "never"))) | |
if "alcohol_consumption" in step["fields"]: | |
st.session_state.alcohol_consumption = st.selectbox("Alcohol Consumption", | |
["none", "moderate", "heavy"], | |
["none", "moderate", "heavy"].index(st.session_state.assessment_data.get("alcohol_consumption", "moderate"))) | |
if "physical_activity" in step["fields"]: | |
st.session_state.physical_activity = st.selectbox("Physical Activity Level", | |
["sedentary", "light", "moderate", "vigorous"], | |
["sedentary", "light", "moderate", "vigorous"].index(st.session_state.assessment_data.get("physical_activity", "moderate"))) | |
if "diet_type" in step["fields"]: | |
st.session_state.diet_type = st.selectbox("Diet Type", | |
["balanced", "high-carb", "high-protein", "vegetarian", "vegan"], | |
["balanced", "high-carb", "high-protein", "vegetarian", "vegan"].index(st.session_state.assessment_data.get("diet_type", "balanced"))) | |
# Medical History | |
if "family_history_diabetes" in step["fields"]: | |
st.session_state.family_history_diabetes = st.checkbox("Family History of Diabetes", st.session_state.assessment_data.get("family_history_diabetes", False)) | |
if "family_history_heart_disease" in step["fields"]: | |
st.session_state.family_history_heart_disease = st.checkbox("Family History of Heart Disease", st.session_state.assessment_data.get("family_history_heart_disease", False)) | |
if "family_history_hypertension" in step["fields"]: | |
st.session_state.family_history_hypertension = st.checkbox("Family History of Hypertension", st.session_state.assessment_data.get("family_history_hypertension", False)) | |
if "previous_diagnoses" in step["fields"]: | |
st.session_state.previous_diagnoses = st.text_input("Previous Diagnoses (comma separated)", st.session_state.assessment_data.get("previous_diagnoses", "")) | |
# Vital Signs | |
if "systolic_bp" in step["fields"]: | |
st.session_state.systolic_bp = st.number_input("Systolic Blood Pressure", 70, 220, st.session_state.assessment_data.get("systolic_bp", 120)) | |
if "diastolic_bp" in step["fields"]: | |
st.session_state.diastolic_bp = st.number_input("Diastolic Blood Pressure", 40, 130, st.session_state.assessment_data.get("diastolic_bp", 80)) | |
if "resting_heart_rate" in step["fields"]: | |
st.session_state.resting_heart_rate = st.number_input("Resting Heart Rate", 40, 120, st.session_state.assessment_data.get("resting_heart_rate", 70)) | |
# Mental Health | |
if "stress_level" in step["fields"]: | |
st.session_state.stress_level = st.slider("Stress Level (1-10)", 1, 10, st.session_state.assessment_data.get("stress_level", 5)) | |
if "sleep_quality" in step["fields"]: | |
st.session_state.sleep_quality = st.selectbox("Sleep Quality", | |
["poor", "fair", "good", "excellent"], | |
["poor", "fair", "good", "excellent"].index(st.session_state.assessment_data.get("sleep_quality", "good"))) | |
if "sleep_duration" in step["fields"]: | |
st.session_state.sleep_duration = st.number_input("Sleep Duration (hours)", 3.0, 12.0, float(st.session_state.assessment_data.get("sleep_duration", 7.0)), 0.5) | |
# Nutrition | |
if "daily_water_intake" in step["fields"]: | |
st.session_state.daily_water_intake = st.number_input("Daily Water Intake (ml)", 0, 5000, st.session_state.assessment_data.get("daily_water_intake", 2000), 100) | |
if "daily_fruit_veg_servings" in step["fields"]: | |
st.session_state.daily_fruit_veg_servings = st.number_input("Daily Fruit & Vegetable Servings", 0, 10, st.session_state.assessment_data.get("daily_fruit_veg_servings", 3)) | |
# Additional Metrics | |
if "waist_circumference" in step["fields"]: | |
st.session_state.waist_circumference = st.number_input("Waist Circumference (cm)", 50, 200, st.session_state.assessment_data.get("waist_circumference", 80)) | |
if "body_fat_percentage" in step["fields"]: | |
st.session_state.body_fat_percentage = st.number_input("Body Fat Percentage", 5.0, 50.0, float(st.session_state.assessment_data.get("body_fat_percentage", 20.0)), 0.5) | |
# Additional Health Information | |
if "family_history_asthma" in step["fields"]: | |
st.session_state.family_history_asthma = st.checkbox("Family History of Asthma", st.session_state.assessment_data.get("family_history_asthma", False)) | |
if "family_history_obesity" in step["fields"]: | |
st.session_state.family_history_obesity = st.checkbox("Family History of Obesity", st.session_state.assessment_data.get("family_history_obesity", False)) | |
if "family_history_depression" in step["fields"]: | |
st.session_state.family_history_depression = st.checkbox("Family History of Depression", st.session_state.assessment_data.get("family_history_depression", False)) | |
if "allergies" in step["fields"]: | |
st.session_state.allergies = st.text_input("Allergies (comma separated)", st.session_state.assessment_data.get("allergies", "")) | |
if "chronic_pain" in step["fields"]: | |
st.session_state.chronic_pain = st.selectbox("Chronic Pain Level", | |
["none", "mild", "moderate", "severe"], | |
["none", "mild", "moderate", "severe"].index(st.session_state.assessment_data.get("chronic_pain", "none"))) | |
if "mental_health_history" in step["fields"]: | |
st.session_state.mental_health_history = st.text_area("Mental Health History", st.session_state.assessment_data.get("mental_health_history", "")) | |
# Form buttons | |
col1, col2 = st.columns(2) | |
with col1: | |
if current_step > 0: | |
back_button = st.form_submit_button("Back") | |
if back_button: | |
go_back() | |
with col2: | |
if current_step < len(steps) - 1: | |
next_button = st.form_submit_button("Next") | |
if next_button: | |
process_step(current_step) | |
else: | |
submit_button = st.form_submit_button("Submit Assessment") | |
if submit_button: | |
process_step(current_step) | |
if __name__ == "__main__": | |
main() |