CoolFace
Apppublic

leilaghomashchi/cgm-data-analyzer

sourceHugging Facemitupdated 1y agoView on Hugging Face
0likes
app.py1112 linesDownload Raw Back to root
1import gradio as gr2import pandas as pd3import numpy as np4import plotly.express as px5import plotly.graph_objects as go6from plotly.subplots import make_subplots7import warnings8 9warnings.filterwarnings('ignore')10 11class CGMAnalyzer:12    def __init__(self):13        self.data = None14        self.columns = []15        16        # داده‌های نمونه CGM17        self.sample_data = [18            {'تاریخ': '2024-01-15', 'زمان': '07:30', 'قند_خون': 125, 'روند': 'افزایش_تند', 'وضعیت': 'نرمال', 'فعالیت': 'صبحانه', 'وعده_غذایی': 'صبحانه', 'انسولین': 5, 'استرس': 'کم', 'خواب': 'خیر', 'کیفیت_خواب': 'خوب', 'آب_وهوا': 'آفتابی', 'فشار_خون': '120/80', 'دارو': 'متفورمین', 'وزن': 75.2, 'ضربان_قلب': 72, 'مایعات_مصرفی': 250, 'قدم_ها': 320, 'کالری_مصرفی': 280, 'یادداشت': ''},19            {'تاریخ': '2024-01-15', 'زمان': '08:00', 'قند_خون': 175, 'روند': 'افزایش_آرام', 'وضعیت': 'بالا', 'فعالیت': 'نشسته', 'وعده_غذایی': 'نداشته', 'انسولین': 0, 'استرس': 'متوسط', 'خواب': 'خیر', 'کیفیت_خواب': 'خوب', 'آب_وهوا': 'آفتابی', 'فشار_خون': '125/85', 'دارو': 'هیچ', 'وزن': 75.1, 'ضربان_قلب': 78, 'مایعات_مصرفی': 180, 'قدم_ها': 150, 'کالری_مصرفی': 0, 'یادداشت': 'کمی گرسنه'},20            {'تاریخ': '2024-01-15', 'زمان': '09:00', 'قند_خون': 152, 'روند': 'کاهش_آرام', 'وضعیت': 'بالا', 'فعالیت': 'کار', 'وعده_غذایی': 'نداشته', 'انسولین': 0, 'استرس': 'زیاد', 'خواب': 'خیر', 'کیفیت_خواب': 'خوب', 'آب_وهوا': 'آفتابی', 'فشار_خون': '130/90', 'دارو': 'هیچ', 'وزن': 75.0, 'ضربان_قلب': 85, 'مایعات_مصرفی': 200, 'قدم_ها': 450, 'کالری_مصرفی': 0, 'یادداشت': ''},21            {'تاریخ': '2024-01-15', 'زمان': '10:00', 'قند_خون': 108, 'روند': 'کاهش_آرام', 'وضعیت': 'نرمال', 'فعالیت': 'کار', 'وعده_غذایی': 'نداشته', 'انسولین': 0, 'استرس': 'کم', 'خواب': 'خیر', 'کیفیت_خواب': 'خوب', 'آب_وهوا': 'آفتابی', 'فشار_خون': '118/78', 'دارو': 'هیچ', 'وزن': 74.9, 'ضربان_قلب': 70, 'مایعات_مصرفی': 220, 'قدم_ها': 680, 'کالری_مصرفی': 0, 'یادداشت': ''},22            {'تاریخ': '2024-01-15', 'زمان': '12:30', 'قند_خون': 135, 'روند': 'افزایش_تند', 'وضعیت': 'نرمال', 'فعالیت': 'ناهار', 'وعده_غذایی': 'ناهار', 'انسولین': 3, 'استرس': 'کم', 'خواب': 'خیر', 'کیفیت_خواب': 'خوب', 'آب_وهوا': 'آفتابی', 'فشار_خون': '115/75', 'دارو': 'هیچ', 'وزن': 74.8, 'ضربان_قلب': 68, 'مایعات_مصرفی': 320, 'قدم_ها': 1250, 'کالری_مصرفی': 450, 'یادداشت': ''},23            {'تاریخ': '2024-01-15', 'زمان': '13:00', 'قند_خون': 185, 'روند': 'افزایش_آرام', 'وضعیت': 'بالا', 'فعالیت': 'نشسته', 'وعده_غذایی': 'نداشته', 'انسولین': 0, 'استرس': 'کم', 'خواب': 'خیر', 'کیفیت_خواب': 'خوب', 'آب_وهوا': 'آفتابی', 'فشار_خون': '122/82', 'دارو': 'هیچ', 'وزن': 74.7, 'ضربان_قلب': 75, 'مایعات_مصرفی': 180, 'قدم_ها': 80, 'کالری_مصرفی': 0, 'یادداشت': ''},24            {'تاریخ': '2024-01-15', 'زمان': '17:00', 'قند_خون': 95, 'روند': 'پایدار', 'وضعیت': 'نرمال', 'فعالیت': 'ورزش', 'وعده_غذایی': 'نداشته', 'انسولین': 0, 'استرس': 'کم', 'خواب': 'خیر', 'کیفیت_خواب': 'خوب', 'آب_وهوا': 'آفتابی', 'فشار_خون': '110/70', 'دارو': 'هیچ', 'وزن': 74.5, 'ضربان_قلب': 95, 'مایعات_مصرفی': 400, 'قدم_ها': 5200, 'کالری_مصرفی': 0, 'یادداشت': 'احساس خوب'},25            {'تاریخ': '2024-01-15', 'زمان': '19:30', 'قند_خون': 145, 'روند': 'افزایش_تند', 'وضعیت': 'نرمال', 'فعالیت': 'شام', 'وعده_غذایی': 'شام', 'انسولین': 4, 'استرس': 'کم', 'خواب': 'خیر', 'کیفیت_خواب': 'خوب', 'آب_وهوا': 'آفتابی', 'فشار_خون': '125/85', 'دارو': 'هیچ', 'وزن': 74.4, 'ضربان_قلب': 72, 'مایعات_مصرفی': 250, 'قدم_ها': 420, 'کالری_مصرفی': 380, 'یادداشت': ''}26        ]27        28        # سوالات آماده29        self.diabetic_queries = [30            'قند من معمولاً چقدر است؟',31            'چقدر وقت قندم نرمال بوده؟', 32            'قندم چه ساعاتی بالا می‌رود؟',33            'چه ساعاتی قندم نرمال است؟',34            'چند بار قندم خیلی پایین شده؟',35            'چند بار قندم خیلی بالا رفته؟',36            'کدام غذاها قندم را بالا می‌برند؟',37            'ورزش چه تاثیری روی قندم دارد؟',38            'انسولین چقدر قندم را پایین می‌آورد؟',39            'استرس چقدر قندم را بالا می‌برد؟',40            'آب‌وهوا چطور روی قندم تاثیر می‌گذارد؟',41            'کیفیت خوابم چه تاثیری روی قند دارد؟',42            'چقدر ورزش کرده‌ام؟',43            'فشار خونم چطوره؟',44            'وزنم چطور تغییر کرده؟'45        ]46 47    def get_column_safely(self, column_keywords):48        """پیدا کردن ستون به صورت ایمن"""49        for keyword in column_keywords:50            for col in self.columns:51                if keyword in col:52                    return col53        return None54 55    def load_sample_data(self):56        """بارگذاری داده‌های نمونه"""57        self.data = pd.DataFrame(self.sample_data)58        self.columns = list(self.data.columns)59        # نمایش همه داده‌های نمونه (8 رکورد)60        return self.data, "✅ داده‌های نمونه CGM بارگذاری شد"61 62    def upload_file(self, file):63        """بارگذاری فایل CSV"""64        if file is None:65            return None, "❌ لطفاً فایل CSV انتخاب کنید"66        67        try:68            # خواندن فایل CSV69            self.data = pd.read_csv(file.name, encoding='utf-8')70            71            # اگر UTF-8 کار نکرد، encoding های دیگر را امتحان کن72            if self.data.empty:73                self.data = pd.read_csv(file.name, encoding='cp1256')74            75            self.columns = list(self.data.columns)76            77            # تبدیل ستون‌های عددی78            for col in self.columns:79                if col in ['قند_خون', 'انسولین'] or 'قند' in col:80                    self.data[col] = pd.to_numeric(self.data[col], errors='coerce')81            82            # نمایش تعداد بیشتری از رکوردها (25 به جای 10)83            return self.data.head(25), f"✅ {len(self.data)} رکورد CGM با موفقیت بارگذاری شد"84            85        except Exception as e:86            return None, f"❌ خطا در خواندن فایل: {str(e)}"87 88    def calculate_diabetic_stats(self):89        """محاسبه آمار دیابت"""90        if self.data is None or self.data.empty:91            return None92        93        # پیدا کردن ستون قند خون94        glucose_col = None95        for col in self.columns:96            if 'قند' in col or 'glucose' in col.lower():97                glucose_col = col98                break99        100        if glucose_col is None:101            return None102        103        glucose_values = self.data[glucose_col].dropna()104        if len(glucose_values) == 0:105            return None106        107        # محاسبه آمار108        time_in_range = len(glucose_values[(glucose_values >= 70) & (glucose_values <= 140)])109        time_in_range_percent = (time_in_range / len(glucose_values)) * 100110        111        hypo_count = len(glucose_values[glucose_values < 70])112        hyper_count = len(glucose_values[glucose_values > 180])113        114        mean_glucose = glucose_values.mean()115        std_glucose = glucose_values.std()116        cv = (std_glucose / mean_glucose) * 100 if mean_glucose > 0 else 0117        118        return {119            'mean': mean_glucose,120            'time_in_range': time_in_range_percent,121            'hypo_count': hypo_count,122            'hyper_count': hyper_count,123            'variability': cv,124            'total_readings': len(glucose_values)125        }126 127    def create_glucose_trend_chart(self):128        """نمودار روند قند خون"""129        if self.data is None:130            return None131        132        # پیدا کردن ستون‌های مورد نیاز133        glucose_col = None134        time_col = None135        136        for col in self.columns:137            if 'قند' in col or 'glucose' in col.lower():138                glucose_col = col139            if 'زمان' in col or 'time' in col.lower():140                time_col = col141        142        if glucose_col is None:143            return None144        145        # ساخت نمودار146        fig = go.Figure()147        148        if time_col:149            x_data = self.data[time_col]150        else:151            x_data = range(len(self.data))152        153        # اضافه کردن خط قند خون154        fig.add_trace(go.Scatter(155            x=x_data,156            y=self.data[glucose_col],157            mode='lines+markers',158            name='قند خون',159            line=dict(color='blue', width=2),160            marker=dict(size=6)161        ))162        163        # اضافه کردن خطوط مرجع164        fig.add_hline(y=70, line_dash="dash", line_color="red", 165                     annotation_text="حد پایین (70)")166        fig.add_hline(y=140, line_dash="dash", line_color="green", 167                     annotation_text="حد بالا (140)")168        fig.add_hline(y=180, line_dash="dash", line_color="orange", 169                     annotation_text="خطرناک (180)")170        171        # تنظیمات نمودار172        fig.update_layout(173            title="روند قند خون در طول زمان",174            xaxis_title="زمان",175            yaxis_title="قند خون (mg/dL)",176            hovermode='x',177            template="plotly_white"178        )179        180        return fig181 182    def create_daily_pattern_chart(self):183        """نمودار الگوی روزانه قند خون"""184        if self.data is None:185            return None186        187        glucose_col = None188        time_col = None189        190        for col in self.columns:191            if 'قند' in col or 'glucose' in col.lower():192                glucose_col = col193            if 'زمان' in col or 'time' in col.lower():194                time_col = col195        196        if glucose_col is None or time_col is None:197            return None198        199        # گروه‌بندی بر اساس ساعت200        self.data['hour'] = self.data[time_col].str.split(':').str[0]201        hourly_avg = self.data.groupby('hour')[glucose_col].mean().reset_index()202        203        fig = go.Figure()204        fig.add_trace(go.Bar(205            x=hourly_avg['hour'],206            y=hourly_avg[glucose_col],207            name='متوسط قند در هر ساعت',208            marker_color='lightblue'209        ))210        211        fig.update_layout(212            title="الگوی روزانه قند خون",213            xaxis_title="ساعت",214            yaxis_title="متوسط قند خون (mg/dL)",215            template="plotly_white"216        )217        218        return fig219 220    def create_meal_impact_chart(self):221        """نمودار تاثیر وعده‌های غذایی"""222        if self.data is None:223            return None224        225        glucose_col = None226        meal_col = None227        228        for col in self.columns:229            if 'قند' in col or 'glucose' in col.lower():230                glucose_col = col231            if 'وعده' in col or 'meal' in col.lower():232                meal_col = col233        234        if glucose_col is None or meal_col is None:235            return None236        237        meal_avg = self.data.groupby(meal_col)[glucose_col].mean().reset_index()238        239        fig = go.Figure()240        fig.add_trace(go.Pie(241            labels=meal_avg[meal_col],242            values=meal_avg[glucose_col],243            name="تاثیر وعده‌های غذایی"244        ))245        246        fig.update_layout(247            title="متوسط قند خون در وعده‌های مختلف",248            template="plotly_white"249        )250        251        return fig252 253    def create_weight_trend_chart(self):254        """نمودار روند وزن"""255        if self.data is None:256            return None257        258        weight_col = None259        date_col = None260        261        for col in self.columns:262            if 'وزن' in col:263                weight_col = col264            if 'تاریخ' in col:265                date_col = col266        267        if weight_col is None or date_col is None:268            return None269        270        # گروه‌بندی بر اساس تاریخ و میانگین‌گیری271        daily_weight = self.data.groupby(date_col)[weight_col].mean().reset_index()272        273        fig = go.Figure()274        fig.add_trace(go.Scatter(275            x=daily_weight[date_col],276            y=daily_weight[weight_col],277            mode='lines+markers',278            name='وزن روزانه',279            line=dict(color='purple', width=3),280            marker=dict(size=8)281        ))282        283        fig.update_layout(284            title="روند تغییرات وزن",285            xaxis_title="تاریخ",286            yaxis_title="وزن (کیلوگرم)",287            template="plotly_white"288        )289        290        return fig291 292    def create_activity_chart(self):293        """نمودار فعالیت فیزیکی"""294        if self.data is None:295            return None296        297        steps_col = None298        date_col = None299        300        for col in self.columns:301            if 'قدم' in col:302                steps_col = col303            if 'تاریخ' in col:304                date_col = col305        306        if steps_col is None or date_col is None:307            return None308        309        # گروه‌بندی بر اساس تاریخ310        daily_steps = self.data.groupby(date_col)[steps_col].sum().reset_index()311        312        fig = go.Figure()313        fig.add_trace(go.Bar(314            x=daily_steps[date_col],315            y=daily_steps[steps_col],316            name='قدم‌های روزانه',317            marker_color='lightgreen'318        ))319        320        # اضافه کردن خط مرجع 10,000 قدم321        fig.add_hline(y=10000, line_dash="dash", line_color="red", 322                     annotation_text="هدف روزانه (10,000)")323        324        fig.update_layout(325            title="فعالیت فیزیکی روزانه",326            xaxis_title="تاریخ",327            yaxis_title="تعداد قدم",328            template="plotly_white"329        )330        331        return fig332 333    def create_stress_correlation_chart(self):334        """نمودار همبستگی استرس و قند"""335        if self.data is None:336            return None337        338        glucose_col = None339        stress_col = None340        341        for col in self.columns:342            if 'قند' in col:343                glucose_col = col344            if 'استرس' in col:345                stress_col = col346        347        if glucose_col is None or stress_col is None:348            return None349        350        # تبدیل سطوح استرس به عدد برای نمودار351        stress_mapping = {'خیلی_کم': 1, 'کم': 2, 'متوسط': 3, 'زیاد': 4, 'خیلی_زیاد': 5}352        plot_data = self.data.copy()353        plot_data['stress_numeric'] = plot_data[stress_col].map(stress_mapping)354        355        fig = go.Figure()356        357        for stress_level in plot_data[stress_col].unique():358            stress_data = plot_data[plot_data[stress_col] == stress_level]359            fig.add_trace(go.Scatter(360                x=stress_data['stress_numeric'],361                y=stress_data[glucose_col],362                mode='markers',363                name=f'استرس {stress_level}',364                marker=dict(size=8, opacity=0.7)365            ))366        367        fig.update_layout(368            title="رابطه بین سطح استرس و قند خون",369            xaxis_title="سطح استرس",370            yaxis_title="قند خون (mg/dL)",371            xaxis=dict(372                tickmode='array',373                tickvals=[1, 2, 3, 4, 5],374                ticktext=['خیلی کم', 'کم', 'متوسط', 'زیاد', 'خیلی زیاد']375            ),376            template="plotly_white"377        )378        379        return fig380 381    def execute_query(self, query):382        """اجرای سوالات کاربر"""383        if self.data is None or self.data.empty:384            return "❌ هیچ داده‌ای موجود نیست. لطفاً ابتدا فایل بارگذاری کنید یا داده نمونه را بارگذاری کنید."385        386        query = query.strip()387        388        try:389            if query == 'قند من معمولاً چقدر است؟':390                stats = self.calculate_diabetic_stats()391                if stats:392                    return f"متوسط قند خون شما {stats['mean']:.0f} mg/dL است.\n" + \393                           ("این عدد خوب است! 🎉" if stats['mean'] < 140 else 394                            "بهتر است با پزشک مشورت کنید. 👨‍⚕️" if stats['mean'] > 150 else "در حد قابل قبول است.")395            396            elif query == 'چقدر وقت قندم نرمال بوده؟':397                stats = self.calculate_diabetic_stats()398                if stats:399                    return f"از {stats['total_readings']} بار اندازه‌گیری، {stats['time_in_range']:.1f}% وقت قند شما در حد نرمال (70-140) بوده است.\n" + \400                           ("عالی! 🎯" if stats['time_in_range'] > 70 else 401                            "نیاز به بهبود دارد. 📈" if stats['time_in_range'] < 50 else "قابل قبول است. ✅")402            403            elif query == 'چند بار قندم خیلی پایین شده؟':404                stats = self.calculate_diabetic_stats()405                if stats:406                    return f"{stats['hypo_count']} بار قند خون شما زیر 70 رفته است (هیپوگلایسمی).\n" + \407                           ("عالی! هیچ مورد هیپو نداشتید. 🎉" if stats['hypo_count'] == 0 else 408                            "⚠️ مراقب باشید و با پزشک صحبت کنید.")409            410            elif query == 'چند بار قندم خیلی بالا رفته؟':411                stats = self.calculate_diabetic_stats()412                if stats:413                    return f"{stats['hyper_count']} بار قند خون شما بالای 180 رفته است (هایپرگلایسمی).\n" + \414                           ("عالی! هیچ مورد هایپر شدید نداشتید. 🎉" if stats['hyper_count'] == 0 else 415                            "⚠️ نیاز به کنترل بیشتر دارید.")416            417            elif query == 'قندم چه ساعاتی بالا می‌رود؟':418                glucose_col = None419                time_col = None420                421                for col in self.columns:422                    if 'قند' in col:423                        glucose_col = col424                    if 'زمان' in col:425                        time_col = col426                427                if glucose_col and time_col:428                    high_glucose = self.data[self.data[glucose_col] > 140]429                    if not high_glucose.empty:430                        high_glucose['hour'] = high_glucose[time_col].str.split(':').str[0]431                        hour_counts = high_glucose['hour'].value_counts().head(3)432                        result = "قند شما بیشتر در این ساعات بالا می‌رود:\n"433                        for hour, count in hour_counts.items():434                            result += f"ساعت {hour}: {count} بار\n"435                        return result436                    else:437                        return "عالی! قند شما در هیچ ساعتی بالای 140 نرفته است. 🎉"438            439            elif query == 'چه ساعاتی قندم نرمال است؟':440                glucose_col = None441                time_col = None442                443                for col in self.columns:444                    if 'قند' in col:445                        glucose_col = col446                    if 'زمان' in col:447                        time_col = col448                449                if glucose_col and time_col:450                    normal_glucose = self.data[(self.data[glucose_col] >= 70) & (self.data[glucose_col] <= 140)]451                    if not normal_glucose.empty:452                        normal_glucose['hour'] = normal_glucose[time_col].str.split(':').str[0]453                        hour_counts = normal_glucose['hour'].value_counts().head(5)454                        result = "قند شما بیشتر در این ساعات نرمال است:\n"455                        for hour, count in hour_counts.items():456                            total_in_hour = len(self.data[self.data[time_col].str.startswith(str(hour))])457                            percentage = (count / total_in_hour * 100) if total_in_hour > 0 else 0458                            result += f"ساعت {hour}: {count} بار ({percentage:.0f}%) 🟢\n"459                        return result460                    else:461                        return "متأسفانه در هیچ ساعتی قند شما نرمال نبوده است. با پزشک مشورت کنید. ⚠️"462            463            elif query == 'کدام غذاها قندم را بالا می‌برند؟':464                glucose_col = None465                meal_col = None466                467                for col in self.columns:468                    if 'قند' in col:469                        glucose_col = col470                    if 'وعده' in col:471                        meal_col = col472                473                if glucose_col and meal_col:474                    meal_avg = self.data.groupby(meal_col)[glucose_col].mean().sort_values(ascending=False)475                    result = "متوسط قند خون بعد از وعده‌های مختلف:\n"476                    for meal, avg in meal_avg.items():477                        status = "🔴" if avg > 160 else "🟡" if avg > 140 else "🟢"478                        result += f"{status} {meal}: {avg:.0f} mg/dL\n"479                    return result480            481            elif query == 'ورزش چه تاثیری روی قندم دارد؟':482                glucose_col = None483                activity_col = None484                485                for col in self.columns:486                    if 'قند' in col:487                        glucose_col = col488                    if 'فعالیت' in col:489                        activity_col = col490                491                if glucose_col and activity_col:492                    exercise_data = self.data[self.data[activity_col] == 'ورزش']493                    if not exercise_data.empty:494                        avg_exercise = exercise_data[glucose_col].mean()495                        non_exercise = self.data[self.data[activity_col] != 'ورزش']496                        avg_non_exercise = non_exercise[glucose_col].mean()497                        difference = avg_non_exercise - avg_exercise498                        499                        return f"هنگام ورزش متوسط قند شما {avg_exercise:.0f} و در سایر اوقات {avg_non_exercise:.0f} است.\n" + \500                               f"ورزش {difference:.0f} واحد قند را کم می‌کند. 💪" if difference > 0 else \501                               "ورزش تاثیر منفی روی قند شما نداشته. 👍"502                    else:503                        return "در این دوره فعالیت ورزشی ثبت نشده است."504            505            elif query == 'انسولین چقدر قندم را پایین می‌آورد؟':506                glucose_col = None507                insulin_col = None508                509                for col in self.columns:510                    if 'قند' in col:511                        glucose_col = col512                    if 'انسولین' in col:513                        insulin_col = col514                515                if glucose_col and insulin_col:516                    # مقایسه قند قبل و بعد از انسولین517                    insulin_data = self.data[self.data[insulin_col] > 0]518                    no_insulin_data = self.data[self.data[insulin_col] == 0]519                    520                    if not insulin_data.empty and not no_insulin_data.empty:521                        avg_with_insulin = insulin_data[glucose_col].mean()522                        avg_without_insulin = no_insulin_data[glucose_col].mean()523                        524                        # محاسبه متوسط انسولین مصرفی525                        avg_insulin_dose = insulin_data[insulin_col].mean()526                        527                        # تاثیر هر واحد انسولین528                        effect_per_unit = (avg_without_insulin - avg_with_insulin) / avg_insulin_dose if avg_insulin_dose > 0 else 0529                        530                        result = f"تحلیل تاثیر انسولین:\n"531                        result += f"• متوسط قند با انسولین: {avg_with_insulin:.0f} mg/dL\n"532                        result += f"• متوسط قند بدون انسولین: {avg_without_insulin:.0f} mg/dL\n"533                        result += f"• متوسط دوز انسولین: {avg_insulin_dose:.1f} واحد\n"534                        result += f"• هر واحد انسولین تقریباً {effect_per_unit:.0f} واحد قند را کم می‌کند 💉\n"535                        536                        if effect_per_unit > 0:537                            result += "انسولین شما خوب کار می‌کند! ✅"538                        else:539                            result += "ممکن است نیاز به تنظیم دوز داشته باشید. با پزشک مشورت کنید. ⚠️"540                        541                        return result542                    else:543                        return "داده کافی برای تحلیل تاثیر انسولین موجود نیست."544            545            elif query == 'استرس چقدر قندم را بالا می‌برد؟':546                glucose_col = None547                stress_col = None548                549                for col in self.columns:550                    if 'قند' in col:551                        glucose_col = col552                    if 'استرس' in col:553                        stress_col = col554                555                if glucose_col and stress_col:556                    stress_levels = ['کم', 'متوسط', 'زیاد']557                    result = "تاثیر سطح استرس روی قند خون:\n"558                    559                    stress_analysis = {}560                    for stress_level in stress_levels:561                        stress_data = self.data[self.data[stress_col] == stress_level]562                        if not stress_data.empty:563                            avg_glucose = stress_data[glucose_col].mean()564                            count = len(stress_data)565                            stress_analysis[stress_level] = {'avg': avg_glucose, 'count': count}566                    567                    if stress_analysis:568                        for stress_level in stress_levels:569                            if stress_level in stress_analysis:570                                data = stress_analysis[stress_level]571                                emoji = "🟢" if data['avg'] < 140 else "🟡" if data['avg'] < 160 else "🔴"572                                result += f"{emoji} استرس {stress_level}: {data['avg']:.0f} mg/dL ({data['count']} بار)\n"573                        574                        # محاسبه تفاوت بین کم‌ترین و بیشترین استرس575                        if 'کم' in stress_analysis and 'زیاد' in stress_analysis:576                            difference = stress_analysis['زیاد']['avg'] - stress_analysis['کم']['avg']577                            result += f"\n💡 استرس زیاد {difference:.0f} واحد قند را نسبت به استرس کم بالا می‌برد.\n"578                            579                            if difference > 30:580                                result += "استرس تاثیر زیادی روی قند شما دارد. تکنیک‌های آرامش‌بخشی را امتحان کنید. 🧘‍♀️"581                            elif difference > 15:582                                result += "استرس تاثیر متوسطی روی قند شما دارد."583                            else:584                                result += "خوشبختانه استرس تاثیر کمی روی قند شما دارد. 👍"585                        586                        return result587                    else:588                        return "داده کافی برای تحلیل تاثیر استرس موجود نیست."589            590            elif query == 'آب‌وهوا چطور روی قندم تاثیر می‌گذارد؟':591                glucose_col = None592                weather_col = None593                594                for col in self.columns:595                    if 'قند' in col:596                        glucose_col = col597                    if 'آب_وهوا' in col or 'آب‌وهوا' in col:598                        weather_col = col599                600                if glucose_col and weather_col:601                    weather_analysis = self.data.groupby(weather_col)[glucose_col].agg(['mean', 'count']).reset_index()602                    result = "تاثیر آب‌وهوا روی قند خون:\n"603                    604                    for _, row in weather_analysis.iterrows():605                        weather = row[weather_col]606                        avg_glucose = row['mean']607                        count = row['count']608                        emoji = "🟢" if avg_glucose < 140 else "🟡" if avg_glucose < 160 else "🔴"609                        result += f"{emoji} {weather}: {avg_glucose:.0f} mg/dL ({count} بار)\n"610                    611                    # یافتن بهترین و بدترین آب‌وهوا612                    best_weather = weather_analysis.loc[weather_analysis['mean'].idxmin(), weather_col]613                    worst_weather = weather_analysis.loc[weather_analysis['mean'].idxmax(), weather_col]614                    615                    result += f"\n🌟 بهترین آب‌وهوا برای قند شما: {best_weather}\n"616                    result += f"⚠️ بدترین آب‌وهوا برای قند شما: {worst_weather}"617                    618                    return result619                else:620                    return "داده آب‌وهوا در فایل شما موجود نیست."621            622            elif query == 'کیفیت خوابم چه تاثیری روی قند دارد؟':623                glucose_col = None624                sleep_col = None625                626                for col in self.columns:627                    if 'قند' in col:628                        glucose_col = col629                    if 'کیفیت_خواب' in col:630                        sleep_col = col631                632                if glucose_col and sleep_col:633                    sleep_analysis = self.data.groupby(sleep_col)[glucose_col].agg(['mean', 'count']).reset_index()634                    result = "تاثیر کیفیت خواب روی قند خون:\n"635                    636                    sleep_order = {'عالی': 1, 'خوب': 2, 'متوسط': 3, 'بد': 4, 'خیلی_بد': 5}637                    sleep_analysis['order'] = sleep_analysis[sleep_col].map(sleep_order)638                    sleep_analysis = sleep_analysis.sort_values('order')639                    640                    for _, row in sleep_analysis.iterrows():641                        sleep_quality = row[sleep_col]642                        avg_glucose = row['mean']643                        count = row['count']644                        emoji = "🟢" if avg_glucose < 140 else "🟡" if avg_glucose < 160 else "🔴"645                        result += f"{emoji} خواب {sleep_quality}: {avg_glucose:.0f} mg/dL ({count} بار)\n"646                    647                    # محاسبه تفاوت بین بهترین و بدترین خواب648                    best_sleep = sleep_analysis.iloc[0]649                    worst_sleep = sleep_analysis.iloc[-1]650                    difference = worst_sleep['mean'] - best_sleep['mean']651                    652                    result += f"\n💤 خواب بد {difference:.0f} واحد قند را بالاتر از خواب خوب می‌برد.\n"653                    654                    if difference > 20:655                        result += "کیفیت خواب تاثیر زیادی روی قند شما دارد. بهبود خواب اولویت باشد! 😴"656                    else:657                        result += "کیفیت خواب تاثیر قابل قبولی روی قند شما دارد. 👍"658                    659                    return result660                else:661                    return "داده کیفیت خواب در فایل شما موجود نیست."662            663            elif query == 'چقدر ورزش کرده‌ام؟':664                steps_col = None665                activity_col = None666                667                for col in self.columns:668                    if 'قدم' in col:669                        steps_col = col670                    if 'فعالیت' in col:671                        activity_col = col672                673                if steps_col:674                    total_steps = self.data[steps_col].sum()675                    avg_daily_steps = total_steps / len(self.data.groupby('تاریخ'))676                    exercise_days = len(self.data[self.data[activity_col] == 'ورزش']) if activity_col else 0677                    678                    result = f"آمار فعالیت فیزیکی شما:\n"679                    result += f"👟 کل قدم‌ها: {total_steps:,} قدم\n"680                    result += f"📊 متوسط روزانه: {avg_daily_steps:.0f} قدم\n"681                    result += f"💪 روزهای ورزش: {exercise_days} روز\n\n"682                    683                    if avg_daily_steps >= 10000:684                        result += "عالی! شما به هدف 10,000 قدم روزانه رسیده‌اید! 🎯"685                    elif avg_daily_steps >= 7000:686                        result += "خوب است! کمی بیشتر قدم بزنید تا به 10,000 برسید. 📈"687                    else:688                        result += "نیاز به فعالیت بیشتر دارید. سعی کنید بیشتر قدم بزنید. 🚶‍♂️"689                    690                    return result691                else:692                    return "داده قدم‌ها در فایل شما موجود نیست."693            694            elif query == 'فشار خونم چطوره؟':695                bp_col = None696                697                for col in self.columns:698                    if 'فشار' in col:699                        bp_col = col700                        break701                702                if bp_col:703                    bp_values = self.data[bp_col].dropna()704                    if not bp_values.empty:705                        # تحلیل فشار خون706                        high_count = 0707                        normal_count = 0708                        low_count = 0709                        710                        for bp in bp_values:711                            try:712                                systolic = int(bp.split('/')[0])713                                if systolic >= 140:714                                    high_count += 1715                                elif systolic >= 120:716                                    normal_count += 1717                                else:718                                    low_count += 1719                            except:720                                continue721                        722                        total = high_count + normal_count + low_count723                        724                        result = f"آمار فشار خون شما:\n"725                        result += f"🔴 بالا (≥140): {high_count} بار ({high_count/total*100:.0f}%)\n"726                        result += f"🟡 نرمال (120-139): {normal_count} بار ({normal_count/total*100:.0f}%)\n"727                        result += f"🟢 ایده‌آل (<120): {low_count} بار ({low_count/total*100:.0f}%)\n\n"728                        729                        if high_count/total > 0.3:730                            result += "⚠️ فشار خون شما اغلب بالا است. با پزشک مشورت کنید."731                        elif normal_count/total > 0.7:732                            result += "✅ فشار خون شما در حد قابل قبول است."733                        else:734                            result += "👍 فشار خون شما در حد ایده‌آل است."735                        736                        return result737                    else:738                        return "داده فشار خون کافی نیست."739                else:740                    return "داده فشار خون در فایل شما موجود نیست."741            742            elif query == 'وزنم چطور تغییر کرده؟':743                weight_col = None744                745                for col in self.columns:746                    if 'وزن' in col:747                        weight_col = col748                        break749                750                if weight_col:751                    weights = self.data[weight_col].dropna()752                    if len(weights) > 1:753                        first_weight = weights.iloc[0]754                        last_weight = weights.iloc[-1]755                        weight_change = last_weight - first_weight756                        avg_weight = weights.mean()757                        758                        result = f"تغییرات وزن شما:\n"759                        result += f"⚖️ وزن اولیه: {first_weight} کیلو\n"760                        result += f"⚖️ وزن فعلی: {last_weight} کیلو\n"761                        result += f"📊 متوسط وزن: {avg_weight:.1f} کیلو\n"762                        result += f"📈 تغییر کلی: {weight_change:+.1f} کیلو\n\n"763                        764                        if abs(weight_change) < 1:765                            result += "👍 وزن شما ثابت مانده است."766                        elif weight_change > 0:767                            result += f"📈 {weight_change:.1f} کیلو افزایش وزن داشته‌اید."768                        else:769                            result += f"📉 {abs(weight_change):.1f} کیلو کاهش وزن داشته‌اید."770                        771                        return result772                    else:773                        return "داده وزن کافی برای تحلیل تغییرات نیست."774                else:775                    return "داده وزن در فایل شما موجود نیست."776            777            else:778                return "متوجه سوال شما نشدم. لطفاً یکی از سوالات آماده را انتخاب کنید."779                780        except Exception as e:781            return f"❌ مشکلی پیش آمده: {str(e)}"782 783    def get_data_summary(self):784        """خلاصه داده‌ها"""785        if self.data is None:786            return "هیچ داده‌ای بارگذاری نشده است."787        788        # محاسبه دوره زمانی789        unique_dates = self.data['تاریخ'].nunique() if 'تاریخ' in self.columns else 1790        791        summary = f"📊 تعداد رکوردها: {len(self.data)}\n"792        summary += f"📅 دوره زمانی: {unique_dates} روز\n"793        summary += f"🏷️ تعداد ستون‌ها: {len(self.columns)}\n"794        795        # آمار قند خون796        stats = self.calculate_diabetic_stats()797        if stats:798            summary += f"\n🩺 آمار قند خون:\n"799            summary += f"• متوسط قند: {stats['mean']:.0f} mg/dL\n"800            summary += f"• زمان در محدوده: {stats['time_in_range']:.1f}%\n"801            summary += f"• تعداد هیپو: {stats['hypo_count']}\n"802            summary += f"• تعداد هایپر: {stats['hyper_count']}\n"803            summary += f"• تنوع گلایسمی: {stats['variability']:.1f}%\n"804        805        # آمار فعالیت فیزیکی806        if 'قدم_ها' in self.columns:807            total_steps = self.data['قدم_ها'].sum()808            avg_daily_steps = total_steps / unique_dates809            summary += f"\n👟 فعالیت فیزیکی:\n"810            summary += f"• کل قدم‌ها: {total_steps:,}\n"811            summary += f"• متوسط روزانه: {avg_daily_steps:.0f} قدم\n"812        813        # آمار انسولین814        if 'انسولین' in self.columns:815            insulin_doses = self.data[self.data['انسولین'] > 0]['انسولین']816            if not insulin_doses.empty:817                summary += f"\n💉 انسولین:\n"818                summary += f"• تعداد دوزها: {len(insulin_doses)}\n"819                summary += f"• متوسط دوز: {insulin_doses.mean():.1f} واحد\n"820        821        # آمار وزن822        if 'وزن' in self.columns:823            weights = self.data['وزن'].dropna()824            if len(weights) > 1:825                weight_change = weights.iloc[-1] - weights.iloc[0]826                summary += f"\n⚖️ وزن:\n"827                summary += f"• وزن فعلی: {weights.iloc[-1]} کیلو\n"828                summary += f"• تغییر: {weight_change:+.1f} کیلو\n"829        830        return summary831 832# ساخت اپلیکیشن Gradio833def create_app():834    analyzer = CGMAnalyzer()835    836    # CSS برای RTL و استایل بهتر837    custom_css = """838    .rtl { direction: rtl; text-align: right; }839    .main-title { text-align: center; color: #d63384; font-size: 28px; font-weight: bold; margin: 20px 0; }840    .subtitle { text-align: center; color: #6c757d; margin-bottom: 30px; font-size: 16px; }841    .section-title { color: #6f42c1; font-weight: bold; margin: 20px 0 10px 0; }842    .gradio-container { font-family: 'Segoe UI', Tahoma, Arial, sans-serif; }843    844    /* بهبود نمایش جدول */845    .dataframe { 846        font-size: 12px !important; 847        width: 100% !important;848        overflow-x: auto !important;849        max-height: 500px !important;850        overflow-y: auto !important;851    }852    .dataframe table { 853        table-layout: fixed !important; 854        width: 100% !important;855        border-collapse: collapse !important;856    }857    .dataframe th { 858        background-color: #f8f9fa !important; 859        font-weight: bold !important;860        padding: 8px 4px !important;861        text-align: center !important;862        border: 1px solid #dee2e6 !important;863        position: sticky !important;864        top: 0 !important;865        z-index: 10 !important;866    }867    .dataframe td { 868        padding: 6px 4px !important; 869        text-align: center !important;870        border: 1px solid #dee2e6 !important;871        word-wrap: break-word !important;872        overflow: hidden !important;873    }874    875    /* ستون‌های خاص با عرض ثابت */876    .dataframe th:nth-child(1), .dataframe td:nth-child(1) { width: 100px !important; } /* تاریخ */877    .dataframe th:nth-child(2), .dataframe td:nth-child(2) { width: 70px !important; }  /* زمان */878    .dataframe th:nth-child(3), .dataframe td:nth-child(3) { width: 80px !important; }  /* قند_خون */879    .dataframe th:nth-child(4), .dataframe td:nth-child(4) { width: 100px !important; } /* روند */880    .dataframe th:nth-child(5), .dataframe td:nth-child(5) { width: 80px !important; }  /* وضعیت */881    .dataframe th:nth-child(6), .dataframe td:nth-child(6) { width: 90px !important; }  /* فعالیت */882    .dataframe th:nth-child(7), .dataframe td:nth-child(7) { width: 100px !important; } /* وعده_غذایی */883    .dataframe th:nth-child(8), .dataframe td:nth-child(8) { width: 70px !important; }  /* انسولین */884    .dataframe th:nth-child(9), .dataframe td:nth-child(9) { width: 80px !important; }  /* استرس */885    .dataframe th:nth-child(10), .dataframe td:nth-child(10) { width: 60px !important; } /* خواب */886    .dataframe th:nth-child(11), .dataframe td:nth-child(11) { width: 90px !important; } /* کیفیت_خواب */887    .dataframe th:nth-child(12), .dataframe td:nth-child(12) { width: 80px !important; } /* آب_وهوا */888    .dataframe th:nth-child(13), .dataframe td:nth-child(13) { width: 90px !important; } /* فشار_خون */889    .dataframe th:nth-child(14), .dataframe td:nth-child(14) { width: 90px !important; } /* دارو */890    .dataframe th:nth-child(15), .dataframe td:nth-child(15) { width: 60px !important; } /* وزن */891    .dataframe th:nth-child(16), .dataframe td:nth-child(16) { width: 80px !important; } /* ضربان_قلب */892    .dataframe th:nth-child(17), .dataframe td:nth-child(17) { width: 90px !important; } /* مایعات_مصرفی */893    .dataframe th:nth-child(18), .dataframe td:nth-child(18) { width: 80px !important; } /* قدم_ها */894    .dataframe th:nth-child(19), .dataframe td:nth-child(19) { width: 90px !important; } /* کالری_مصرفی */895    .dataframe th:nth-child(20), .dataframe td:nth-child(20) { width: 120px !important; } /* یادداشت */896    897    /* اسکرول بار بهتر */898    .dataframe::-webkit-scrollbar {899        width: 8px;900        height: 8px;901    }902    .dataframe::-webkit-scrollbar-track {903        background: #f1f1f1;904    }905    .dataframe::-webkit-scrollbar-thumb {906        background: #888;907        border-radius: 4px;908    }909    .dataframe::-webkit-scrollbar-thumb:hover {910        background: #555;911    }912    """913    914    with gr.Blocks(title="تحلیل‌گر داده‌های CGM", theme=gr.themes.Soft(), css=custom_css) as app:915        916        gr.HTML('<div class="main-title">🩺 تحلیل‌گر داده‌های CGM</div>')917        gr.HTML('<div class="subtitle">مانیتورینگ مداوم قند خون • ابزار تحلیل هوشمند برای بیماران دیابتی</div>')918        919        with gr.Tab("📂 بارگذاری داده‌ها"):920            with gr.Row():921                with gr.Column():922                    file_input = gr.File(923                        label="انتخاب فایل CSV", 924                        file_types=[".csv"],925                        elem_classes=["rtl"]926                    )927                    sample_btn = gr.Button("🔄 بارگذاری داده نمونه", variant="secondary")928                    upload_status = gr.Textbox(929                        label="وضعیت بارگذاری", 930                        interactive=False,931                        elem_classes=["rtl"]932                    )933                934                with gr.Column():935                    data_summary = gr.Textbox(936                        label="خلاصه داده‌ها",937                        lines=8,938                        interactive=False,939                        elem_classes=["rtl"]940                    )941            942            # دکمه‌های کنترل نمایش داده‌ها943            with gr.Row():944                more_data_btn = gr.Button("📊 نمایش 50 رکورد اول", variant="secondary")945                all_data_btn = gr.Button("📋 نمایش همه داده‌ها", variant="secondary")946                gr.HTML('<div style="color: #6c757d; font-size: 14px; padding: 10px;">💡 نکته: برای مشاهده داده‌های بیشتر از دکمه‌های بالا استفاده کنید</div>')947            948            data_preview = gr.Dataframe(949                label="نمایش داده‌ها",950                wrap=True,951                elem_classes=["rtl"]952            )953        954        with gr.Tab("🤔 سوالات آماده"):955            gr.HTML('<div class="section-title">سوالات رایج از قند خون - روی هر دکمه کلیک کنید:</div>')956            957            with gr.Row():958                with gr.Column():959                    query_buttons = []960                    for i, query in enumerate(analyzer.diabetic_queries):961                        btn = gr.Button(query, elem_classes=["rtl"])962                        query_buttons.append(btn)963            964            query_result = gr.Textbox(965                label="پاسخ سوال",966                lines=5,967                interactive=False,968                elem_classes=["rtl"]969            )970        971        with gr.Tab("💬 سوال دلخواه"):972            with gr.Row():973                custom_query = gr.Textbox(974                    label="سوال خود را بنویسید",975                    placeholder="مثال: قند من معمولاً چقدر است؟",976                    elem_classes=["rtl"]977                )978                ask_btn = gr.Button("🔍 پرسش", variant="primary")979            980            custom_result = gr.Textbox(981                label="پاسخ",982                lines=5,983                interactive=False,984                elem_classes=["rtl"]985            )986        987        with gr.Tab("📈 نمودارها"):988            gr.HTML('<div class="section-title">نمودارهای تحلیل داده‌ها</div>')989            990            with gr.Row():991                trend_btn = gr.Button("📊 روند قند خون")992                pattern_btn = gr.Button("🕐 الگوی روزانه") 993                meal_btn = gr.Button("🍽️ تاثیر وعده‌ها")994            995            with gr.Row():996                weight_btn = gr.Button("⚖️ روند وزن")997                activity_btn = gr.Button("👟 فعالیت فیزیکی")998                stress_btn = gr.Button("😰 استرس و قند")999            1000            chart_output = gr.Plot(label="نمودار")1001        1002        with gr.Tab("💡 راهنما"):1003            gr.HTML("""1004            <div class="rtl" style="padding: 20px; font-family: Tahoma;">1005                <h3>💡 راهنمای استفاده:</h3>1006                <ul style="line-height: 1.8;">1007                    <li><strong>بارگذاری داده‌ها:</strong> فایل CSV حاوی ستون‌های زیر:1008                        <br>• اجباری: تاریخ، زمان، قند_خون، وضعیت، فعالیت، وعده_غذایی، انسولین، استرس1009                        <br>• اختیاری: کیفیت_خواب، آب_وهوا، فشار_خون، دارو، وزن، ضربان_قلب، مایعات_مصرفی، قدم_ها، کالری_مصرفی، یادداشت1010                    </li>1011                    <li><strong>سوالات آماده:</strong> روی هر سوال کلیک کنید تا پاسخ را ببینید</li>1012                    <li><strong>سوال دلخواه:</strong> سوال خود را با کلمات ساده بنویسید</li>1013                    <li><strong>نمودارها:</strong> تحلیل بصری داده‌های شما شامل 6 نوع نمودار مختلف</li>1014                </ul>1015                1016                <h3>📊 محدوده‌های قند خون:</h3>1017                <ul style="line-height: 1.8;">1018                    <li><span style="color: red; font-weight: bold;">🔴 خطرناک:</span> کمتر از 70 (فوری به پزشک مراجعه کنید)</li>1019                    <li><span style="color: green; font-weight: bold;">🟢 خوب:</span> 70 تا 140 (عالی است)</li>1020                    <li><span style="color: orange; font-weight: bold;">🟡 بالا:</span> بیشتر از 140 (بهتر است کنترل کنید)</li>1021                    <li><span style="color: red; font-weight: bold;">🔴 خیلی بالا:</span> بیشتر از 180 (حتماً با پزشک صحبت کنید)</li>1022                </ul>1023 1024                <h3>🆕 ویژگی‌های جدید:</h3>1025                <ul style="line-height: 1.8;">1026                    <li><strong>تحلیل کیفیت خواب:</strong> بررسی تاثیر خواب روی قند خون</li>1027                    <li><strong>تاثیر آب‌وهوا:</strong> نحوه تاثیر شرایط جوی بر کنترل قند</li>1028                    <li><strong>ردیابی وزن:</strong> پیگیری تغییرات وزن در طول زمان</li>1029                    <li><strong>فعالیت فیزیکی:</strong> تحلیل میزان قدم‌زدن و ورزش</li>1030                    <li><strong>مانیتورینگ فشار خون:</strong> کنترل همزمان فشار خون</li>1031                    <li><strong>مدیریت دارو:</strong> پیگیری مصرف داروها</li>1032                </ul>1033                1034                <h3>🏥 نکات مهم:</h3>1035                <ul style="line-height: 1.8;">1036                    <li><strong>هدف:</strong> بیش از 70% وقت قند در محدوده نرمال باشد</li>1037                    <li><strong>هدف روزانه:</strong> حداقل 10,000 قدم در روز</li>1038                    <li>اگر قند زیر 70 رفت، فوری شکر یا آبمیوه بخورید</li>1039                    <li>اگر قند بالای 300 رفت، فوری به بیمارستان بروید</li>1040                    <li><strong>کیفیت خواب:</strong> 7-8 ساعت خواب باکیفیت ضروری است</li>1041                    <li><strong>مدیریت استرس:</strong> تکنیک‌های آرامش‌بخشی یاد بگیرید</li>1042                    <li><strong style="color: red;">این برنامه جایگزین مشاوره پزشک نیست</strong></li>1043                </ul>1044 1045                <h3>📋 نمونه فرمت CSV:</h3>1046                <pre style="background: #f8f9fa; padding: 10px; border-radius: 5px; font-size: 12px;">1047تاریخ,زمان,قند_خون,روند,وضعیت,فعالیت,وعده_غذایی,انسولین,استرس,خواب,کیفیت_خواب,آب_وهوا,فشار_خون,دارو,وزن,ضربان_قلب,مایعات_مصرفی,قدم_ها,کالری_مصرفی,یادداشت10482024-01-15,07:30,125,افزایش_تند,نرمال,صبحانه,صبحانه,5,کم,خیر,خوب,آفتابی,120/80,متفورمین,75.2,72,250,320,280,1049                </pre>1050                1051                <h3>🔒 حریم خصوصی:</h3>1052                <p>داده‌های شما محلی پردازش می‌شوند و ذخیره نمی‌شوند.</p>1053            </div>1054            """)1055        1056        # Event handlers1057        def upload_and_preview(file):1058            data, status = analyzer.upload_file(file)1059            summary = analyzer.get_data_summary()1060            return data, status, summary1061        1062        def load_sample_and_preview():1063            data, status = analyzer.load_sample_data()1064            summary = analyzer.get_data_summary()1065            return data, status, summary1066        1067        def show_more_data():1068            """نمایش داده‌های بیشتر"""1069            if analyzer.data is not None:1070                # نمایش 50 رکورد اول1071                return analyzer.data.head(50)1072            return None1073        1074        def show_all_data():1075            """نمایش همه داده‌ها"""1076            if analyzer.data is not None:1077                return analyzer.data1078            return None1079        1080        # اتصال رویدادها1081        file_input.upload(upload_and_preview, inputs=file_input, outputs=[data_preview, upload_status, data_summary])1082        sample_btn.click(load_sample_and_preview, outputs=[data_preview, upload_status, data_summary])1083        1084        # دکمه‌های نمایش داده‌های بیشتر1085        more_data_btn.click(show_more_data, outputs=data_preview)1086        all_data_btn.click(show_all_data, outputs=data_preview)1087        1088        # اتصال دکمه‌های سوالات آماده1089        for i, btn in enumerate(query_buttons):1090            btn.click(1091                lambda q=analyzer.diabetic_queries[i]: analyzer.execute_query(q),1092                outputs=query_result1093            )1094        1095        # سوال دلخواه1096        ask_btn.click(analyzer.execute_query, inputs=custom_query, outputs=custom_result)1097        custom_query.submit(analyzer.execute_query, inputs=custom_query, outputs=custom_result)1098        1099        # نمودارها1100        trend_btn.click(analyzer.create_glucose_trend_chart, outputs=chart_output)1101        pattern_btn.click(analyzer.create_daily_pattern_chart, outputs=chart_output)1102        meal_btn.click(analyzer.create_meal_impact_chart, outputs=chart_output)1103        weight_btn.click(analyzer.create_weight_trend_chart, outputs=chart_output)1104        activity_btn.click(analyzer.create_activity_chart, outputs=chart_output)1105        stress_btn.click(analyzer.create_stress_correlation_chart, outputs=chart_output)1106    1107    return app1108 1109# برای Hugging Face Spaces1110if __name__ == "__main__":1111    app = create_app()1112    app.launch()