Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import pandas as pd | |
| import datetime | |
| import json | |
| import os | |
| from typing import Dict, List, Tuple | |
| import plotly.graph_objects as go | |
| import plotly.express as px | |
| from dataclasses import dataclass, asdict | |
| import google.generativeai as genai | |
| # Data structure for health records | |
| class HealthRecord: | |
| date: str | |
| morning_mood: int | |
| morning_energy: int | |
| morning_sleep_quality: int | |
| afternoon_water_intake: int | |
| afternoon_physical_activity: int | |
| afternoon_stress_level: int | |
| evening_meal_quality: int | |
| evening_screen_time: int | |
| evening_gratitude: int | |
| daily_score: float | |
| ai_recommendation: str | |
| class AIDoctor: | |
| def __init__(self): | |
| self.data_file = "health_data.json" | |
| self.setup_gemini() | |
| self.load_data() | |
| def setup_gemini(self): | |
| """Setup Google Gemini AI""" | |
| # Get API key from environment variable or Hugging Face Secrets | |
| api_key = os.getenv("GEMINI_API_KEY") or os.getenv("GOOGLE_API_KEY") | |
| if api_key: | |
| genai.configure(api_key=api_key) | |
| self.model = genai.GenerativeModel('gemini-pro') | |
| self.gemini_available = True | |
| else: | |
| self.gemini_available = False | |
| print("β οΈ Gemini API key not found. Using fallback recommendations.") | |
| def load_data(self): | |
| """Load existing health data""" | |
| if os.path.exists(self.data_file): | |
| try: | |
| with open(self.data_file, 'r') as f: | |
| data = json.load(f) | |
| self.records = [HealthRecord(**record) for record in data] | |
| except: | |
| self.records = [] | |
| else: | |
| self.records = [] | |
| def save_data(self): | |
| """Save health data to file""" | |
| try: | |
| with open(self.data_file, 'w') as f: | |
| json.dump([asdict(record) for record in self.records], f, indent=2) | |
| except: | |
| pass | |
| def calculate_daily_score(self, morning_data: Dict, afternoon_data: Dict, evening_data: Dict) -> float: | |
| """Calculate daily health score (0-100)""" | |
| # Morning score (30% weight) | |
| morning_score = ( | |
| morning_data['mood'] * 0.4 + | |
| morning_data['energy'] * 0.4 + | |
| morning_data['sleep_quality'] * 0.2 | |
| ) * 10 | |
| # Afternoon score (40% weight) | |
| afternoon_score = ( | |
| min(morning_data['water_intake'] / 8, 1) * 40 + # 8 glasses target | |
| min(afternoon_data['physical_activity'] / 60, 1) * 40 + # 60 min target | |
| (10 - afternoon_data['stress_level']) * 2 # Lower stress is better | |
| ) | |
| # Evening score (30% weight) | |
| evening_score = ( | |
| evening_data['meal_quality'] * 8 + | |
| max(0, (8 - evening_data['screen_time'])) * 2 + # Less than 8 hours | |
| evening_data['gratitude'] * 10 | |
| ) | |
| # Weighted total | |
| total_score = (morning_score * 0.3 + afternoon_score * 0.4 + evening_score * 0.3) | |
| return min(100, max(0, total_score)) | |
| def generate_ai_recommendation(self, score: float, morning_data: Dict, afternoon_data: Dict, evening_data: Dict) -> str: | |
| """Generate AI doctor recommendations using Gemini""" | |
| if self.gemini_available: | |
| try: | |
| # Create detailed health context for Gemini | |
| health_context = f""" | |
| You are an AI Health Doctor analyzing a patient's daily health data. Provide personalized, actionable health recommendations. | |
| PATIENT DAILY HEALTH DATA: | |
| - Overall Health Score: {score:.1f}/100 | |
| Morning Metrics: | |
| - Mood: {morning_data['mood']}/10 | |
| - Energy Level: {morning_data['energy']}/10 | |
| - Sleep Quality: {morning_data['sleep_quality']}/10 | |
| Afternoon Metrics: | |
| - Water Intake: {morning_data['water_intake']} glasses (target: 8) | |
| - Physical Activity: {afternoon_data['physical_activity']} minutes (target: 60) | |
| - Stress Level: {afternoon_data['stress_level']}/10 (lower is better) | |
| Evening Metrics: | |
| - Meal Quality: {evening_data['meal_quality']}/10 | |
| - Screen Time: {evening_data['screen_time']} hours | |
| - Gratitude Practice: {evening_data['gratitude']}/10 | |
| INSTRUCTIONS: | |
| 1. Analyze the overall health pattern | |
| 2. Identify 2-3 key areas for improvement | |
| 3. Provide specific, actionable recommendations | |
| 4. Use encouraging, doctor-like tone | |
| 5. Include emojis for better engagement | |
| 6. Keep response under 300 words | |
| 7. Focus on the lowest-scoring metrics | |
| Format: Start with overall assessment, then provide specific recommendations for improvement areas. | |
| """ | |
| # Get historical context if available | |
| if len(self.records) >= 3: | |
| recent_scores = [r.daily_score for r in self.records[-3:]] | |
| trend = "improving" if recent_scores[-1] > recent_scores[0] else "declining" if recent_scores[-1] < recent_scores[0] else "stable" | |
| health_context += f"\n\nRecent 3-day trend: {trend} (scores: {recent_scores})" | |
| # Generate response with Gemini | |
| response = self.model.generate_content(health_context) | |
| return response.text | |
| except Exception as e: | |
| print(f"Gemini API error: {e}") | |
| return self.fallback_recommendations(score, morning_data, afternoon_data, evening_data) | |
| else: | |
| return self.fallback_recommendations(score, morning_data, afternoon_data, evening_data) | |
| def fallback_recommendations(self, score: float, morning_data: Dict, afternoon_data: Dict, evening_data: Dict) -> str: | |
| """Fallback recommendations when Gemini is not available""" | |
| recommendations = [] | |
| # Score-based general advice | |
| if score >= 85: | |
| recommendations.append("π Excellent health habits! You're doing amazing!") | |
| elif score >= 70: | |
| recommendations.append("π Good health practices! Small improvements can make you even better.") | |
| elif score >= 50: | |
| recommendations.append("β οΈ Moderate health status. Focus on key areas for improvement.") | |
| else: | |
| recommendations.append("π¨ Your health needs attention. Let's work on fundamental habits.") | |
| # Specific recommendations | |
| if morning_data['sleep_quality'] < 6: | |
| recommendations.append("π€ Sleep Quality: Aim for 7-9 hours of sleep. Create a bedtime routine.") | |
| if morning_data['mood'] < 6: | |
| recommendations.append("π Mood: Try 10 minutes of meditation or journaling in the morning.") | |
| if morning_data['energy'] < 6: | |
| recommendations.append("β‘ Energy: Consider a protein-rich breakfast and light morning exercise.") | |
| if morning_data['water_intake'] < 6: | |
| recommendations.append("π§ Hydration: Aim for 8 glasses of water daily. Set hourly reminders.") | |
| if afternoon_data['physical_activity'] < 30: | |
| recommendations.append("π Activity: Try to get at least 30 minutes of physical activity daily.") | |
| if afternoon_data['stress_level'] > 7: | |
| recommendations.append("π§ Stress: Practice deep breathing or take short breaks throughout the day.") | |
| if evening_data['meal_quality'] < 6: | |
| recommendations.append("π₯ Nutrition: Focus on whole foods, vegetables, and balanced meals.") | |
| if evening_data['screen_time'] > 6: | |
| recommendations.append("π± Screen Time: Reduce screen time before bed for better sleep quality.") | |
| return " | ".join(recommendations) | |
| def morning_checkin(self, mood: int, energy: int, sleep_quality: int, water_goal: int) -> str: | |
| """Process morning check-in""" | |
| today = datetime.date.today().isoformat() | |
| # Store morning data temporarily | |
| self.temp_morning = { | |
| 'mood': mood, | |
| 'energy': energy, | |
| 'sleep_quality': sleep_quality, | |
| 'water_intake': water_goal | |
| } | |
| return f"β Morning check-in completed!\n\nMood: {mood}/10\nEnergy: {energy}/10\nSleep Quality: {sleep_quality}/10\nWater Goal: {water_goal} glasses\n\nπ Complete your afternoon check-in next!" | |
| def afternoon_checkin(self, water_consumed: int, physical_activity: int, stress_level: int) -> str: | |
| """Process afternoon check-in""" | |
| if not hasattr(self, 'temp_morning'): | |
| return "β Please complete your morning check-in first!" | |
| self.temp_afternoon = { | |
| 'physical_activity': physical_activity, | |
| 'stress_level': stress_level | |
| } | |
| # Update water intake | |
| self.temp_morning['water_intake'] = water_consumed | |
| return f"β Afternoon check-in completed!\n\nWater Consumed: {water_consumed} glasses\nPhysical Activity: {physical_activity} minutes\nStress Level: {stress_level}/10\n\nπ Complete your evening check-in to get your daily score!" | |
| def evening_checkin(self, meal_quality: int, screen_time: int, gratitude: int) -> Tuple[str, str, object]: | |
| """Process evening check-in and generate daily report""" | |
| if not hasattr(self, 'temp_morning') or not hasattr(self, 'temp_afternoon'): | |
| return "β Please complete morning and afternoon check-ins first!", "", None | |
| evening_data = { | |
| 'meal_quality': meal_quality, | |
| 'screen_time': screen_time, | |
| 'gratitude': gratitude | |
| } | |
| # Calculate daily score | |
| score = self.calculate_daily_score(self.temp_morning, self.temp_afternoon, evening_data) | |
| # Generate AI recommendation | |
| recommendation = self.generate_ai_recommendation(score, self.temp_morning, self.temp_afternoon, evening_data) | |
| # Create health record | |
| today = datetime.date.today().isoformat() | |
| record = HealthRecord( | |
| date=today, | |
| morning_mood=self.temp_morning['mood'], | |
| morning_energy=self.temp_morning['energy'], | |
| morning_sleep_quality=self.temp_morning['sleep_quality'], | |
| afternoon_water_intake=self.temp_morning['water_intake'], | |
| afternoon_physical_activity=self.temp_afternoon['physical_activity'], | |
| afternoon_stress_level=self.temp_afternoon['stress_level'], | |
| evening_meal_quality=evening_data['meal_quality'], | |
| evening_screen_time=evening_data['screen_time'], | |
| evening_gratitude=evening_data['gratitude'], | |
| daily_score=score, | |
| ai_recommendation=recommendation | |
| ) | |
| # Save record | |
| self.records = [r for r in self.records if r.date != today] # Remove today's old record | |
| self.records.append(record) | |
| self.save_data() | |
| # Generate report | |
| report = f""" | |
| # π₯ Daily Health Report - {today} | |
| ## π Your Health Score: {score:.1f}/100 | |
| ### π Morning Metrics: | |
| - Mood: {self.temp_morning['mood']}/10 | |
| - Energy: {self.temp_morning['energy']}/10 | |
| - Sleep Quality: {self.temp_morning['sleep_quality']}/10 | |
| ### π Afternoon Metrics: | |
| - Water Intake: {self.temp_morning['water_intake']} glasses | |
| - Physical Activity: {self.temp_afternoon['physical_activity']} minutes | |
| - Stress Level: {self.temp_afternoon['stress_level']}/10 | |
| ### π Evening Metrics: | |
| - Meal Quality: {evening_data['meal_quality']}/10 | |
| - Screen Time: {evening_data['screen_time']} hours | |
| - Gratitude Practice: {gratitude}/10 | |
| ## π€ AI Doctor Recommendations: | |
| {recommendation} | |
| --- | |
| *Keep up the great work! Consistency is key to better health.* π | |
| """ | |
| # Create progress chart | |
| chart = self.create_progress_chart() | |
| # Clear temporary data | |
| delattr(self, 'temp_morning') | |
| delattr(self, 'temp_afternoon') | |
| return f"β Evening check-in completed!", report, chart | |
| def create_progress_chart(self): | |
| """Create progress visualization""" | |
| if len(self.records) < 2: | |
| return None | |
| df = pd.DataFrame([asdict(record) for record in self.records[-7:]]) # Last 7 days | |
| fig = go.Figure() | |
| fig.add_trace(go.Scatter( | |
| x=df['date'], | |
| y=df['daily_score'], | |
| mode='lines+markers', | |
| name='Daily Health Score', | |
| line=dict(color='#2E86AB', width=3), | |
| marker=dict(size=8) | |
| )) | |
| fig.update_layout( | |
| title='π Your 7-Day Health Progress', | |
| xaxis_title='Date', | |
| yaxis_title='Health Score', | |
| yaxis=dict(range=[0, 100]), | |
| template='plotly_white', | |
| height=400 | |
| ) | |
| return fig | |
| def get_weekly_summary(self) -> str: | |
| """Generate weekly health summary""" | |
| if len(self.records) < 7: | |
| return "π Complete 7 days of check-ins to see your weekly summary!" | |
| recent_records = self.records[-7:] | |
| avg_score = sum(r.daily_score for r in recent_records) / len(recent_records) | |
| # Find trends | |
| scores = [r.daily_score for r in recent_records] | |
| trend = "π Improving" if scores[-1] > scores[0] else "π Declining" if scores[-1] < scores[0] else "β‘οΈ Stable" | |
| best_day = max(recent_records, key=lambda x: x.daily_score) | |
| summary = f""" | |
| # π Weekly Health Summary | |
| ## π― Average Score: {avg_score:.1f}/100 | |
| ## π Trend: {trend} | |
| ## π Best Day: {best_day.date} (Score: {best_day.daily_score:.1f}) | |
| ### Key Insights: | |
| - Best performing area: {"Sleep" if sum(r.morning_sleep_quality for r in recent_records) > 42 else "Physical Activity" if sum(r.afternoon_physical_activity for r in recent_records) > 210 else "Nutrition"} | |
| - Focus area: {"Sleep routine" if sum(r.morning_sleep_quality for r in recent_records) < 35 else "Exercise" if sum(r.afternoon_physical_activity for r in recent_records) < 140 else "Stress management"} | |
| *Keep building those healthy habits! πͺ* | |
| """ | |
| return summary | |
| # Initialize AI Doctor | |
| ai_doctor = AIDoctor() | |
| # Create Gradio Interface | |
| with gr.Blocks(title="π₯ AI Doctor - Daily Health Checkup", theme=gr.themes.Soft()) as app: | |
| gr.Markdown(""" | |
| # π₯ AI Doctor - Your Personal Health Assistant | |
| Complete 3 daily check-ins to track your health and get **AI-powered recommendations from Google Gemini**! π€β¨ | |
| **π± How it works:** | |
| 1. **Morning Check-in** - Rate your mood, energy, and sleep | |
| 2. **Afternoon Check-in** - Log water, activity, and stress | |
| 3. **Evening Check-in** - Rate meals, screen time, and gratitude | |
| Get your daily health score and personalized AI recommendations! | |
| > π **Setup**: Add your `GEMINI_API_KEY` in Hugging Face Secrets for enhanced AI recommendations! | |
| """) | |
| # API Key status indicator | |
| if ai_doctor.gemini_available: | |
| gr.Markdown("β **Gemini AI Active** - Enhanced recommendations enabled!") | |
| else: | |
| gr.Markdown("β οΈ **Gemini AI Inactive** - Add GEMINI_API_KEY for enhanced recommendations (using fallback mode)") | |
| with gr.Tabs(): | |
| # Morning Check-in Tab | |
| with gr.TabItem("π Morning Check-in"): | |
| gr.Markdown("### Start your day with a quick health check!") | |
| with gr.Row(): | |
| mood_slider = gr.Slider(1, 10, value=7, label="π How's your mood? (1=Terrible, 10=Amazing)") | |
| energy_slider = gr.Slider(1, 10, value=7, label="β‘ Energy level? (1=Exhausted, 10=Energetic)") | |
| with gr.Row(): | |
| sleep_slider = gr.Slider(1, 10, value=7, label="π€ Sleep quality? (1=Terrible, 10=Perfect)") | |
| water_goal = gr.Slider(4, 12, value=8, label="π§ Water goal today? (glasses)") | |
| morning_btn = gr.Button("Complete Morning Check-in β ", variant="primary") | |
| morning_output = gr.Textbox(label="Morning Status", lines=6) | |
| morning_btn.click( | |
| ai_doctor.morning_checkin, | |
| inputs=[mood_slider, energy_slider, sleep_slider, water_goal], | |
| outputs=morning_output | |
| ) | |
| # Afternoon Check-in Tab | |
| with gr.TabItem("π Afternoon Check-in"): | |
| gr.Markdown("### Midday health update!") | |
| with gr.Row(): | |
| water_consumed = gr.Slider(0, 15, value=4, label="π§ Water consumed so far? (glasses)") | |
| activity_minutes = gr.Slider(0, 180, value=30, label="π Physical activity? (minutes)") | |
| stress_slider = gr.Slider(1, 10, value=5, label="π° Stress level? (1=Zen, 10=Overwhelmed)") | |
| afternoon_btn = gr.Button("Complete Afternoon Check-in β ", variant="primary") | |
| afternoon_output = gr.Textbox(label="Afternoon Status", lines=6) | |
| afternoon_btn.click( | |
| ai_doctor.afternoon_checkin, | |
| inputs=[water_consumed, activity_minutes, stress_slider], | |
| outputs=afternoon_output | |
| ) | |
| # Evening Check-in Tab | |
| with gr.TabItem("π Evening Check-in"): | |
| gr.Markdown("### End your day and get your health score!") | |
| with gr.Row(): | |
| meal_quality = gr.Slider(1, 10, value=7, label="π₯ Meal quality today? (1=Junk, 10=Nutritious)") | |
| screen_time = gr.Slider(0, 12, value=4, label="π± Screen time? (hours)") | |
| gratitude_slider = gr.Slider(1, 10, value=7, label="π Gratitude practice? (1=None, 10=Very mindful)") | |
| evening_btn = gr.Button("Complete Evening Check-in & Get Score! π―", variant="primary") | |
| with gr.Row(): | |
| evening_status = gr.Textbox(label="Evening Status") | |
| daily_report = gr.Markdown(label="π Daily Health Report") | |
| progress_chart = gr.Plot(label="π Progress Chart") | |
| evening_btn.click( | |
| ai_doctor.evening_checkin, | |
| inputs=[meal_quality, screen_time, gratitude_slider], | |
| outputs=[evening_status, daily_report, progress_chart] | |
| ) | |
| # Progress Tab | |
| with gr.TabItem("π Weekly Summary"): | |
| gr.Markdown("### Your health journey overview") | |
| summary_btn = gr.Button("Generate Weekly Summary π ", variant="secondary") | |
| weekly_summary = gr.Markdown() | |
| summary_btn.click( | |
| ai_doctor.get_weekly_summary, | |
| outputs=weekly_summary | |
| ) | |
| gr.Markdown(""" | |
| --- | |
| ### π‘ Health Tips: | |
| - **Consistency** is more important than perfection | |
| - Aim for **8 glasses** of water daily | |
| - Get **7-9 hours** of quality sleep | |
| - **30+ minutes** of physical activity | |
| - Practice **gratitude** for mental wellness | |
| *Your AI Doctor is here to help you build lasting healthy habits! π* | |
| """) | |
| if __name__ == "__main__": | |
| app.launch() |