leilaghomashchi commited on
Commit
b0a54ec
·
verified ·
1 Parent(s): dbc5b76

upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +521 -0
  2. requirements.txt +4 -0
app.py ADDED
@@ -0,0 +1,521 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import numpy as np
4
+ import plotly.express as px
5
+ import plotly.graph_objects as go
6
+ from plotly.subplots import make_subplots
7
+ import warnings
8
+
9
+ warnings.filterwarnings('ignore')
10
+
11
+ class CGMAnalyzer:
12
+ def __init__(self):
13
+ self.data = None
14
+ self.columns = []
15
+
16
+ # داده‌های نمونه CGM
17
+ self.sample_data = [
18
+ {'تاریخ': '2024-01-15', 'زمان': '07:30', 'قند_خون': 125, 'روند': 'افزایش_تند', 'وضعیت': 'نرمال', 'فعالیت': 'صبحانه', 'وعده_غذایی': 'صبحانه', 'انسولین': 5, 'استرس': 'کم'},
19
+ {'تاریخ': '2024-01-15', 'زمان': '08:00', 'قند_خون': 175, 'روند': 'افزایش_آرام', 'وضعیت': 'بالا', 'فعالیت': 'نشسته', 'وعده_غذایی': 'صبحانه', 'انسولین': 0, 'استرس': 'متوسط'},
20
+ {'تاریخ': '2024-01-15', 'زمان': '09:00', 'قند_خون': 152, 'روند': 'کاهش_آرام', 'وضعیت': 'بالا', 'فعالیت': 'کار', 'وعده_غذایی': 'نداشته', 'انسولین': 0, 'استرس': 'زیاد'},
21
+ {'تاریخ': '2024-01-15', 'زمان': '10:00', 'قند_خون': 108, 'روند': 'کاهش_آرام', 'وضعیت': 'نرمال', 'فعالیت': 'کار', 'وعده_غذایی': 'نداشته', 'انسولین': 0, 'استرس': 'کم'},
22
+ {'تاریخ': '2024-01-15', 'زمان': '12:30', 'قند_خون': 135, 'روند': 'افزایش_تند', 'وضعیت': 'نرمال', 'فعالیت': 'ناهار', 'وعده_غذایی': 'ناهار', 'انسولین': 3, 'استرس': 'کم'},
23
+ {'تاریخ': '2024-01-15', 'زمان': '13:00', 'قند_خون': 185, 'روند': 'افزایش_آرام', 'وضعیت': 'بالا', 'فعالیت': 'نشسته', 'وعده_غذایی': 'ناهار', 'انسولین': 0, 'استرس': 'کم'},
24
+ {'تاریخ': '2024-01-15', 'زمان': '17:00', 'قند_خون': 95, 'روند': 'پایدار', 'وضعیت': 'نرمال', 'فعالیت': 'ورزش', 'وعده_غذایی': 'نداشته', 'انسولین': 0, 'استرس': 'کم'},
25
+ {'تاریخ': '2024-01-15', 'زمان': '19:30', 'قند_خون': 145, 'روند': 'افزایش_تند', 'وضعیت': 'نرمال', 'فعالیت': 'شام', 'وعده_غذایی': 'شام', 'انسولین': 4, 'استرس': 'کم'}
26
+ ]
27
+
28
+ # سوالات آماده
29
+ self.diabetic_queries = [
30
+ 'قند من معمولاً چقدر است؟',
31
+ 'چقدر وقت قندم نرمال بوده؟',
32
+ 'قندم چه ساعاتی بالا می‌رود؟',
33
+ 'چه ساعاتی قندم نرمال است؟',
34
+ 'چند بار قندم خیلی پایین شده؟',
35
+ 'چند بار قندم خیلی بالا رفته؟',
36
+ 'کدام غذاها قندم را بالا می‌برند؟',
37
+ 'ورزش چه تاثیری روی قندم دارد؟',
38
+ 'انسولین چقدر قندم را پایین می‌آورد؟',
39
+ 'استرس چقدر قندم را بالا می‌برد؟'
40
+ ]
41
+
42
+ def load_sample_data(self):
43
+ """بارگذاری داده‌های نمونه"""
44
+ self.data = pd.DataFrame(self.sample_data)
45
+ self.columns = list(self.data.columns)
46
+ return self.data, "✅ داده‌های نمونه CGM بارگذاری شد"
47
+
48
+ def upload_file(self, file):
49
+ """بارگذاری فایل CSV"""
50
+ if file is None:
51
+ return None, "❌ لطفاً فایل CSV انتخاب کنید"
52
+
53
+ try:
54
+ # خواندن فایل CSV
55
+ self.data = pd.read_csv(file.name, encoding='utf-8')
56
+
57
+ # اگر UTF-8 کار نکرد، encoding های دیگر را امتحان کن
58
+ if self.data.empty:
59
+ self.data = pd.read_csv(file.name, encoding='cp1256')
60
+
61
+ self.columns = list(self.data.columns)
62
+
63
+ # تبدیل ستون‌های عددی
64
+ for col in self.columns:
65
+ if col in ['قند_خون', 'انسولین'] or 'قند' in col:
66
+ self.data[col] = pd.to_numeric(self.data[col], errors='coerce')
67
+
68
+ return self.data.head(10), f"✅ {len(self.data)} رکورد CGM با موفقیت بارگذاری شد"
69
+
70
+ except Exception as e:
71
+ return None, f"❌ خطا در خواندن فایل: {str(e)}"
72
+
73
+ def calculate_diabetic_stats(self):
74
+ """محاسبه آمار دیابت"""
75
+ if self.data is None or self.data.empty:
76
+ return None
77
+
78
+ # پیدا کردن ستون قند خون
79
+ glucose_col = None
80
+ for col in self.columns:
81
+ if 'قند' in col or 'glucose' in col.lower():
82
+ glucose_col = col
83
+ break
84
+
85
+ if glucose_col is None:
86
+ return None
87
+
88
+ glucose_values = self.data[glucose_col].dropna()
89
+ if len(glucose_values) == 0:
90
+ return None
91
+
92
+ # محاسبه آمار
93
+ time_in_range = len(glucose_values[(glucose_values >= 70) & (glucose_values <= 140)])
94
+ time_in_range_percent = (time_in_range / len(glucose_values)) * 100
95
+
96
+ hypo_count = len(glucose_values[glucose_values < 70])
97
+ hyper_count = len(glucose_values[glucose_values > 180])
98
+
99
+ mean_glucose = glucose_values.mean()
100
+ std_glucose = glucose_values.std()
101
+ cv = (std_glucose / mean_glucose) * 100 if mean_glucose > 0 else 0
102
+
103
+ return {
104
+ 'mean': mean_glucose,
105
+ 'time_in_range': time_in_range_percent,
106
+ 'hypo_count': hypo_count,
107
+ 'hyper_count': hyper_count,
108
+ 'variability': cv,
109
+ 'total_readings': len(glucose_values)
110
+ }
111
+
112
+ def create_glucose_trend_chart(self):
113
+ """نمودار روند قند خون"""
114
+ if self.data is None:
115
+ return None
116
+
117
+ # پیدا کردن ستون‌های مورد نیاز
118
+ glucose_col = None
119
+ time_col = None
120
+
121
+ for col in self.columns:
122
+ if 'قند' in col or 'glucose' in col.lower():
123
+ glucose_col = col
124
+ if 'زمان' in col or 'time' in col.lower():
125
+ time_col = col
126
+
127
+ if glucose_col is None:
128
+ return None
129
+
130
+ # ساخت نمودار
131
+ fig = go.Figure()
132
+
133
+ if time_col:
134
+ x_data = self.data[time_col]
135
+ else:
136
+ x_data = range(len(self.data))
137
+
138
+ # اضافه کردن خط قند خون
139
+ fig.add_trace(go.Scatter(
140
+ x=x_data,
141
+ y=self.data[glucose_col],
142
+ mode='lines+markers',
143
+ name='قند خون',
144
+ line=dict(color='blue', width=2),
145
+ marker=dict(size=6)
146
+ ))
147
+
148
+ # اضافه کردن خطوط مرجع
149
+ fig.add_hline(y=70, line_dash="dash", line_color="red",
150
+ annotation_text="حد پایین (70)")
151
+ fig.add_hline(y=140, line_dash="dash", line_color="green",
152
+ annotation_text="حد بالا (140)")
153
+ fig.add_hline(y=180, line_dash="dash", line_color="orange",
154
+ annotation_text="خطرناک (180)")
155
+
156
+ # تنظیمات نمودار
157
+ fig.update_layout(
158
+ title="روند قند خون در طول زمان",
159
+ xaxis_title="زمان",
160
+ yaxis_title="قند خون (mg/dL)",
161
+ hovermode='x',
162
+ template="plotly_white"
163
+ )
164
+
165
+ return fig
166
+
167
+ def create_daily_pattern_chart(self):
168
+ """نمودار الگوی روزانه قند خون"""
169
+ if self.data is None:
170
+ return None
171
+
172
+ glucose_col = None
173
+ time_col = None
174
+
175
+ for col in self.columns:
176
+ if 'قند' in col or 'glucose' in col.lower():
177
+ glucose_col = col
178
+ if 'زمان' in col or 'time' in col.lower():
179
+ time_col = col
180
+
181
+ if glucose_col is None or time_col is None:
182
+ return None
183
+
184
+ # گروه‌بندی بر اساس ساعت
185
+ self.data['hour'] = self.data[time_col].str.split(':').str[0]
186
+ hourly_avg = self.data.groupby('hour')[glucose_col].mean().reset_index()
187
+
188
+ fig = go.Figure()
189
+ fig.add_trace(go.Bar(
190
+ x=hourly_avg['hour'],
191
+ y=hourly_avg[glucose_col],
192
+ name='متوسط قند در هر ساعت',
193
+ marker_color='lightblue'
194
+ ))
195
+
196
+ fig.update_layout(
197
+ title="الگوی روزانه قند خون",
198
+ xaxis_title="ساعت",
199
+ yaxis_title="متوسط قند خون (mg/dL)",
200
+ template="plotly_white"
201
+ )
202
+
203
+ return fig
204
+
205
+ def create_meal_impact_chart(self):
206
+ """نمودار تاثیر وعده‌های غذایی"""
207
+ if self.data is None:
208
+ return None
209
+
210
+ glucose_col = None
211
+ meal_col = None
212
+
213
+ for col in self.columns:
214
+ if 'قند' in col or 'glucose' in col.lower():
215
+ glucose_col = col
216
+ if 'وعده' in col or 'meal' in col.lower():
217
+ meal_col = col
218
+
219
+ if glucose_col is None or meal_col is None:
220
+ return None
221
+
222
+ meal_avg = self.data.groupby(meal_col)[glucose_col].mean().reset_index()
223
+
224
+ fig = go.Figure()
225
+ fig.add_trace(go.Pie(
226
+ labels=meal_avg[meal_col],
227
+ values=meal_avg[glucose_col],
228
+ name="تاثیر وعده‌های غذایی"
229
+ ))
230
+
231
+ fig.update_layout(
232
+ title="متوسط قند خون در وعده‌های مختلف",
233
+ template="plotly_white"
234
+ )
235
+
236
+ return fig
237
+
238
+ def execute_query(self, query):
239
+ """اجرای سوالات کاربر"""
240
+ if self.data is None or self.data.empty:
241
+ return "❌ هیچ داده‌ای موجود نیست. لطفاً ابتدا فایل بارگذاری کنید یا داده نمونه را بارگذاری کنید."
242
+
243
+ query = query.strip()
244
+
245
+ try:
246
+ if query == 'قند من معمولاً چقدر است؟':
247
+ stats = self.calculate_diabetic_stats()
248
+ if stats:
249
+ return f"متوسط قند خون شما {stats['mean']:.0f} mg/dL است.\n" + \
250
+ ("این عدد خوب است! 🎉" if stats['mean'] < 140 else
251
+ "بهتر است با پزشک مشورت کنید. 👨‍⚕️" if stats['mean'] > 150 else "در حد قابل قبول است.")
252
+
253
+ elif query == 'چقدر وقت قندم نرمال بوده؟':
254
+ stats = self.calculate_diabetic_stats()
255
+ if stats:
256
+ return f"از {stats['total_readings']} بار اندازه‌گیری، {stats['time_in_range']:.1f}% وقت قند شما در حد نرمال (70-140) بوده است.\n" + \
257
+ ("عالی! 🎯" if stats['time_in_range'] > 70 else
258
+ "نیاز به بهبود دارد. 📈" if stats['time_in_range'] < 50 else "قابل قبول است. ✅")
259
+
260
+ elif query == 'چند بار قندم خیلی پایین شده؟':
261
+ stats = self.calculate_diabetic_stats()
262
+ if stats:
263
+ return f"{stats['hypo_count']} بار قند خون شما زیر 70 رفته است (هیپوگلایسمی).\n" + \
264
+ ("عالی! هیچ مورد هیپو نداشتید. 🎉" if stats['hypo_count'] == 0 else
265
+ "⚠️ مراقب باشید و با پزشک صحبت کنید.")
266
+
267
+ elif query == 'چند بار قندم خیلی بالا رفته؟':
268
+ stats = self.calculate_diabetic_stats()
269
+ if stats:
270
+ return f"{stats['hyper_count']} بار قند خون شما بالای 180 رفته است (هایپرگلایسمی).\n" + \
271
+ ("عالی! هیچ مورد هایپر شدید نداشتید. 🎉" if stats['hyper_count'] == 0 else
272
+ "⚠️ نیاز به کنترل بیشتر دارید.")
273
+
274
+ elif query == 'قندم چه ساعاتی بالا می‌رود؟':
275
+ glucose_col = None
276
+ time_col = None
277
+
278
+ for col in self.columns:
279
+ if 'قند' in col:
280
+ glucose_col = col
281
+ if 'زمان' in col:
282
+ time_col = col
283
+
284
+ if glucose_col and time_col:
285
+ high_glucose = self.data[self.data[glucose_col] > 140]
286
+ if not high_glucose.empty:
287
+ high_glucose['hour'] = high_glucose[time_col].str.split(':').str[0]
288
+ hour_counts = high_glucose['hour'].value_counts().head(3)
289
+ result = "قند شما بیشتر در این ساعات بالا می‌رود:\n"
290
+ for hour, count in hour_counts.items():
291
+ result += f"ساعت {hour}: {count} بار\n"
292
+ return result
293
+ else:
294
+ return "عالی! قند شما در هیچ ساعتی بالای 140 نرفته است. 🎉"
295
+
296
+ elif query == 'کدام غذاها قندم را بالا می‌برند؟':
297
+ glucose_col = None
298
+ meal_col = None
299
+
300
+ for col in self.columns:
301
+ if 'قند' in col:
302
+ glucose_col = col
303
+ if 'وعده' in col:
304
+ meal_col = col
305
+
306
+ if glucose_col and meal_col:
307
+ meal_avg = self.data.groupby(meal_col)[glucose_col].mean().sort_values(ascending=False)
308
+ result = "متوسط قند خون بعد از وعده‌های مختلف:\n"
309
+ for meal, avg in meal_avg.items():
310
+ status = "🔴" if avg > 160 else "🟡" if avg > 140 else "🟢"
311
+ result += f"{status} {meal}: {avg:.0f} mg/dL\n"
312
+ return result
313
+
314
+ elif query == 'ورزش چه تاثیری روی قندم دارد؟':
315
+ glucose_col = None
316
+ activity_col = None
317
+
318
+ for col in self.columns:
319
+ if 'قند' in col:
320
+ glucose_col = col
321
+ if 'فعالیت' in col:
322
+ activity_col = col
323
+
324
+ if glucose_col and activity_col:
325
+ exercise_data = self.data[self.data[activity_col] == 'ورزش']
326
+ if not exercise_data.empty:
327
+ avg_exercise = exercise_data[glucose_col].mean()
328
+ non_exercise = self.data[self.data[activity_col] != 'ورزش']
329
+ avg_non_exercise = non_exercise[glucose_col].mean()
330
+ difference = avg_non_exercise - avg_exercise
331
+
332
+ return f"هنگام ورزش متوسط قند شما {avg_exercise:.0f} و در سایر اوقات {avg_non_exercise:.0f} است.\n" + \
333
+ f"ورزش {difference:.0f} واحد قند را کم می‌کند. 💪" if difference > 0 else \
334
+ "ورزش تاثیر منفی روی قند شما نداشته. 👍"
335
+ else:
336
+ return "در این دوره فعالیت ورزشی ثبت نشده است."
337
+
338
+ else:
339
+ return "متوجه سوال شما نشدم. لطفاً یکی از سوالات آماده را انتخاب کنید."
340
+
341
+ except Exception as e:
342
+ return f"❌ مشکلی پیش آمده: {str(e)}"
343
+
344
+ def get_data_summary(self):
345
+ """خلاصه داده‌ها"""
346
+ if self.data is None:
347
+ return "هیچ داده‌ای بارگذاری نشده است."
348
+
349
+ summary = f"📊 تعداد رکوردها: {len(self.data)}\n"
350
+ summary += f"📅 ستون‌ها: {', '.join(self.columns)}\n"
351
+
352
+ stats = self.calculate_diabetic_stats()
353
+ if stats:
354
+ summary += f"\n🩺 آمار کلی:\n"
355
+ summary += f"• متوسط قند: {stats['mean']:.0f} mg/dL\n"
356
+ summary += f"• زمان در محدوده: {stats['time_in_range']:.1f}%\n"
357
+ summary += f"• تعداد هیپو: {stats['hypo_count']}\n"
358
+ summary += f"• تعداد هایپر: {stats['hyper_count']}\n"
359
+ summary += f"• تنوع گلایسمی: {stats['variability']:.1f}%\n"
360
+
361
+ return summary
362
+
363
+ # ساخت اپلیکیشن Gradio
364
+ def create_app():
365
+ analyzer = CGMAnalyzer()
366
+
367
+ # CSS برای RTL و استایل بهتر
368
+ custom_css = """
369
+ .rtl { direction: rtl; text-align: right; }
370
+ .main-title { text-align: center; color: #d63384; font-size: 28px; font-weight: bold; margin: 20px 0; }
371
+ .subtitle { text-align: center; color: #6c757d; margin-bottom: 30px; font-size: 16px; }
372
+ .section-title { color: #6f42c1; font-weight: bold; margin: 20px 0 10px 0; }
373
+ .gradio-container { font-family: 'Segoe UI', Tahoma, Arial, sans-serif; }
374
+ """
375
+
376
+ with gr.Blocks(title="تحلیل‌گر داده‌های CGM", theme=gr.themes.Soft(), css=custom_css) as app:
377
+
378
+ gr.HTML('<div class="main-title">🩺 تحلیل‌گر داده‌های CGM</div>')
379
+ gr.HTML('<div class="subtitle">مانیتورینگ مداوم قند خون • ابزار تحلیل هوشمند برای بیماران دیابتی</div>')
380
+
381
+ with gr.Tab("📂 بارگذاری داده‌ها"):
382
+ with gr.Row():
383
+ with gr.Column():
384
+ file_input = gr.File(
385
+ label="انتخاب فایل CSV",
386
+ file_types=[".csv"],
387
+ elem_classes=["rtl"]
388
+ )
389
+ sample_btn = gr.Button("🔄 بارگذاری داده نمونه", variant="secondary")
390
+ upload_status = gr.Textbox(
391
+ label="وضعیت بارگذاری",
392
+ interactive=False,
393
+ elem_classes=["rtl"]
394
+ )
395
+
396
+ with gr.Column():
397
+ data_summary = gr.Textbox(
398
+ label="خلاصه داده‌ها",
399
+ lines=8,
400
+ interactive=False,
401
+ elem_classes=["rtl"]
402
+ )
403
+
404
+ data_preview = gr.Dataframe(
405
+ label="نمایش داده‌ها",
406
+ wrap=True,
407
+ elem_classes=["rtl"]
408
+ )
409
+
410
+ with gr.Tab("🤔 سوالات آماده"):
411
+ gr.HTML('<div class="section-title">سوالات رایج از قند خون - روی هر دکمه کلیک کنید:</div>')
412
+
413
+ with gr.Row():
414
+ with gr.Column():
415
+ query_buttons = []
416
+ for i, query in enumerate(analyzer.diabetic_queries):
417
+ btn = gr.Button(query, elem_classes=["rtl"])
418
+ query_buttons.append(btn)
419
+
420
+ query_result = gr.Textbox(
421
+ label="پاسخ سوال",
422
+ lines=5,
423
+ interactive=False,
424
+ elem_classes=["rtl"]
425
+ )
426
+
427
+ with gr.Tab("💬 سوال دلخواه"):
428
+ with gr.Row():
429
+ custom_query = gr.Textbox(
430
+ label="سوال خود را بنویسید",
431
+ placeholder="مثال: قند من معمولاً چقدر است؟",
432
+ elem_classes=["rtl"]
433
+ )
434
+ ask_btn = gr.Button("🔍 پرسش", variant="primary")
435
+
436
+ custom_result = gr.Textbox(
437
+ label="پاسخ",
438
+ lines=5,
439
+ interactive=False,
440
+ elem_classes=["rtl"]
441
+ )
442
+
443
+ with gr.Tab("📈 نمودارها"):
444
+ gr.HTML('<div class="section-title">نمودارهای تحلیل داده‌ها</div>')
445
+
446
+ with gr.Row():
447
+ trend_btn = gr.Button("📊 روند قند خون")
448
+ pattern_btn = gr.Button("🕐 الگوی روزانه")
449
+ meal_btn = gr.Button("🍽️ تاثیر وعده‌ها")
450
+
451
+ chart_output = gr.Plot(label="نمودار")
452
+
453
+ with gr.Tab("💡 راهنما"):
454
+ gr.HTML("""
455
+ <div class="rtl" style="padding: 20px; font-family: Tahoma;">
456
+ <h3>💡 راهنمای استفاده:</h3>
457
+ <ul style="line-height: 1.8;">
458
+ <li><strong>بارگذاری داده‌ها:</strong> فایل CSV حاوی ستون‌های تاریخ، زمان، قند_خون، وضعیت، فعالیت، وعده_غذایی، انسولین</li>
459
+ <li><strong>سوالات آماده:</strong> روی هر سوال کلیک کنید تا پاسخ را ببینید</li>
460
+ <li><strong>سوال دلخواه:</strong> سوال خود را با کلمات ساده بنویسید</li>
461
+ <li><strong>نمودارها:</strong> تحلیل بصری داده‌های شما</li>
462
+ </ul>
463
+
464
+ <h3>📊 محدوده‌های قند خون:</h3>
465
+ <ul style="line-height: 1.8;">
466
+ <li><span style="color: red; font-weight: bold;">🔴 خطرناک:</span> کمتر از 70 (فوری به پزشک مراجعه کنید)</li>
467
+ <li><span style="color: green; font-weight: bold;">🟢 خوب:</span> 70 تا 140 (عالی است)</li>
468
+ <li><span style="color: orange; font-weight: bold;">🟡 بالا:</span> بیشتر از 140 (بهتر است کنترل کنید)</li>
469
+ <li><span style="color: red; font-weight: bold;">🔴 خیلی بالا:</span> بیشتر از 180 (حتماً با پزشک صحبت کنید)</li>
470
+ </ul>
471
+
472
+ <h3>🏥 نکات مهم:</h3>
473
+ <ul style="line-height: 1.8;">
474
+ <li><strong>هدف:</strong> بیش از 70% وقت قند در محدوده نرمال باشد</li>
475
+ <li>اگر قند زیر 70 رفت، فوری شکر یا آبمیوه بخورید</li>
476
+ <li>اگر قند بالای 300 رفت، فوری به بیمارستان بروید</li>
477
+ <li><strong style="color: red;">این برنامه جایگزین مشاوره پزشک نیست</strong></li>
478
+ </ul>
479
+
480
+ <h3>🔒 حریم خصوصی:</h3>
481
+ <p>داده‌های شما محلی پردازش می‌شوند و ذخیره نمی‌شوند.</p>
482
+ </div>
483
+ """)
484
+
485
+ # Event handlers
486
+ def upload_and_preview(file):
487
+ data, status = analyzer.upload_file(file)
488
+ summary = analyzer.get_data_summary()
489
+ return data, status, summary
490
+
491
+ def load_sample_and_preview():
492
+ data, status = analyzer.load_sample_data()
493
+ summary = analyzer.get_data_summary()
494
+ return data, status, summary
495
+
496
+ # اتصال رویدادها
497
+ file_input.upload(upload_and_preview, inputs=file_input, outputs=[data_preview, upload_status, data_summary])
498
+ sample_btn.click(load_sample_and_preview, outputs=[data_preview, upload_status, data_summary])
499
+
500
+ # اتصال دکمه‌های سوالات آماده
501
+ for i, btn in enumerate(query_buttons):
502
+ btn.click(
503
+ lambda q=analyzer.diabetic_queries[i]: analyzer.execute_query(q),
504
+ outputs=query_result
505
+ )
506
+
507
+ # سوال دلخواه
508
+ ask_btn.click(analyzer.execute_query, inputs=custom_query, outputs=custom_result)
509
+ custom_query.submit(analyzer.execute_query, inputs=custom_query, outputs=custom_result)
510
+
511
+ # نمودارها
512
+ trend_btn.click(analyzer.create_glucose_trend_chart, outputs=chart_output)
513
+ pattern_btn.click(analyzer.create_daily_pattern_chart, outputs=chart_output)
514
+ meal_btn.click(analyzer.create_meal_impact_chart, outputs=chart_output)
515
+
516
+ return app
517
+
518
+ # برای Hugging Face Spaces
519
+ if __name__ == "__main__":
520
+ app = create_app()
521
+ app.launch()
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ gradio==4.44.0
2
+ pandas==2.0.3
3
+ numpy==1.24.3
4
+ plotly==5.17.0