""" Alertra Health Monitoring - Streamlit Demo App Version: 1.0.0 Developer: Cancer Survivor Healthcare AI Team Beautiful, interactive demo for YC presentation """ import streamlit as st import pandas as pd import numpy as np import plotly.graph_objects as go import plotly.express as px from datetime import datetime, timedelta import json import requests import time # Page configuration st.set_page_config( page_title="Alertra Health Monitor", page_icon="🏥", layout="wide", initial_sidebar_state="expanded" ) # Custom CSS for better styling st.markdown(""" """, unsafe_allow_html=True) # Initialize session state if 'prediction_history' not in st.session_state: st.session_state.prediction_history = [] if 'current_patient' not in st.session_state: st.session_state.current_patient = "Demo Patient" # Demo scenarios DEMO_SCENARIOS = { "Normal Day": { 'heart_rate': 74, 'systolic_bp': 128, 'diastolic_bp': 82, 'sleep_hours': 7.2, 'steps': 6800, 'spo2': 97, 'weight_lbs': 178, 'medication_taken': 1, 'pain_level': 2 }, "Early Warning": { 'heart_rate': 92, 'systolic_bp': 145, 'diastolic_bp': 88, 'sleep_hours': 5.5, 'steps': 3200, 'spo2': 94, 'weight_lbs': 176, 'medication_taken': 0, 'pain_level': 5 }, "🚨 Medical Emergency": { 'heart_rate': 125, 'systolic_bp': 185, 'diastolic_bp': 95, 'sleep_hours': 3.5, 'steps': 500, 'spo2': 86, 'weight_lbs': 174, 'medication_taken': 0, 'pain_level': 8 }, "Recovery Monitoring": { 'heart_rate': 68, 'systolic_bp': 132, 'diastolic_bp': 79, 'sleep_hours': 6.8, 'steps': 4200, 'spo2': 96, 'weight_lbs': 172, 'medication_taken': 1, 'pain_level': 3 } } def make_prediction(health_data): """Make prediction using local ML logic (fallback if API not available)""" # Enhanced features pulse_pressure = health_data['systolic_bp'] - health_data['diastolic_bp'] activity_sleep_ratio = health_data['steps'] / (health_data['sleep_hours'] + 0.1) # Safety rules (critical overrides) safety_triggered = False safety_message = "" if health_data['spo2'] < 88: safety_triggered = True safety_message = f"CRITICAL: SpO2 {health_data['spo2']}% (<88%)" elif health_data['heart_rate'] > 120: safety_triggered = True safety_message = f"HIGH: Heart rate {health_data['heart_rate']} (>120)" elif health_data['systolic_bp'] > 180: safety_triggered = True safety_message = f"HIGH: Blood pressure {health_data['systolic_bp']} (>180)" elif health_data['pain_level'] > 7: safety_triggered = True safety_message = f"HIGH: Pain level {health_data['pain_level']} (>7)" # Simple scoring algorithm risk_score = 0 # Heart rate risk if health_data['heart_rate'] > 100: risk_score += 0.3 elif health_data['heart_rate'] < 60: risk_score += 0.2 # Blood pressure risk if health_data['systolic_bp'] > 140: risk_score += 0.3 elif health_data['systolic_bp'] < 100: risk_score += 0.2 # SpO2 risk if health_data['spo2'] < 95: risk_score += 0.4 # Pain risk if health_data['pain_level'] > 5: risk_score += 0.2 # Medication compliance if health_data['medication_taken'] == 0: risk_score += 0.3 # Sleep and activity if health_data['sleep_hours'] < 6: risk_score += 0.1 if health_data['steps'] < 3000: risk_score += 0.1 # Final prediction if safety_triggered: prediction = "Alert" confidence = 0.95 ml_prob_alert = 0.95 ml_prob_normal = 0.05 decision_reason = f"SAFETY OVERRIDE: {safety_message}" elif risk_score > 0.5: prediction = "Alert" confidence = min(0.6 + risk_score * 0.3, 0.95) ml_prob_alert = confidence ml_prob_normal = 1 - confidence decision_reason = f"ML Model Prediction (confidence: {confidence:.3f})" else: prediction = "Normal" confidence = max(0.8 - risk_score * 0.2, 0.6) ml_prob_normal = confidence ml_prob_alert = 1 - confidence decision_reason = f"ML Model Prediction (confidence: {confidence:.3f})" # Generate recommendations recommendations = [] if prediction == "Alert": recommendations.append("🚨 IMMEDIATE ATTENTION NEEDED") if health_data['spo2'] < 88: recommendations.append("• CRITICAL: Oxygen levels dangerously low - seek emergency care") if health_data['heart_rate'] > 120: recommendations.append("• Heart rate very high - rest immediately and monitor") if health_data['systolic_bp'] > 180: recommendations.append("• Blood pressure critically high - medical attention required") if health_data['medication_taken'] == 0: recommendations.append("• Take missed medications immediately") recommendations.append("• Family and healthcare provider automatically notified") else: recommendations.append("✅ Health patterns within normal range") if health_data['steps'] > 8000: recommendations.append("• Great activity level - keep it up!") if health_data['sleep_hours'] >= 7: recommendations.append("• Good sleep habits maintained") if health_data['medication_taken'] == 1: recommendations.append("• Excellent medication compliance") recommendations.append("• Continue current healthy lifestyle") return { 'prediction': prediction, 'confidence': confidence, 'ml_probability_normal': ml_prob_normal, 'ml_probability_alert': ml_prob_alert, 'safety_triggered': safety_triggered, 'decision_reason': decision_reason, 'recommendations': recommendations, 'timestamp': datetime.now().isoformat(), 'risk_score': risk_score } def create_gauge_chart(value, title, min_val=0, max_val=100, threshold=None): """Create a gauge chart for metrics""" # Determine color based on value and threshold if threshold: if isinstance(threshold, dict): if value < threshold.get('low', 0): color = "red" elif value > threshold.get('high', 100): color = "red" else: color = "green" else: color = "red" if value > threshold else "green" else: color = "blue" fig = go.Figure(go.Indicator( mode = "gauge+number+delta", value = value, domain = {'x': [0, 1], 'y': [0, 1]}, title = {'text': title}, gauge = { 'axis': {'range': [None, max_val]}, 'bar': {'color': color}, 'steps': [ {'range': [0, max_val*0.7], 'color': "lightgray"}, {'range': [max_val*0.7, max_val], 'color': "gray"} ], 'threshold': { 'line': {'color': "red", 'width': 4}, 'thickness': 0.75, 'value': threshold if isinstance(threshold, (int, float)) else max_val } } )) fig.update_layout(height=200, margin=dict(l=20, r=20, t=40, b=20)) return fig def main(): # Header st.markdown('

🏥 Alertra Health Monitor

', unsafe_allow_html=True) st.markdown('

AI-Powered Health Monitoring for Cancer Survivors

', unsafe_allow_html=True) # Sidebar for demo scenarios st.sidebar.markdown("## 🎯 Demo Scenarios") st.sidebar.markdown("*Click to load preset health data*") # Demo scenario buttons for scenario_name, scenario_data in DEMO_SCENARIOS.items(): if st.sidebar.button(scenario_name, key=f"demo_{scenario_name}", help=f"Load {scenario_name} health data"): for key, value in scenario_data.items(): st.session_state[f"input_{key}"] = value st.rerun() st.sidebar.markdown("---") st.sidebar.markdown("## 📊 System Info") st.sidebar.info(""" **Version**: 1.0.0 **Model**: Random Forest **Accuracy**: 96.3% **Developer**: Cancer Survivor AI Team """) # Main content area col1, col2 = st.columns([1, 1]) with col1: st.markdown("## 📝 Health Data Input") # Health input form with st.form("health_form"): st.markdown("### Vital Signs") heart_rate = st.number_input( "Heart Rate (BPM)", min_value=30, max_value=200, value=st.session_state.get('input_heart_rate', 74), help="Normal: 60-100 BPM" ) col_bp1, col_bp2 = st.columns(2) with col_bp1: systolic_bp = st.number_input( "Systolic BP", min_value=70, max_value=250, value=st.session_state.get('input_systolic_bp', 128), help="Normal: <130" ) with col_bp2: diastolic_bp = st.number_input( "Diastolic BP", min_value=40, max_value=150, value=st.session_state.get('input_diastolic_bp', 82), help="Normal: <80" ) spo2 = st.number_input( "Oxygen Saturation (%)", min_value=70, max_value=100, value=st.session_state.get('input_spo2', 97), help="Normal: >95%. Critical: <88%" ) st.markdown("### Daily Activities") col_sleep, col_steps = st.columns(2) with col_sleep: sleep_hours = st.number_input( "Sleep Hours", min_value=0.0, max_value=24.0, step=0.1, value=st.session_state.get('input_sleep_hours', 7.2), help="Recommended: 7-9 hours" ) with col_steps: steps = st.number_input( "Daily Steps", min_value=0, max_value=50000, value=st.session_state.get('input_steps', 6800), help="Target: 6000+ steps" ) weight_lbs = st.number_input( "Weight (lbs)", min_value=50, max_value=500, value=st.session_state.get('input_weight_lbs', 178) ) st.markdown("### Health Management") medication_taken = st.selectbox( "Medication Taken Today", options=[1, 0], format_func=lambda x: "✅ Yes" if x == 1 else "❌ Missed", index=0 if st.session_state.get('input_medication_taken', 1) == 1 else 1 ) pain_level = st.slider( "Pain Level (0-10)", min_value=0, max_value=10, value=st.session_state.get('input_pain_level', 2), help="0 = No pain, 10 = Severe pain" ) # Submit button submitted = st.form_submit_button("🔍 Analyze Health Status", type="primary") if submitted: # Prepare health data health_data = { 'heart_rate': heart_rate, 'systolic_bp': systolic_bp, 'diastolic_bp': diastolic_bp, 'sleep_hours': sleep_hours, 'steps': steps, 'spo2': spo2, 'weight_lbs': weight_lbs, 'medication_taken': medication_taken, 'pain_level': pain_level } # Make prediction with loading spinner with st.spinner('🤖 AI analyzing health data...'): time.sleep(1) # Simulate processing time for demo effect result = make_prediction(health_data) # Store in session state for the results column st.session_state['latest_result'] = result st.session_state['latest_input'] = health_data # Add to history st.session_state.prediction_history.append({ 'timestamp': datetime.now().strftime('%H:%M:%S'), 'prediction': result['prediction'], 'confidence': result['confidence'] }) with col2: st.markdown("## 🎯 AI Analysis Results") if 'latest_result' in st.session_state: result = st.session_state['latest_result'] health_data = st.session_state['latest_input'] # Prediction result card prediction = result['prediction'] confidence = result['confidence'] if prediction == "Alert": st.markdown(f"""

🚨 HEALTH ALERT

Confidence: {confidence:.1%}

Decision: {result['decision_reason']}

""", unsafe_allow_html=True) else: st.markdown(f"""

✅ Normal Status

Confidence: {confidence:.1%}

Decision: {result['decision_reason']}

""", unsafe_allow_html=True) # Key metrics st.markdown("### 📊 Detailed Analysis") col_met1, col_met2 = st.columns(2) with col_met1: st.metric( "Normal Probability", f"{result['ml_probability_normal']:.1%}", delta=f"{result['ml_probability_normal']-0.5:.1%}" if result['ml_probability_normal'] > 0.5 else None ) with col_met2: st.metric( "Alert Probability", f"{result['ml_probability_alert']:.1%}", delta=f"{result['ml_probability_alert']-0.5:.1%}" if result['ml_probability_alert'] > 0.5 else None ) # Safety override indicator if result['safety_triggered']: st.error("🛡️ **SAFETY OVERRIDE ACTIVATED**") else: st.success("🛡️ Safety checks passed") # Recommendations st.markdown("### 💡 Recommendations") for rec in result['recommendations']: if rec.startswith('🚨'): st.error(rec) elif rec.startswith('✅'): st.success(rec) else: st.info(rec) # Vital signs gauges st.markdown("### 📈 Vital Signs Analysis") gauge_col1, gauge_col2 = st.columns(2) with gauge_col1: # Heart rate gauge hr_fig = create_gauge_chart( health_data['heart_rate'], "Heart Rate (BPM)", max_val=150, threshold={'low': 60, 'high': 100} ) st.plotly_chart(hr_fig, use_container_width=True) # SpO2 gauge spo2_fig = create_gauge_chart( health_data['spo2'], "Oxygen Saturation (%)", min_val=80, max_val=100, threshold=95 ) st.plotly_chart(spo2_fig, use_container_width=True) with gauge_col2: # Blood pressure gauge bp_fig = create_gauge_chart( health_data['systolic_bp'], "Systolic BP", max_val=200, threshold=140 ) st.plotly_chart(bp_fig, use_container_width=True) # Pain level gauge pain_fig = create_gauge_chart( health_data['pain_level'], "Pain Level", max_val=10, threshold=5 ) st.plotly_chart(pain_fig, use_container_width=True) else: st.info("👆 Enter health data and click 'Analyze Health Status' to see AI predictions") # Show demo preview st.markdown("### 🎯 Try Demo Scenarios") st.markdown("Click any scenario in the sidebar to see:") st.markdown("- **Normal Day**: 97% confidence normal prediction") st.markdown("- **Early Warning**: Intervention recommended") st.markdown("- **🚨 Medical Emergency**: Safety override triggered") st.markdown("- **Recovery Monitoring**: Post-treatment analysis") # Prediction history if st.session_state.prediction_history: st.markdown("## 📈 Prediction History") history_df = pd.DataFrame(st.session_state.prediction_history) fig = px.line( history_df, x='timestamp', y='confidence', color='prediction', title='Prediction Confidence Over Time', color_discrete_map={'Normal': 'green', 'Alert': 'red'} ) st.plotly_chart(fig, use_container_width=True) if __name__ == "__main__": main()