Upload 2 files
Browse files- app.py +345 -0
- requirements.txt +0 -0
app.py
ADDED
@@ -0,0 +1,345 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import gradio as gr
|
3 |
+
import pandas as pd
|
4 |
+
import plotly.express as px
|
5 |
+
import plotly.graph_objects as go
|
6 |
+
from plotly.subplots import make_subplots
|
7 |
+
from langchain_groq import ChatGroq
|
8 |
+
from langchain.prompts import PromptTemplate
|
9 |
+
from typing import TypedDict, List
|
10 |
+
from typing_extensions import Annotated
|
11 |
+
from dotenv import load_dotenv
|
12 |
+
import numpy as np
|
13 |
+
|
14 |
+
# --- SETUP ---
|
15 |
+
load_dotenv()
|
16 |
+
api_key = os.getenv('GROQ_API_KEY')
|
17 |
+
|
18 |
+
# Define the structured output type
|
19 |
+
class AssessmentOutput(TypedDict):
|
20 |
+
stress_management: Annotated[float, "Percentage score (0-100) for Stress Management KPI"]
|
21 |
+
motivation: Annotated[float, "Percentage score (0-100) for Motivation KPI"]
|
22 |
+
restless_night_score: Annotated[float, "Percentage score (0-100) for Restless Night Score KPI"]
|
23 |
+
anxiety_level: Annotated[float, "Percentage score (0-100) for Anxiety Level KPI"]
|
24 |
+
burnout_level: Annotated[float, "Percentage score (0-100) for Burnout Level KPI"]
|
25 |
+
physical_fitness_score: Annotated[float, "Percentage score (0-100) for Physical Fitness KPI"]
|
26 |
+
dietary_habit_score: Annotated[float, "Percentage score (0-100) for Diet & Nutrition KPI"]
|
27 |
+
focus_score: Annotated[float, "Percentage score (0-100) for Cognitive Performance and Focus KPI"]
|
28 |
+
overall_wellness_score: Annotated[float, "Percentage score (0-100) based on all the individual KPIs"]
|
29 |
+
package: Annotated[List[str], "List of recommended packages"]
|
30 |
+
report: Annotated[str, "A detailed summary report of the assessment results"]
|
31 |
+
|
32 |
+
# Define the prompt template
|
33 |
+
template = """
|
34 |
+
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.
|
35 |
+
|
36 |
+
Based on the user's responses to the following 15 questions, predict the following KPIs as percentages out of 100:
|
37 |
+
- stress_management
|
38 |
+
- motivation
|
39 |
+
- restless_night_score
|
40 |
+
- anxiety_level
|
41 |
+
- burnout_level
|
42 |
+
- physical_fitness_score
|
43 |
+
- dietary_habit_score
|
44 |
+
- focus_score
|
45 |
+
- overall_wellness_score
|
46 |
+
|
47 |
+
Recommendation System:
|
48 |
+
Based on the predicted KPIs, recommend one of the following *DailyWellnessAI* packages:
|
49 |
+
- Focus (for low concentration, motivation, or burnout)
|
50 |
+
- Insomnia (for sleep disturbances, restlessness, or anxiety before sleep)
|
51 |
+
- Fitness (for low physical activity, poor dietary habits, or weak physical strength)
|
52 |
+
|
53 |
+
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.
|
54 |
+
|
55 |
+
Summary Report:
|
56 |
+
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.
|
57 |
+
|
58 |
+
### Assessment Questions:
|
59 |
+
|
60 |
+
1. How often do you feel stressed by daily tasks?
|
61 |
+
Answer: {ans1}
|
62 |
+
2. How well do you handle stress?
|
63 |
+
Answer: {ans2}
|
64 |
+
3. How would you rate your current level of burnout?
|
65 |
+
Answer: {ans3}
|
66 |
+
4. How well can you concentrate on your daily tasks?
|
67 |
+
Answer: {ans4}
|
68 |
+
5. How often do you have trouble falling asleep?
|
69 |
+
Answer: {ans5}
|
70 |
+
6. How would you rate the quality of your sleep?
|
71 |
+
Answer: {ans6}
|
72 |
+
7. How often do you wake up during the night?
|
73 |
+
Answer: {ans7}
|
74 |
+
8. How often do you feel anxious before sleep?
|
75 |
+
Answer: {ans8}
|
76 |
+
9. How happy are you with your eating habits?
|
77 |
+
Answer: {ans9}
|
78 |
+
10. How balanced is your diet?
|
79 |
+
Answer: {ans10}
|
80 |
+
11. How often do you exercise or do physical activity?
|
81 |
+
Answer: {ans11}
|
82 |
+
12. How would you rate your physical strength?
|
83 |
+
Answer: {ans12}
|
84 |
+
13. How motivated are you to work on your wellness goals daily?
|
85 |
+
Answer: {ans13}
|
86 |
+
14. How would you rate your overall health and well-being?
|
87 |
+
Answer: {ans14}
|
88 |
+
15. Any more remarks about yourself that you want to add?
|
89 |
+
Answer: {ans15}
|
90 |
+
"""
|
91 |
+
|
92 |
+
# Initialize model once
|
93 |
+
chat = ChatGroq(api_key=api_key, model="llama-3.3-70b-versatile", temperature=0.2)
|
94 |
+
prompt_template = PromptTemplate(
|
95 |
+
input_variables=[f"ans{i}" for i in range(1, 16)],
|
96 |
+
template=template
|
97 |
+
)
|
98 |
+
|
99 |
+
def run_assessment(answers):
|
100 |
+
prompt = prompt_template.format(**answers)
|
101 |
+
structured_llm = chat.with_structured_output(AssessmentOutput)
|
102 |
+
return structured_llm.invoke(prompt)
|
103 |
+
|
104 |
+
# --- VISUALIZATION FUNCTIONS ---
|
105 |
+
|
106 |
+
def get_emoji(score):
|
107 |
+
if score < 20:
|
108 |
+
return "😢"
|
109 |
+
elif score < 40:
|
110 |
+
return "😞"
|
111 |
+
elif score < 60:
|
112 |
+
return "😐"
|
113 |
+
elif score < 80:
|
114 |
+
return "🙂"
|
115 |
+
else:
|
116 |
+
return "😄"
|
117 |
+
|
118 |
+
def create_overall_wellness_donut(score):
|
119 |
+
color = '#FF5252' if score < 50 else '#FFC107' if score < 75 else '#4CAF50'
|
120 |
+
fig = go.Figure(go.Pie(
|
121 |
+
values=[score, 100 - score],
|
122 |
+
hole=0.7,
|
123 |
+
textinfo='none',
|
124 |
+
marker_colors=[color, '#E0E0E0'],
|
125 |
+
showlegend=False
|
126 |
+
))
|
127 |
+
fig.update_layout(
|
128 |
+
annotations=[dict(
|
129 |
+
text=f"{get_emoji(score)}",
|
130 |
+
font_size=24,
|
131 |
+
showarrow=False
|
132 |
+
)],
|
133 |
+
title=dict(text="Overall Wellness", x=0.5, font=dict(size=16)),
|
134 |
+
margin=dict(t=20, b=20, l=20, r=20),
|
135 |
+
height=300
|
136 |
+
)
|
137 |
+
return fig
|
138 |
+
|
139 |
+
def create_kpi_bar_chart(kpis, values):
|
140 |
+
colors = ['#FF5252' if v < 50 else '#FFC107' if v < 75 else '#4CAF50' for v in values]
|
141 |
+
fig = go.Figure(go.Bar(
|
142 |
+
x=kpis,
|
143 |
+
y=values,
|
144 |
+
marker_color=colors,
|
145 |
+
text=[f"{v}%" for v in values],
|
146 |
+
textposition='auto'
|
147 |
+
))
|
148 |
+
fig.update_layout(
|
149 |
+
title="KPI Breakdown",
|
150 |
+
xaxis=dict(title="KPI"),
|
151 |
+
yaxis=dict(title="Score (%)", range=[0, 100]),
|
152 |
+
margin=dict(l=40, r=40, t=60, b=40),
|
153 |
+
height=400
|
154 |
+
)
|
155 |
+
return fig
|
156 |
+
|
157 |
+
def create_radar_chart(data):
|
158 |
+
categories = [
|
159 |
+
'Stress Management',
|
160 |
+
'Motivation',
|
161 |
+
'Sleep Quality',
|
162 |
+
'Anxiety Control',
|
163 |
+
'Burnout Resistance',
|
164 |
+
'Physical Fitness',
|
165 |
+
'Diet & Nutrition',
|
166 |
+
'Focus'
|
167 |
+
]
|
168 |
+
values = [
|
169 |
+
data['stress_management'],
|
170 |
+
data['motivation'],
|
171 |
+
100 - data['restless_night_score'],
|
172 |
+
100 - data['anxiety_level'],
|
173 |
+
100 - data['burnout_level'],
|
174 |
+
data['physical_fitness_score'],
|
175 |
+
data['dietary_habit_score'],
|
176 |
+
data['focus_score']
|
177 |
+
]
|
178 |
+
fig = go.Figure()
|
179 |
+
fig.add_trace(go.Scatterpolar(
|
180 |
+
r=values,
|
181 |
+
theta=categories,
|
182 |
+
fill='toself',
|
183 |
+
fillcolor='rgba(76, 175, 80, 0.3)',
|
184 |
+
line=dict(color='#4CAF50', width=2),
|
185 |
+
name='Your Profile'
|
186 |
+
))
|
187 |
+
fig.update_layout(
|
188 |
+
polar=dict(
|
189 |
+
radialaxis=dict(visible=True, range=[0, 100], tickfont=dict(size=10))
|
190 |
+
),
|
191 |
+
showlegend=False,
|
192 |
+
margin=dict(l=40, r=40, t=20, b=20),
|
193 |
+
height=400
|
194 |
+
)
|
195 |
+
return fig
|
196 |
+
|
197 |
+
def create_bullet_charts_combined(data):
|
198 |
+
# Define bullet data for 8 KPIs; for "negative" metrics, invert value.
|
199 |
+
bullet_data = [
|
200 |
+
("Stress Management", data['stress_management']),
|
201 |
+
("Motivation", data['motivation']),
|
202 |
+
("Sleep Quality", 100 - data['restless_night_score']),
|
203 |
+
("Anxiety Control", 100 - data['anxiety_level']),
|
204 |
+
("Burnout Resistance", 100 - data['burnout_level']),
|
205 |
+
("Physical Fitness", data['physical_fitness_score']),
|
206 |
+
("Diet & Nutrition", data['dietary_habit_score']),
|
207 |
+
("Focus", data['focus_score'])
|
208 |
+
]
|
209 |
+
rows, cols = 2, 4
|
210 |
+
target = 80
|
211 |
+
fig = make_subplots(rows=rows, cols=cols, subplot_titles=[item[0] for item in bullet_data])
|
212 |
+
for i, (label, val) in enumerate(bullet_data):
|
213 |
+
row = i // cols + 1
|
214 |
+
col = i % cols + 1
|
215 |
+
# Add a simple horizontal bar as the bullet indicator.
|
216 |
+
fig.add_trace(go.Bar(
|
217 |
+
x=[val],
|
218 |
+
y=[""],
|
219 |
+
orientation="h",
|
220 |
+
marker_color='#4CAF50' if val >= target else '#FF5252',
|
221 |
+
text=[f"{val}%"],
|
222 |
+
textposition='inside',
|
223 |
+
showlegend=False
|
224 |
+
), row=row, col=col)
|
225 |
+
fig.update_xaxes(range=[0, 100], row=row, col=col)
|
226 |
+
# Add a vertical dashed line for the target.
|
227 |
+
fig.add_shape(
|
228 |
+
type="line",
|
229 |
+
x0=target, x1=target,
|
230 |
+
y0=0, y1=1,
|
231 |
+
xref=f"x{i+1} domain",
|
232 |
+
yref=f"y{i+1} domain",
|
233 |
+
line=dict(color="black", width=2, dash="dash")
|
234 |
+
)
|
235 |
+
fig.update_layout(height=400, width=1000, margin=dict(l=20, r=20, t=40, b=20))
|
236 |
+
return fig
|
237 |
+
|
238 |
+
def combine_report(results):
|
239 |
+
packages = results["package"]
|
240 |
+
rec_text = ", ".join(packages) if packages else "None"
|
241 |
+
final_text = f"### Report\n{results['report']}\n\n**Recommended Packages:** {rec_text}"
|
242 |
+
return final_text
|
243 |
+
|
244 |
+
# --- GRADIO APP FUNCTION ---
|
245 |
+
|
246 |
+
def gradio_assessment(
|
247 |
+
ans1, ans2, ans3, ans4, ans5,
|
248 |
+
ans6, ans7, ans8, ans9, ans10,
|
249 |
+
ans11, ans12, ans13, ans14, ans15
|
250 |
+
):
|
251 |
+
answers = {
|
252 |
+
"ans1": ans1, "ans2": ans2, "ans3": ans3, "ans4": ans4, "ans5": ans5,
|
253 |
+
"ans6": ans6, "ans7": ans7, "ans8": ans8, "ans9": ans9, "ans10": ans10,
|
254 |
+
"ans11": ans11, "ans12": ans12, "ans13": ans13, "ans14": ans14,
|
255 |
+
"ans15": ans15 or None
|
256 |
+
}
|
257 |
+
results = run_assessment(answers)
|
258 |
+
overall_score = int(results["overall_wellness_score"])
|
259 |
+
donut_fig = create_overall_wellness_donut(overall_score)
|
260 |
+
|
261 |
+
kpis = [
|
262 |
+
"Stress Management", "Motivation", "Sleep Quality",
|
263 |
+
"Anxiety Control", "Burnout Resistance", "Physical Fitness",
|
264 |
+
"Diet & Nutrition", "Focus"
|
265 |
+
]
|
266 |
+
values = [
|
267 |
+
results["stress_management"],
|
268 |
+
results["motivation"],
|
269 |
+
100 - results["restless_night_score"],
|
270 |
+
100 - results["anxiety_level"],
|
271 |
+
100 - results["burnout_level"],
|
272 |
+
results["physical_fitness_score"],
|
273 |
+
results["dietary_habit_score"],
|
274 |
+
results["focus_score"]
|
275 |
+
]
|
276 |
+
bar_fig = create_kpi_bar_chart(kpis, values)
|
277 |
+
radar_fig = create_radar_chart(results)
|
278 |
+
bullet_fig = create_bullet_charts_combined(results)
|
279 |
+
report_text = combine_report(results)
|
280 |
+
return donut_fig, bar_fig, radar_fig, bullet_fig, report_text
|
281 |
+
|
282 |
+
# --- BUILD GRADIO INTERFACE ---
|
283 |
+
|
284 |
+
def build_app():
|
285 |
+
with gr.Blocks() as demo:
|
286 |
+
gr.Markdown("# 🌿 DailyWellnessAI Assessment")
|
287 |
+
gr.Markdown("Fill out the questionnaire below to receive personalized insights and recommendations.")
|
288 |
+
|
289 |
+
with gr.Row():
|
290 |
+
with gr.Column():
|
291 |
+
ans1 = gr.Dropdown(label="1. How often do you feel stressed by daily tasks?",
|
292 |
+
choices=["Never", "Sometimes", "Often", "Always"], value="Never")
|
293 |
+
ans2 = gr.Dropdown(label="2. How well do you handle stress?",
|
294 |
+
choices=["Excellent", "Good", "Fair", "Poor"], value="Good")
|
295 |
+
ans3 = gr.Dropdown(label="3. How would you rate your current level of burnout?",
|
296 |
+
choices=["None", "Mild", "Moderate", "Severe"], value="None")
|
297 |
+
ans4 = gr.Dropdown(label="4. How well can you concentrate on your daily tasks?",
|
298 |
+
choices=["Excellent", "Good", "Fair", "Poor"], value="Good")
|
299 |
+
ans5 = gr.Dropdown(label="5. How often do you have trouble falling asleep?",
|
300 |
+
choices=["Never", "Rarely", "Sometimes", "Always"], value="Rarely")
|
301 |
+
ans6 = gr.Dropdown(label="6. How would you rate the quality of your sleep?",
|
302 |
+
choices=["Excellent", "Good", "Fair", "Poor"], value="Good")
|
303 |
+
ans7 = gr.Dropdown(label="7. How often do you wake up during the night?",
|
304 |
+
choices=["Never", "Rarely", "Sometimes", "Often"], value="Rarely")
|
305 |
+
ans8 = gr.Dropdown(label="8. How often do you feel anxious before sleep?",
|
306 |
+
choices=["Never", "Rarely", "Sometimes", "Often"], value="Rarely")
|
307 |
+
with gr.Column():
|
308 |
+
ans9 = gr.Dropdown(label="9. How happy are you with your eating habits?",
|
309 |
+
choices=["Very happy", "Happy", "Unhappy", "Very unhappy"], value="Happy")
|
310 |
+
ans10 = gr.Dropdown(label="10. How balanced is your diet?",
|
311 |
+
choices=["Very balanced", "Balanced", "Unbalanced", "Very unbalanced"], value="Balanced")
|
312 |
+
ans11 = gr.Dropdown(label="11. How often do you exercise or do physical activity?",
|
313 |
+
choices=["Daily", "Several times a week", "Once a week", "Never"], value="Daily")
|
314 |
+
ans12 = gr.Dropdown(label="12. How would you rate your physical strength?",
|
315 |
+
choices=["Excellent", "Good", "Fair", "Poor"], value="Good")
|
316 |
+
ans13 = gr.Dropdown(label="13. How motivated are you to work on your wellness goals daily?",
|
317 |
+
choices=["Very motivated", "Moderately motivated", "Slightly motivated", "Not at all"], value="Very motivated")
|
318 |
+
ans14 = gr.Dropdown(label="14. How would you rate your overall health and well-being?",
|
319 |
+
choices=["Excellent", "Good", "Fair", "Poor"], value="Good")
|
320 |
+
ans15 = gr.Textbox(label="15. Any more remarks about yourself (optional):", placeholder="Optional", lines=3)
|
321 |
+
|
322 |
+
with gr.Row():
|
323 |
+
submit_btn = gr.Button("Submit Assessment")
|
324 |
+
|
325 |
+
with gr.Row():
|
326 |
+
gr.Markdown("## Results")
|
327 |
+
with gr.Row():
|
328 |
+
donut_plot = gr.Plot(label="Overall Wellness Donut")
|
329 |
+
bar_plot = gr.Plot(label="KPI Bar Chart")
|
330 |
+
with gr.Row():
|
331 |
+
radar_plot = gr.Plot(label="Radar Chart")
|
332 |
+
bullet_plot = gr.Plot(label="Bullet Charts")
|
333 |
+
with gr.Row():
|
334 |
+
report_md = gr.Markdown(label="Assessment Report")
|
335 |
+
|
336 |
+
submit_btn.click(
|
337 |
+
fn=gradio_assessment,
|
338 |
+
inputs=[ans1, ans2, ans3, ans4, ans5, ans6, ans7, ans8, ans9, ans10, ans11, ans12, ans13, ans14, ans15],
|
339 |
+
outputs=[donut_plot, bar_plot, radar_plot, bullet_plot, report_md]
|
340 |
+
)
|
341 |
+
return demo
|
342 |
+
|
343 |
+
if __name__ == "__main__":
|
344 |
+
demo_app = build_app()
|
345 |
+
demo_app.launch(server_name="0.0.0.0", server_port=7860, share= True)
|
requirements.txt
ADDED
Binary file (2.88 kB). View file
|
|