datafreak's picture
Update app.py
79f2e8b verified
import os
import gradio as gr
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from langchain_groq import ChatGroq
from langchain.prompts import PromptTemplate
from typing import TypedDict, List
from typing_extensions import Annotated
from dotenv import load_dotenv
import numpy as np
load_dotenv()
api_key = os.getenv('GROQ_API_KEY')
class AssessmentOutput(TypedDict):
stress_management: Annotated[float, "Percentage score (0-100) for Stress Management KPI"]
motivation: Annotated[float, "Percentage score (0-100) for Motivation KPI"]
restless_night_score: Annotated[float, "Percentage score (0-100) for Restless Night Score KPI"]
anxiety_level: Annotated[float, "Percentage score (0-100) for Anxiety Level KPI"]
burnout_level: Annotated[float, "Percentage score (0-100) for Burnout Level KPI"]
physical_fitness_score: Annotated[float, "Percentage score (0-100) for Physical Fitness KPI"]
dietary_habit_score: Annotated[float, "Percentage score (0-100) for Diet & Nutrition KPI"]
focus_score: Annotated[float, "Percentage score (0-100) for Cognitive Performance and Focus KPI"]
overall_wellness_score: Annotated[float, "Percentage score (0-100) based on all the individual KPIs"]
package: Annotated[List[str], "List of recommended packages. Options include 'Focus', 'Fitness', and 'Insomnia'. The recommendation can be a single package, a combination of packages, or all three packages based on the assessment."]
report: Annotated[str, "A detailed summary report of the assessment results and recommendations based on the KPI analysis."]
template = """
You are an AI wellness assessment system designed to evaluate users' well-being and provide personalized insights. This assessment system analyzes responses and generates wellness reports, recommending specific services and packages from *DailyWellnessAI* to help users improve their mental and physical health. While this system itself is not called *DailyWellnessAI*, all recommendations are part of the *DailyWellnessAI* platform.
Based on the user's responses to the following 15 questions, along with their personal details (Age, Gender, Height, Weight), predict the following KPIs as percentages out of 100:
- stress_management
- motivation
- restless_night_score
- anxiety_level
- burnout_level
- physical_fitness_score
- dietary_habit_score
- focus_score
- overall_wellness_score
**Recommendation System:**
Based on the predicted KPIs, recommend one of the following *DailyWellnessAI* packages:
- Focus (for low concentration, motivation, burnout, mental fog, and lack of focus)
- Insomnia (for sleep disturbances, restlessness, anxiety before sleep, difficulty sleeping, and poor sleep quality)
- Fitness (for low physical activity, poor dietary habits, weak physical strength, low endurance, and lack of energy)
If the overall_wellness_score is greater than 90 (or 95), recommend all three packages and let the user choose among them, emphasizing that DailyWellnessAI offers holistic well-being solutions.
**Summary Report:**
Provide a brief wellness summary explaining the predicted KPIs and recommended package(s) based on the user's responses. Justify the recommendations by highlighting key factors affecting the user's well-being and how DailyWellnessAI can help improve them. Take into account the user's name, age, gender, height, and weight when providing recommendations.
### Personal Details:
- Age: {age}
- Gender: {gender}
- Height: {height}
- Weight: {weight}
### Assessment Questions:
1. How often do you feel stressed by daily tasks?
Options: Never, Sometimes, Often, Always
Answer: {ans1}
2. How well do you handle stress?
Options: Excellent, Good, Fair, Poor
Answer: {ans2}
3. How would you rate your current level of burnout?
Options: None, Mild, Moderate, Severe
Answer: {ans3}
4. How well can you concentrate on your daily tasks?
Options: Excellent, Good, Fair, Poor
Answer: {ans4}
5. How often do you have trouble falling asleep?
Options: Never, Rarely, Sometimes, Always
Answer: {ans5}
6. How would you rate the quality of your sleep?
Options: Excellent, Good, Fair, Poor
Answer: {ans6}
7. How often do you wake up during the night?
Options: Never, Rarely, Sometimes, Often
Answer: {ans7}
8. How often do you feel anxious before sleep?
Options: Never, Rarely, Sometimes, Often
Answer: {ans8}
9. How happy are you with your eating habits?
Options: Very happy, Happy, Unhappy, Very unhappy
Answer: {ans9}
10. How balanced is your diet?
Options: Very balanced, Balanced, Unbalanced, Very unbalanced
Answer: {ans10}
11. How often do you exercise or do physical activity?
Options: Daily, Several times a week, Once a week, Never
Answer: {ans11}
12. How would you rate your physical strength?
Options: Excellent, Good, Fair, Poor
Answer: {ans12}
13. How motivated are you to work on your wellness goals daily?
Options: Very motivated, Moderately motivated, Slightly motivated, Not at all
Answer: {ans13}
14. How would you rate your overall health and well-being?
Options: Excellent, Good, Fair, Poor
Answer: {ans14}
15. Any more remarks about yourself that you want to add?
Answer: {ans15}
Use the responses and personal details to generate KPI predictions, determine the recommended *DailyWellnessAI* package(s), and provide a concise summary report that briefly justifies the recommendations, taking into account the user's age, gender, height, and weight.
"""
chat = ChatGroq(api_key=api_key, model="llama-3.3-70b-versatile", temperature=0.2)
prompt_template = PromptTemplate(
input_variables=["age", "gender", "height", "weight"] + [f"ans{i}" for i in range(1, 16)],
template=template
)
def run_assessment(personal_details, answers):
prompt = prompt_template.format(**personal_details, **answers)
structured_llm = chat.with_structured_output(AssessmentOutput)
return structured_llm.invoke(prompt)
def get_emoji(score):
if score < 20:
return "😢"
elif score < 40:
return "😞"
elif score < 60:
return "😐"
elif score < 80:
return "🙂"
else:
return "😄"
def create_overall_wellness_donut(score):
color = '#FF5252' if score < 50 else '#FFC107' if score < 75 else '#4CAF50'
fig = go.Figure(go.Pie(
values=[score, 100 - score],
hole=0.7,
textinfo='none',
marker_colors=[color, '#E0E0E0'],
showlegend=False
))
fig.update_layout(
annotations=[dict(
text=f"{get_emoji(score)}",
font_size=24,
showarrow=False
)],
title=dict(text="Overall Wellness", x=0.5, font=dict(size=16)),
margin=dict(t=20, b=20, l=20, r=20),
height=300
)
return fig
def create_kpi_bar_chart(kpis, values):
colors = ['#FF5252' if v < 50 else '#FFC107' if v < 75 else '#4CAF50' for v in values]
fig = go.Figure(go.Bar(
x=kpis,
y=values,
marker_color=colors,
text=[f"{v}%" for v in values],
textposition='auto'
))
fig.update_layout(
title="KPI Breakdown",
xaxis=dict(title="KPI"),
yaxis=dict(title="Score (%)", range=[0, 100]),
margin=dict(l=40, r=40, t=60, b=40),
height=400
)
return fig
def create_radar_chart(data):
categories = [
'Stress Management',
'Motivation',
'Sleep Quality',
'Anxiety Control',
'Burnout Resistance',
'Physical Fitness',
'Diet & Nutrition',
'Focus'
]
values = [
float(data['stress_management']),
float(data['motivation']),
100 - float(data['restless_night_score']),
100 - float(data['anxiety_level']),
100 - float(data['burnout_level']),
float(data['physical_fitness_score']),
float(data['dietary_habit_score']),
float(data['focus_score'])
]
fig = go.Figure()
fig.add_trace(go.Scatterpolar(
r=values,
theta=categories,
fill='toself',
fillcolor='rgba(76, 175, 80, 0.3)',
line=dict(color='#4CAF50', width=2),
name='Your Profile'
))
fig.update_layout(
polar=dict(
radialaxis=dict(visible=True, range=[0, 100], tickfont=dict(size=10))
),
showlegend=False,
margin=dict(l=40, r=40, t=20, b=20),
height=400
)
return fig
def create_bullet_charts_combined(data):
bullet_data = [
("Stress Management", float(data['stress_management'])),
("Motivation", float(data['motivation'])),
("Sleep Quality", 100 - float(data['restless_night_score'])),
("Anxiety Control", 100 - float(data['anxiety_level'])),
("Burnout Resistance", 100 - float(data['burnout_level'])),
("Physical Fitness", float(data['physical_fitness_score'])),
("Diet & Nutrition", float(data['dietary_habit_score'])),
("Focus", float(data['focus_score']))
]
rows, cols = 2, 4
target = 80
fig = make_subplots(rows=rows, cols=cols, subplot_titles=[item[0] for item in bullet_data])
for i, (label, val) in enumerate(bullet_data):
row = i // cols + 1
col = i % cols + 1
fig.add_trace(go.Bar(
x=[val],
y=[""],
orientation="h",
marker_color='#4CAF50' if val >= target else '#FF5252',
text=[f"{val}%"],
textposition='inside',
showlegend=False
), row=row, col=col)
fig.update_xaxes(range=[0, 100], row=row, col=col)
fig.add_shape(
type="line",
x0=target, x1=target,
y0=0, y1=1,
xref=f"x{i+1}",
yref=f"y{i+1}",
line=dict(color="black", width=2, dash="dash")
)
fig.update_layout(height=400, width=1000, margin=dict(l=20, r=20, t=40, b=20))
return fig
def combine_report(results):
packages = results["package"]
rec_text = ", ".join(packages) if packages else "None"
final_text = f"### Report\n{results['report']}\n\n**Recommended Packages:** {rec_text}"
return final_text
def gradio_assessment(
age, gender, height, weight,
ans1, ans2, ans3, ans4, ans5,
ans6, ans7, ans8, ans9, ans10,
ans11, ans12, ans13, ans14, ans15
):
personal_details = {
"age": age,
"gender": gender,
"height": height,
"weight": weight
}
answers = {
"ans1": ans1, "ans2": ans2, "ans3": ans3, "ans4": ans4, "ans5": ans5,
"ans6": ans6, "ans7": ans7, "ans8": ans8, "ans9": ans9, "ans10": ans10,
"ans11": ans11, "ans12": ans12, "ans13": ans13, "ans14": ans14,
"ans15": ans15
}
results = run_assessment(personal_details, answers)
overall_score = int(float(results["overall_wellness_score"]))
donut_fig = create_overall_wellness_donut(overall_score)
kpis = [
"Stress Management", "Motivation", "Sleep Quality",
"Anxiety Control", "Burnout Resistance", "Physical Fitness",
"Diet & Nutrition", "Focus"
]
values = [
float(results["stress_management"]),
float(results["motivation"]),
100 - float(results["restless_night_score"]),
100 - float(results["anxiety_level"]),
100 - float(results["burnout_level"]),
float(results["physical_fitness_score"]),
float(results["dietary_habit_score"]),
float(results["focus_score"])
]
bar_fig = create_kpi_bar_chart(kpis, values)
radar_fig = create_radar_chart(results)
bullet_fig = create_bullet_charts_combined(results)
report_text = combine_report(results)
return donut_fig, bar_fig, radar_fig, bullet_fig, report_text
def build_app():
with gr.Blocks() as demo:
gr.Markdown("# 🌿 DailyWellnessAI Assessment")
gr.Markdown("Fill out the questionnaire below to receive personalized insights and recommendations.")
with gr.Row():
with gr.Column():
age = gr.Number(label="Your Age")
gender = gr.Dropdown(label="Your Gender", choices=["Male", "Female", "Other"], value="Male")
height = gr.Textbox(label="Your Height (e.g., 180 cm)", placeholder="Enter your height")
weight = gr.Textbox(label="Your Weight (e.g., 80 kg)", placeholder="Enter your weight")
with gr.Column():
ans1 = gr.Dropdown(label="1. How often do you feel stressed by daily tasks?", choices=["Never", "Sometimes", "Often", "Always"], value="Never")
ans2 = gr.Dropdown(label="2. How well do you handle stress?", choices=["Excellent", "Good", "Fair", "Poor"], value="Good")
ans3 = gr.Dropdown(label="3. How would you rate your current level of burnout?", choices=["None", "Mild", "Moderate", "Severe"], value="None")
ans4 = gr.Dropdown(label="4. How well can you concentrate on your daily tasks?", choices=["Excellent", "Good", "Fair", "Poor"], value="Good")
ans5 = gr.Dropdown(label="5. How often do you have trouble falling asleep?", choices=["Never", "Rarely", "Sometimes", "Always"], value="Rarely")
ans6 = gr.Dropdown(label="6. How would you rate the quality of your sleep?", choices=["Excellent", "Good", "Fair", "Poor"], value="Good")
ans7 = gr.Dropdown(label="7. How often do you wake up during the night?", choices=["Never", "Rarely", "Sometimes", "Often"], value="Rarely")
ans8 = gr.Dropdown(label="8. How often do you feel anxious before sleep?", choices=["Never", "Rarely", "Sometimes", "Often"], value="Rarely")
with gr.Column():
ans9 = gr.Dropdown(label="9. How happy are you with your eating habits?", choices=["Very happy", "Happy", "Unhappy", "Very unhappy"], value="Happy")
ans10 = gr.Dropdown(label="10. How balanced is your diet?", choices=["Very balanced", "Balanced", "Unbalanced", "Very unbalanced"], value="Balanced")
ans11 = gr.Dropdown(label="11. How often do you exercise or do physical activity?", choices=["Daily", "Several times a week", "Once a week", "Never"], value="Daily")
ans12 = gr.Dropdown(label="12. How would you rate your physical strength?", choices=["Excellent", "Good", "Fair", "Poor"], value="Good")
ans13 = gr.Dropdown(label="13. How motivated are you to work on your wellness goals daily?", choices=["Very motivated", "Moderately motivated", "Slightly motivated", "Not at all"], value="Very motivated")
ans14 = gr.Dropdown(label="14. How would you rate your overall health and well-being?", choices=["Excellent", "Good", "Fair", "Poor"], value="Good")
ans15 = gr.Textbox(label="15. Any more remarks about yourself that you want to add?", lines=3)
with gr.Row():
submit_btn = gr.Button("Submit Assessment")
with gr.Row():
gr.Markdown("## Results")
with gr.Row():
donut_plot = gr.Plot(label="Overall Wellness Donut")
bar_plot = gr.Plot(label="KPI Bar Chart")
with gr.Row():
radar_plot = gr.Plot(label="Radar Chart")
bullet_plot = gr.Plot(label="Bullet Charts")
with gr.Row():
report_md = gr.Markdown(label="Assessment Report")
submit_btn.click(
fn=gradio_assessment,
inputs=[age, gender, height, weight, ans1, ans2, ans3, ans4, ans5, ans6, ans7, ans8, ans9, ans10, ans11, ans12, ans13, ans14, ans15],
outputs=[donut_plot, bar_plot, radar_plot, bullet_plot, report_md]
)
return demo
if __name__ == "__main__":
demo_app = build_app()
demo_app.launch(server_name="0.0.0.0", server_port=7860, share=True)