{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":50160,"databundleVersionId":7921029,"sourceType":"competition"},{"sourceId":8215104,"sourceType":"datasetVersion","datasetId":4589852},{"sourceId":172824708,"sourceType":"kernelVersion"}],"dockerImageVersionId":30664,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import polars as pl\nimport numpy as np\nimport pandas as pd\nfrom glob import glob\nimport lightgbm as lgb\nfrom sklearn.model_selection import train_test_split, StratifiedKFold\nfrom sklearn.preprocessing import OrdinalEncoder\nfrom sklearn.metrics import roc_auc_score \nimport pickle\nimport matplotlib.pyplot as plt\nimport os \nfrom gc import collect\nfrom os import path, walk, getpid\nfrom psutil import Process\nimport ctypes;\nlibc = ctypes.CDLL(\"libc.so.6\");","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-04-24T11:08:59.948879Z","iopub.execute_input":"2024-04-24T11:08:59.949360Z","iopub.status.idle":"2024-04-24T11:08:59.958761Z","shell.execute_reply.started":"2024-04-24T11:08:59.949326Z","shell.execute_reply":"2024-04-24T11:08:59.956955Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Config:\n    experiment_number = 1\n    version = 5\n    num_folds = 5\n    mode = 'test'\n    data_path = \"/kaggle/input/home-credit-credit-risk-model-stability/\"\n    train_base_path = \"/kaggle/input/folded-base-train/train_base_week_folds.csv\"\n    train_path         = \"/kaggle/input/home-credit-credit-risk-model-stability/csv_files/train\";\n    test_path          = \"/kaggle/input/home-credit-credit-risk-model-stability/csv_files/test\";\n    model_path = '/kaggle/input/hc-models'\n    covid_date = \"2020-02-29\"","metadata":{"execution":{"iopub.status.busy":"2024-04-24T11:09:01.060910Z","iopub.execute_input":"2024-04-24T11:09:01.061351Z","iopub.status.idle":"2024-04-24T11:09:01.068810Z","shell.execute_reply.started":"2024-04-24T11:09:01.061318Z","shell.execute_reply":"2024-04-24T11:09:01.067362Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Utilities:\n    @staticmethod\n    def set_table_dtypes(df: pl.DataFrame) -> pl.DataFrame:\n        for col in df.columns:\n            if col in [\"case_id\", \"WEEK_NUM\", \"num_group1\", \"num_group2\"]:\n                df = df.with_columns(pl.col(col).cast(pl.Int64));\n            elif len(col) == 0:\n                df = df.drop(col)\n            elif col in [\"date_decision\"] or col[-1] in (\"D\",):\n                df = df.with_columns(pl.col(col).cast(pl.Date));\n            elif col[-1] in (\"P\", \"A\"):\n                df = df.with_columns(pl.col(col).cast(pl.Float64));\n            elif col[-1] in (\"M\",):\n                df = df.with_columns(pl.col(col).cast(pl.String));\n\n        return df;\n\n    @staticmethod\n    def handle_dates(df):\n        for col in df.columns:\n            if col[-1] in (\"D\",):\n                df = df.with_columns(pl.col(col) - pl.col(\"date_decision\"))\n                df = df.with_columns(pl.col(col).dt.total_days())\n                df = df.with_columns(pl.col(col).cast(pl.Float32))\n                \n        df = df.drop(\"date_decision\", \"MONTH\")\n\n        return df\n    @staticmethod\n    def filter_cols(df):\n        for col in df.columns:\n            if col not in [\"target\", \"case_id\", \"WEEK_NUM\"]:\n                isnull = df[col].is_null().mean()\n\n                if isnull > Config.null_cut_off:\n                    df = df.drop(col)\n\n        for col in df.columns:\n            if (col not in [\"target\", \"case_id\", \"WEEK_NUM\"]) & (df[col].dty|pe == pl.String):\n                freq = df[col].n_unique()\n\n                if (freq == 1) | (freq > 200):\n                    df = df.drop(col)\n        return df \n    @staticmethod\n    def CleanMemory():\n        \"This method cleans the memory off unused objects and displays the cleaned state RAM usage\";\n\n        collect();\n        libc.malloc_trim(0);\n        pid        = getpid();\n        py         = Process(pid);\n        memory_use = py.memory_info()[0] / 2. ** 30;\n        return f\"RAM usage = {memory_use :.4} GB\";","metadata":{"execution":{"iopub.status.busy":"2024-04-24T11:09:02.018177Z","iopub.execute_input":"2024-04-24T11:09:02.018645Z","iopub.status.idle":"2024-04-24T11:09:02.037592Z","shell.execute_reply.started":"2024-04-24T11:09:02.018610Z","shell.execute_reply":"2024-04-24T11:09:02.036575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Aggregator:\n    @staticmethod\n    def num_expr(df):\n        cols = [col for col in df.columns if col[-1] in (\"P\", \"A\")]\n\n        expr_max = [pl.max(col).alias(f\"max_{col}\") for col in cols]\n\n        return expr_max\n\n    @staticmethod\n    def date_expr(df):\n        cols = [col for col in df.columns if col[-1] in (\"D\",)]\n\n        expr_max = [pl.max(col).alias(f\"max_{col}\") for col in cols]\n\n        return expr_max\n\n    @staticmethod\n    def str_expr(df):\n        cols = [col for col in df.columns if col[-1] in (\"M\",)]\n        \n        expr_max = [pl.max(col).alias(f\"max_{col}\") for col in cols]\n\n        return expr_max\n\n    @staticmethod\n    def other_expr(df):\n        cols = [col for col in df.columns if col[-1] in (\"T\", \"L\")]\n        \n        expr_max = [pl.max(col).alias(f\"max_{col}\") for col in cols]\n\n        return expr_max\n    \n    @staticmethod\n    def count_expr(df):\n        cols = [col for col in df.columns if \"num_group\" in col]\n\n        expr_max = [pl.max(col).alias(f\"max_{col}\") for col in cols]\n\n        return expr_max\n\n    @staticmethod\n    def get_exprs(df):\n        exprs = Aggregator.num_expr(df) + \\\n                Aggregator.date_expr(df) + \\\n                Aggregator.str_expr(df) + \\\n                Aggregator.other_expr(df) + \\\n                Aggregator.count_expr(df)\n\n        return exprs","metadata":{"execution":{"iopub.status.busy":"2024-04-24T11:09:02.861045Z","iopub.execute_input":"2024-04-24T11:09:02.861479Z","iopub.status.idle":"2024-04-24T11:09:02.875877Z","shell.execute_reply.started":"2024-04-24T11:09:02.861444Z","shell.execute_reply":"2024-04-24T11:09:02.874369Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def reduce_mem_usage(df):\n    \"\"\" iterate through all the columns of a dataframe and modify the data type\n        to reduce memory usage.        \n    \"\"\"\n    start_mem = df.memory_usage().sum() / 1024**2\n    print('Memory usage of dataframe is {:.2f} MB'.format(start_mem))\n    \n    for col in df.columns:\n        col_type = df[col].dtype\n        if str(col_type)==\"category\":\n            continue\n        \n        if col_type != object:\n            c_min = df[col].min()\n            c_max = df[col].max()\n            if str(col_type)[:3] == 'int':\n                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:\n                    df[col] = df[col].astype(np.int8)\n                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:\n                    df[col] = df[col].astype(np.int16)\n                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:\n                    df[col] = df[col].astype(np.int32)\n                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:\n                    df[col] = df[col].astype(np.int64)  \n            else:\n                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:\n                    df[col] = df[col].astype(np.float16)\n                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:\n                    df[col] = df[col].astype(np.float32)\n                else:\n                    df[col] = df[col].astype(np.float64)\n        else:\n            continue\n    end_mem = df.memory_usage().sum() / 1024**2\n    print('Memory usage after optimization is: {:.2f} MB'.format(end_mem))\n    print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))\n    \n    return df","metadata":{"execution":{"iopub.status.busy":"2024-04-24T11:09:03.626014Z","iopub.execute_input":"2024-04-24T11:09:03.626467Z","iopub.status.idle":"2024-04-24T11:09:03.643237Z","shell.execute_reply.started":"2024-04-24T11:09:03.626433Z","shell.execute_reply":"2024-04-24T11:09:03.641931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def read_file(path, depth=None):\n    df = pl.read_csv(path).pipe(Utilities.set_table_dtypes)\n    if depth in [1, 2]:\n        df = df.group_by(\"case_id\").agg(Aggregator.get_exprs(df))\n    return df \n\ndef read_files(regex_path, depth=None):\n    chunks = []\n    for path in glob(str(regex_path)):\n        chunks.append(read_file(path, depth))\n    df = pl.concat(chunks, how='vertical_relaxed')\n    df = df.unique(subset=[\"case_id\"])\n    return df","metadata":{"execution":{"iopub.status.busy":"2024-04-24T11:09:04.698117Z","iopub.execute_input":"2024-04-24T11:09:04.698834Z","iopub.status.idle":"2024-04-24T11:09:04.707938Z","shell.execute_reply.started":"2024-04-24T11:09:04.698774Z","shell.execute_reply":"2024-04-24T11:09:04.706467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DataTransformer:\n    def __init__(self, selected_columns=[], selected_cat_columns=[]):\n        self.mode = Config.mode.lower()\n        self.path = Config.train_path if self.mode == 'train' else Config.test_path\n        self.selected_columns = selected_columns \n        self.selected_cat_columns = selected_cat_columns\n\n    \n    def transform_base(self, base):\n        base = base.with_columns(pl.col('date_decision').cast(pl.Date))\n        base = base.with_columns((pl.col('date_decision') > pd.to_datetime(Config.covid_date)).alias('covid'))   \n        return base \n\n    def transform_static(self, static):\n        with open('/kaggle/input/hc-static-preprocessing/static_cols_to_drop_V3.pkl', 'rb') as f:\n            cols_to_drop = pickle.load(f)\n        static = static.drop(cols_to_drop)\n        cols_to_cast = [c for c in static.columns if (c[-1] == 'L') and (c[:3] == 'num')]\n        static = static.with_columns(pl.col(cols_to_cast).cast(pl.Float64))\n        return static\n    \n    def transform_cb(self, cb):\n#         cb = cb.join(base[['case_id', 'date_decision']], on='case_id')\n#         cb = cb.with_columns((pl.col(pl.Date) - pl.col('date_decision')).dt.total_days())\n#         cb = cb.drop('date_decision')\n        return cb\n#     def transform_person_1(self, df, person_1):\n#         person_1_feats_1 = person_1.group_by(\"case_id\").agg(\n#             pl.col(\"mainoccupationinc_384A\").max().alias(\"mainoccupationinc_384A_max\"),\n#             (pl.col(\"incometype_1044T\") == \"SELFEMPLOYED\").max().alias(\"mainoccupationinc_384A_any_selfemployed\")\n#         )\n#         person_1_feats_2 = person_1.select([\"case_id\", \"num_group1\", \"housetype_905L\"]).filter(\n#             pl.col(\"num_group1\") == 0\n#         ).drop(\"num_group1\").rename({\"housetype_905L\": \"person_housetype\"})\n#         df = df.join(person_1_feats_1, on='case_id', how='left')\n#         df = df.join(person_1_feats_2, on='case_id', how='left')\n#         df = df.with_columns(pl.col('mainoccupationinc_384A_any_selfemployed').fill_null(False))\n#         return df\n#     def transform_cb_b_2(self, df, cb_b_2):\n#         cb_b_2_feats = cb_b_2.group_by(\"case_id\").agg(\n#             pl.col(\"pmts_pmtsoverdue_635A\").max().alias(\"pmts_pmtsoverdue_635A_max\"),\n#             (pl.col(\"pmts_dpdvalue_108P\") > 31).max().alias(\"pmts_dpdvalue_108P_over31\")\n#         )\n#         df = df.join(cb_b_2_feats, on='case_id', how='left')\n#         return df\n    \n    def transform_depth_2(self, df):\n        cb_b_2 = read_file(os.path.join(self.path, f\"{self.mode}_credit_bureau_b_2.csv\"), depth=2)\n        df = df.join(cb_b_2, how='left', on='case_id', suffix='_cb_b_2')\n        del cb_b_2\n        return df \n        \n    def transform_depth_1(self, df):\n        app_prev = read_files(os.path.join(self.path, f\"{self.mode}_applprev_1_*.csv\"), depth=1)\n        df = df.join(app_prev, how='left', on='case_id', suffix='_app')\n        del app_prev\n        tax_a = read_file(os.path.join(self.path, f\"{self.mode}_tax_registry_a_1.csv\"), depth=1)\n        df = df.join(tax_a, how='left', on='case_id', suffix='_tax_a')\n        del tax_a\n        tax_b = read_file(os.path.join(self.path, f\"{self.mode}_tax_registry_b_1.csv\"), depth=1)\n        df = df.join(tax_b, how='left', on='case_id', suffix='_tax_b')\n        del tax_b\n        tax_c = read_file(os.path.join(self.path, f\"{self.mode}_tax_registry_c_1.csv\"), depth=1)\n        df = df.join(tax_c, how='left', on='case_id', suffix='_tax_c')\n        del tax_c\n        cb_a = read_files(os.path.join(self.path, f\"{self.mode}_credit_bureau_a_1_*.csv\"), depth=1)\n        df = df.join(cb_a, how='left', on='case_id', suffix='_cb_a')\n        del cb_a\n        cb_b = read_file(os.path.join(self.path, f\"{self.mode}_credit_bureau_b_1.csv\"), depth=1)\n        df = df.join(cb_b, how='left', on='case_id', suffix='_cb_b')\n        del cb_b\n        other = read_file(os.path.join(self.path, f\"{self.mode}_other_1.csv\"), depth=1)\n        df = df.join(other, how='left', on='case_id', suffix='_other')\n        del other\n        person = read_file(os.path.join(self.path, f\"{self.mode}_person_1.csv\"), depth=1)\n        df = df.join(person, how='left', on='case_id', suffix='_person')\n        del person                   \n        deposit = read_file(os.path.join(self.path, f\"{self.mode}_deposit_1.csv\"), depth=1)\n        df = df.join(deposit, how='left', on='case_id', suffix='_deposit')\n        del deposit\n        debit = read_file(os.path.join(self.path, f\"{self.mode}_debitcard_1.csv\"), depth=1)\n        df = df.join(debit, how='left', on='case_id', suffix='_debit')\n        del debit\n        return df \n\n    def transform_depth_0(self, base):\n        # static data transformation \n        static = read_files(os.path.join(self.path, f\"{self.mode}_static_0_*.csv\"))\n        static = self.transform_static(static)\n        # cb - credit bureau\n        cb = read_file(os.path.join(self.path, f\"{self.mode}_static_cb_0.csv\"))\n        cb = self.transform_cb(cb)\n        base = base.join(static, on='case_id', how='left').join(cb, on='case_id', how='left')\n        del static \n        del cb \n        return base\n    \n    def transform(self):\n        if self.mode == 'train':\n            base = read_file(Config.train_base_path)\n        else:\n            base = read_file(os.path.join(self.path, f\"{self.mode}_base.csv\"))\n        base = self.transform_base(base)\n        df = self.transform_depth_0(base)\n        df = self.transform_depth_1(df)\n        df = self.transform_depth_2(df)\n        if self.mode == 'train':\n            df = df.pipe(Utilities.filter_cols).pipe(Utilities.handle_dates)\n        else:\n            df = df.pipe(Utilities.handle_dates)\n        df = df.to_pandas()\n        exp_num = Config.experiment_number\n        version = Config.version \n        if self.mode == 'train':\n            cols_to_ignore = [f'fold_{i}' for i in range(Config.num_folds)]\n            cols_to_ignore.extend(['case_id', 'date_decision', 'MONTH', 'WEEK_NUM', 'target'])\n            selected_columns = [col for col in df.columns if col not in cols_to_ignore]\n            with open(f'./selected_columns_E{exp_num}_V{version}.pkl', 'wb') as f:\n                pickle.dump(selected_columns, f)\n            selected_cat_columns = []\n            for col in df.columns:\n                if col not in cols_to_ignore and df[col].dtype.name in ['object', 'string']:\n                    selected_cat_columns.append(col)\n            ordinal_encoder = OrdinalEncoder(handle_unknown='use_encoded_value', unknown_value=-1)\n            df.loc[:, selected_cat_columns] = ordinal_encoder.fit_transform(df.loc[:, selected_cat_columns])\n            with open(f'./selected_cat_columns_E{exp_num}_V{version}.pkl', 'wb') as f:\n                pickle.dump(selected_cat_columns, f)\n            with open(f'./ordinal_enc_E{exp_num}_V{version}.pkl', 'wb') as f:\n                pickle.dump(ordinal_encoder, f)\n        else:\n            model_path = Config.model_path\n            with open(f'{model_path}/selected_columns_E{exp_num}_V{version}.pkl', 'rb') as f:\n                selected_columns = pickle.load(f)\n            with open(f'{model_path}/selected_cat_columns_E{exp_num}_V{version}.pkl', 'rb') as f:\n                selected_cat_columns = pickle.load(f)\n            with open(f'{model_path}/ordinal_enc_E{exp_num}_V{version}.pkl', 'rb') as f:\n                ordinal_encoder = pickle.load(f)\n            df.loc[:, selected_cat_columns] = ordinal_encoder.transform(df.loc[:, selected_cat_columns].values)\n            for c in selected_columns:\n                if c not in selected_cat_columns and df[c].dtype == object:\n                    df[c] = df[c].astype(float)\n        df[selected_cat_columns] = df[selected_cat_columns].astype(float)\n        self.selected_columns = selected_columns\n        self.selected_cat_columns = selected_cat_columns\n        return df","metadata":{"execution":{"iopub.status.busy":"2024-04-24T11:11:16.133232Z","iopub.execute_input":"2024-04-24T11:11:16.133687Z","iopub.status.idle":"2024-04-24T11:11:16.175672Z","shell.execute_reply.started":"2024-04-24T11:11:16.133653Z","shell.execute_reply":"2024-04-24T11:11:16.174405Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transformer = DataTransformer()","metadata":{"execution":{"iopub.status.busy":"2024-04-24T11:11:17.852304Z","iopub.execute_input":"2024-04-24T11:11:17.852738Z","iopub.status.idle":"2024-04-24T11:11:17.857821Z","shell.execute_reply.started":"2024-04-24T11:11:17.852704Z","shell.execute_reply":"2024-04-24T11:11:17.856710Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = transformer.transform()","metadata":{"execution":{"iopub.status.busy":"2024-04-24T11:11:18.160025Z","iopub.execute_input":"2024-04-24T11:11:18.161321Z","iopub.status.idle":"2024-04-24T11:11:18.491519Z","shell.execute_reply.started":"2024-04-24T11:11:18.161267Z","shell.execute_reply":"2024-04-24T11:11:18.488719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data","metadata":{"execution":{"iopub.status.busy":"2024-04-24T11:11:23.093586Z","iopub.execute_input":"2024-04-24T11:11:23.094020Z","iopub.status.idle":"2024-04-24T11:11:23.141003Z","shell.execute_reply.started":"2024-04-24T11:11:23.093988Z","shell.execute_reply":"2024-04-24T11:11:23.139214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def split_df(df):\n    if Config.mode == 'train':\n        base = df[['case_id', 'WEEK_NUM', 'target']]\n        X = df[transformer.selected_columns]\n        y = df['target']\n        return base, X, y\n    else:\n        base = df[['case_id']]\n        X = df[transformer.selected_columns]\n        return base, X","metadata":{"execution":{"iopub.status.busy":"2024-04-24T11:11:46.723345Z","iopub.execute_input":"2024-04-24T11:11:46.725230Z","iopub.status.idle":"2024-04-24T11:11:46.732859Z","shell.execute_reply.started":"2024-04-24T11:11:46.725168Z","shell.execute_reply":"2024-04-24T11:11:46.731522Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base, X = split_df(data)","metadata":{"execution":{"iopub.status.busy":"2024-04-24T11:11:46.940200Z","iopub.execute_input":"2024-04-24T11:11:46.940654Z","iopub.status.idle":"2024-04-24T11:11:46.952611Z","shell.execute_reply.started":"2024-04-24T11:11:46.940622Z","shell.execute_reply":"2024-04-24T11:11:46.950936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"exp_num = Config.experiment_number\nversion = Config.version\nmodel_path = Config.model_path","metadata":{"execution":{"iopub.status.busy":"2024-04-24T11:11:49.612070Z","iopub.execute_input":"2024-04-24T11:11:49.612497Z","iopub.status.idle":"2024-04-24T11:11:49.618700Z","shell.execute_reply.started":"2024-04-24T11:11:49.612464Z","shell.execute_reply":"2024-04-24T11:11:49.617241Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred = 0\nfor i in range(5):\n    with open(f'{model_path}/lgb_model_E{exp_num}_V{version}_{i+1}.pkl', 'rb') as f:\n        gbm = pickle.load(f)\n    y_pred += gbm.predict(X, num_iteration=gbm.best_iteration)\ny_pred /= 5","metadata":{"execution":{"iopub.status.busy":"2024-04-24T11:11:51.162946Z","iopub.execute_input":"2024-04-24T11:11:51.163326Z","iopub.status.idle":"2024-04-24T11:11:51.372646Z","shell.execute_reply.started":"2024-04-24T11:11:51.163297Z","shell.execute_reply":"2024-04-24T11:11:51.371649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.DataFrame({\n    \"case_id\": base[\"case_id\"].values,\n    \"score\": y_pred\n}).set_index('case_id')\nsubmission.to_csv(\"./submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2024-04-24T11:11:53.267769Z","iopub.execute_input":"2024-04-24T11:11:53.268280Z","iopub.status.idle":"2024-04-24T11:11:53.285487Z","shell.execute_reply.started":"2024-04-24T11:11:53.268243Z","shell.execute_reply":"2024-04-24T11:11:53.284106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission","metadata":{"execution":{"iopub.status.busy":"2024-04-24T11:11:57.656750Z","iopub.execute_input":"2024-04-24T11:11:57.657266Z","iopub.status.idle":"2024-04-24T11:11:57.671495Z","shell.execute_reply.started":"2024-04-24T11:11:57.657224Z","shell.execute_reply":"2024-04-24T11:11:57.669699Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}