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()