{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":4104,"databundleVersionId":46661,"sourceType":"competition"},{"sourceId":14774,"databundleVersionId":875431,"sourceType":"competition"}],"dockerImageVersionId":31236,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nos.listdir(\"/kaggle/input\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T11:40:38.702994Z","iopub.execute_input":"2025-12-17T11:40:38.703259Z","iopub.status.idle":"2025-12-17T11:40:38.711443Z","shell.execute_reply.started":"2025-12-17T11:40:38.703226Z","shell.execute_reply":"2025-12-17T11:40:38.710604Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\nfor item in os.listdir(\"/kaggle/input/diabetic-retinopathy-detection\"):\n    print(item)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T11:43:53.563193Z","iopub.execute_input":"2025-12-17T11:43:53.563870Z","iopub.status.idle":"2025-12-17T11:43:53.569558Z","shell.execute_reply.started":"2025-12-17T11:43:53.563842Z","shell.execute_reply":"2025-12-17T11:43:53.569023Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import zipfile\nimport os\n\nzip_path = \"/kaggle/input/diabetic-retinopathy-detection/trainLabels.csv.zip\"\nextract_path = \"/kaggle/working/eyepacs\"\n\nos.makedirs(extract_path, exist_ok=True)\n\nwith zipfile.ZipFile(zip_path, 'r') as zip_ref:\n    zip_ref.extractall(extract_path)\n\nprint(os.listdir(extract_path))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T11:44:37.084371Z","iopub.execute_input":"2025-12-17T11:44:37.084648Z","iopub.status.idle":"2025-12-17T11:44:37.108465Z","shell.execute_reply.started":"2025-12-17T11:44:37.084626Z","shell.execute_reply":"2025-12-17T11:44:37.107782Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\n\neyepacs_df = pd.read_csv(\"/kaggle/working/eyepacs/trainLabels.csv\")\n\neyepacs_df.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T11:44:53.358941Z","iopub.execute_input":"2025-12-17T11:44:53.359232Z","iopub.status.idle":"2025-12-17T11:44:53.412332Z","shell.execute_reply.started":"2025-12-17T11:44:53.359208Z","shell.execute_reply":"2025-12-17T11:44:53.411783Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# EyePACS standard format\neyepacs_df.rename(\n    columns={\"image\": \"id_code\", \"level\": \"label\"},\n    inplace=True\n)\n\neyepacs_df[\"source\"] = \"EyePACS\"\n\neyepacs_df.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T11:45:40.333842Z","iopub.execute_input":"2025-12-17T11:45:40.334138Z","iopub.status.idle":"2025-12-17T11:45:40.343747Z","shell.execute_reply.started":"2025-12-17T11:45:40.334113Z","shell.execute_reply":"2025-12-17T11:45:40.343036Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"aptos_df = pd.read_csv(\n    \"/kaggle/input/aptos2019-blindness-detection/train.csv\"\n)\n\naptos_df.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T11:46:26.175205Z","iopub.execute_input":"2025-12-17T11:46:26.175781Z","iopub.status.idle":"2025-12-17T11:46:26.192360Z","shell.execute_reply.started":"2025-12-17T11:46:26.175745Z","shell.execute_reply":"2025-12-17T11:46:26.191798Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"aptos_df.rename(columns={\"diagnosis\": \"label\"}, inplace=True)\naptos_df[\"source\"] = \"APTOS\"\n\naptos_df.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T11:46:45.653641Z","iopub.execute_input":"2025-12-17T11:46:45.653945Z","iopub.status.idle":"2025-12-17T11:46:45.665429Z","shell.execute_reply.started":"2025-12-17T11:46:45.653923Z","shell.execute_reply":"2025-12-17T11:46:45.664642Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"EyePACS:\", eyepacs_df.shape)\nprint(\"APTOS:\", aptos_df.shape)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T11:48:03.145273Z","iopub.execute_input":"2025-12-17T11:48:03.146054Z","iopub.status.idle":"2025-12-17T11:48:03.150362Z","shell.execute_reply.started":"2025-12-17T11:48:03.146023Z","shell.execute_reply":"2025-12-17T11:48:03.149519Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#both merging\n\nfull_df = pd.concat(\n    [eyepacs_df, aptos_df],\n    ignore_index=True\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T11:49:28.545632Z","iopub.execute_input":"2025-12-17T11:49:28.546365Z","iopub.status.idle":"2025-12-17T11:49:28.551511Z","shell.execute_reply.started":"2025-12-17T11:49:28.546332Z","shell.execute_reply":"2025-12-17T11:49:28.550990Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Full dataset shape:\", full_df.shape)\n\nprint(\"\\nSource distribution:\")\nprint(full_df[\"source\"].value_counts())\n\nprint(\"\\nLabel distribution:\")\nprint(full_df[\"label\"].value_counts())\n\nfull_df.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T11:49:36.546535Z","iopub.execute_input":"2025-12-17T11:49:36.547163Z","iopub.status.idle":"2025-12-17T11:49:36.596609Z","shell.execute_reply.started":"2025-12-17T11:49:36.547136Z","shell.execute_reply":"2025-12-17T11:49:36.596035Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#STEP 4: IMAGE PREPROCESSING (START SLOW)\n#Goal (iss step ka):\n\n#Black borders remove\n\n#Image readable banani\n\n#Model ke liye ready karni (later resize)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Pick ONE sample image (APTOS)\nimport cv2\nimport matplotlib.pyplot as plt\n\nsample = full_df[full_df[\"source\"] == \"APTOS\"].iloc[0]\n\nimg_path = (\n    \"/kaggle/input/aptos2019-blindness-detection/train_images/\"\n    + sample[\"id_code\"]\n    + \".png\"\n)\n\nimg = cv2.imread(img_path)\nimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\nplt.imshow(img)\nplt.title(\"Original Image\")\nplt.axis(\"off\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T11:53:37.049502Z","iopub.execute_input":"2025-12-17T11:53:37.050076Z","iopub.status.idle":"2025-12-17T11:53:39.282905Z","shell.execute_reply.started":"2025-12-17T11:53:37.050045Z","shell.execute_reply":"2025-12-17T11:53:39.282176Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Black Border Crop Function\nimport numpy as np\n\ndef crop_black(img, tol=7):\n    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)\n    mask = gray > tol\n    if mask.any():\n        img = img[np.ix_(mask.any(1), mask.any(0))]\n    return img\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T11:55:33.054588Z","iopub.execute_input":"2025-12-17T11:55:33.055176Z","iopub.status.idle":"2025-12-17T11:55:33.059275Z","shell.execute_reply.started":"2025-12-17T11:55:33.055149Z","shell.execute_reply":"2025-12-17T11:55:33.058631Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"cropped = crop_black(img)\n\nplt.figure(figsize=(10,4))\n\nplt.subplot(1,2,1)\nplt.imshow(img)\nplt.title(\"Before Crop\")\nplt.axis(\"off\")\n\nplt.subplot(1,2,2)\nplt.imshow(cropped)\nplt.title(\"After Crop\")\nplt.axis(\"off\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T11:55:45.907543Z","iopub.execute_input":"2025-12-17T11:55:45.908238Z","iopub.status.idle":"2025-12-17T11:55:47.124891Z","shell.execute_reply.started":"2025-12-17T11:55:45.908209Z","shell.execute_reply":"2025-12-17T11:55:47.124051Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Resize + Normalize Function\ndef preprocess_image(img, target_size=(224, 224)):\n    img = crop_black(img)\n    img = cv2.resize(img, target_size)\n    img = img / 255.0   # normalize to [0,1]\n    return img\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T11:57:55.997505Z","iopub.execute_input":"2025-12-17T11:57:55.997897Z","iopub.status.idle":"2025-12-17T11:57:56.001976Z","shell.execute_reply.started":"2025-12-17T11:57:55.997869Z","shell.execute_reply":"2025-12-17T11:57:56.001272Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Test Full Preprocessing Pipeline\nprocessed = preprocess_image(img)\n\nplt.figure(figsize=(4,4))\nplt.imshow(processed)\nplt.title(\"Preprocessed Image (224x224)\")\nplt.axis(\"off\")\n\nprint(\"Shape:\", processed.shape)\nprint(\"Pixel range:\", processed.min(), processed.max())\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T11:58:29.668120Z","iopub.execute_input":"2025-12-17T11:58:29.668651Z","iopub.status.idle":"2025-12-17T11:58:29.948457Z","shell.execute_reply.started":"2025-12-17T11:58:29.668617Z","shell.execute_reply":"2025-12-17T11:58:29.947555Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Image Loader Function\ndef load_image(row):\n    if row[\"source\"] == \"APTOS\":\n        path = (\n            \"/kaggle/input/aptos2019-blindness-detection/train_images/\"\n            + row[\"id_code\"]\n            + \".png\"\n        )\n    else:  # EyePACS (later, when images available)\n        path = None\n    \n    img = cv2.imread(path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    img = preprocess_image(img)\n    return img\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T12:00:56.880032Z","iopub.execute_input":"2025-12-17T12:00:56.880741Z","iopub.status.idle":"2025-12-17T12:00:56.884911Z","shell.execute_reply.started":"2025-12-17T12:00:56.880699Z","shell.execute_reply":"2025-12-17T12:00:56.884210Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#: Test Loader on 3 Images\nfor i in range(3):\n    sample = full_df[full_df[\"source\"] == \"APTOS\"].iloc[i]\n    img = load_image(sample)\n    plt.imshow(img)\n    plt.title(f\"Label: {sample['label']}\")\n    plt.axis(\"off\")\n    plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T12:01:11.076086Z","iopub.execute_input":"2025-12-17T12:01:11.076613Z","iopub.status.idle":"2025-12-17T12:01:12.325287Z","shell.execute_reply.started":"2025-12-17T12:01:11.076585Z","shell.execute_reply":"2025-12-17T12:01:12.324604Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#TRAIN–VALIDATION SPLIT (APTOS ONLY)\nfrom sklearn.model_selection import train_test_split\n\naptos_only = full_df[full_df[\"source\"] == \"APTOS\"].reset_index(drop=True)\n\ntrain_df, val_df = train_test_split(\n    aptos_only,\n    test_size=0.2,\n    stratify=aptos_only[\"label\"],\n    random_state=42\n)\n\nprint(\"Train:\", train_df.shape)\nprint(\"Val:\", val_df.shape)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T12:03:28.992364Z","iopub.execute_input":"2025-12-17T12:03:28.992747Z","iopub.status.idle":"2025-12-17T12:03:29.933061Z","shell.execute_reply.started":"2025-12-17T12:03:28.992706Z","shell.execute_reply":"2025-12-17T12:03:29.932194Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import random\nimport cv2\nimport matplotlib.pyplot as plt\n\nsamples = aptos_df.sample(6, random_state=42)\n\nplt.figure(figsize=(12, 8))\n\nfor i, (_, row) in enumerate(samples.iterrows()):\n    img_path = (\n        \"/kaggle/input/aptos2019-blindness-detection/train_images/\"\n        + row[\"id_code\"]\n        + \".png\"\n    )\n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\n    plt.subplot(2, 3, i+1)\n    plt.imshow(img)\n    plt.title(f\"Label: {row['label']}\")\n    plt.axis(\"off\")\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T13:44:15.595684Z","iopub.execute_input":"2025-12-17T13:44:15.596627Z","iopub.status.idle":"2025-12-17T13:44:18.231509Z","shell.execute_reply.started":"2025-12-17T13:44:15.596584Z","shell.execute_reply":"2025-12-17T13:44:18.230792Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(15, 6))\n\nfor label in range(5):\n    row = aptos_df[aptos_df[\"label\"] == label].sample(1, random_state=1).iloc[0]\n    img_path = (\n        \"/kaggle/input/aptos2019-blindness-detection/train_images/\"\n        + row[\"id_code\"]\n        + \".png\"\n    )\n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\n    plt.subplot(1, 5, label+1)\n    plt.imshow(img)\n    plt.title(f\"Class {label}\")\n    plt.axis(\"off\")\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T13:45:05.808101Z","iopub.execute_input":"2025-12-17T13:45:05.808880Z","iopub.status.idle":"2025-12-17T13:45:08.025135Z","shell.execute_reply.started":"2025-12-17T13:45:05.808851Z","shell.execute_reply":"2025-12-17T13:45:08.024287Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install -q ultralytics\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T13:46:06.051470Z","iopub.execute_input":"2025-12-17T13:46:06.052243Z","iopub.status.idle":"2025-12-17T13:46:14.578157Z","shell.execute_reply.started":"2025-12-17T13:46:06.052214Z","shell.execute_reply":"2025-12-17T13:46:14.577140Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from ultralytics import YOLO\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T13:46:44.153481Z","iopub.execute_input":"2025-12-17T13:46:44.154303Z","iopub.status.idle":"2025-12-17T13:46:55.934031Z","shell.execute_reply.started":"2025-12-17T13:46:44.154268Z","shell.execute_reply":"2025-12-17T13:46:55.933437Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import cv2\nimport numpy as np\n\ndef generate_pseudo_boxes(img):\n    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)\n\n    # enhance contrast\n    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))\n    enhanced = clahe.apply(gray)\n\n    # threshold\n    _, thresh = cv2.threshold(enhanced, 200, 255, cv2.THRESH_BINARY)\n\n    # find contours\n    contours, _ = cv2.findContours(\n        thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE\n    )\n\n    boxes = []\n    h, w = gray.shape\n\n    for cnt in contours:\n        x, y, bw, bh = cv2.boundingRect(cnt)\n        area = bw * bh\n\n        if area > 300:   # remove tiny noise\n            boxes.append((x, y, bw, bh))\n\n    return boxes\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T13:47:13.055148Z","iopub.execute_input":"2025-12-17T13:47:13.056275Z","iopub.status.idle":"2025-12-17T13:47:13.062169Z","shell.execute_reply.started":"2025-12-17T13:47:13.056238Z","shell.execute_reply":"2025-12-17T13:47:13.061413Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nsample = aptos_df.sample(1).iloc[0]\nimg_path = (\n    \"/kaggle/input/aptos2019-blindness-detection/train_images/\"\n    + sample[\"id_code\"]\n    + \".png\"\n)\n\nimg = cv2.imread(img_path)\nimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\nboxes = generate_pseudo_boxes(img)\n\nfor (x, y, w, h) in boxes:\n    cv2.rectangle(img, (x,y), (x+w, y+h), (255,0,0), 2)\n\nplt.figure(figsize=(6,6))\nplt.imshow(img)\nplt.title(\"Pseudo Bounding Boxes\")\nplt.axis(\"off\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T13:47:24.527168Z","iopub.execute_input":"2025-12-17T13:47:24.527448Z","iopub.status.idle":"2025-12-17T13:47:24.847058Z","shell.execute_reply.started":"2025-12-17T13:47:24.527424Z","shell.execute_reply":"2025-12-17T13:47:24.846348Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport cv2\nimport random\n\nsamples = aptos_df.sample(6, random_state=42)\n\nplt.figure(figsize=(14, 10))\n\nfor i, (_, row) in enumerate(samples.iterrows()):\n    img_path = (\n        \"/kaggle/input/aptos2019-blindness-detection/train_images/\"\n        + row[\"id_code\"]\n        + \".png\"\n    )\n    \n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\n    boxes = generate_pseudo_boxes(img)\n\n    # draw BLACK + BOLD boxes\n    for (x, y, w, h) in boxes:\n        cv2.rectangle(\n            img,\n            (x, y),\n            (x + w, y + h),\n            (0, 0, 0),   # BLACK color\n            4            # thickness (bold)\n        )\n\n    plt.subplot(2, 3, i + 1)\n    plt.imshow(img)\n    plt.title(f\"Label: {row['label']}\")\n    plt.axis(\"off\")\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T13:50:23.409594Z","iopub.execute_input":"2025-12-17T13:50:23.410161Z","iopub.status.idle":"2025-12-17T13:50:26.465210Z","shell.execute_reply.started":"2025-12-17T13:50:23.410131Z","shell.execute_reply":"2025-12-17T13:50:26.464334Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def convert_to_yolo_format(boxes, img_w, img_h):\n    yolo_labels = []\n\n    for (x, y, w, h) in boxes:\n        x_center = (x + w / 2) / img_w\n        y_center = (y + h / 2) / img_h\n        bw = w / img_w\n        bh = h / img_h\n\n        # class 0 = lesion\n        yolo_labels.append(f\"0 {x_center} {y_center} {bw} {bh}\")\n\n    return yolo_labels\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T13:51:46.589870Z","iopub.execute_input":"2025-12-17T13:51:46.590513Z","iopub.status.idle":"2025-12-17T13:51:46.595230Z","shell.execute_reply.started":"2025-12-17T13:51:46.590482Z","shell.execute_reply":"2025-12-17T13:51:46.594555Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\nbase_dir = \"/kaggle/working/yolo_aptos\"\nimg_dir = os.path.join(base_dir, \"images/train\")\nlbl_dir = os.path.join(base_dir, \"labels/train\")\n\nos.makedirs(img_dir, exist_ok=True)\nos.makedirs(lbl_dir, exist_ok=True)\n\nprint(\"Folders ready\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T13:52:33.651362Z","iopub.execute_input":"2025-12-17T13:52:33.652137Z","iopub.status.idle":"2025-12-17T13:52:33.657624Z","shell.execute_reply.started":"2025-12-17T13:52:33.652104Z","shell.execute_reply":"2025-12-17T13:52:33.656799Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import shutil\n\nsubset = aptos_df.sample(200, random_state=42)\n\nfor _, row in subset.iterrows():\n    img_name = row[\"id_code\"] + \".png\"\n    src_path = (\n        \"/kaggle/input/aptos2019-blindness-detection/train_images/\"\n        + img_name\n    )\n\n    img = cv2.imread(src_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\n    h, w, _ = img.shape\n    boxes = generate_pseudo_boxes(img)\n    yolo_labels = convert_to_yolo_format(boxes, w, h)\n\n    # save image\n    shutil.copy(src_path, os.path.join(img_dir, img_name))\n\n    # save label file\n    label_path = os.path.join(lbl_dir, row[\"id_code\"] + \".txt\")\n    with open(label_path, \"w\") as f:\n        for line in yolo_labels:\n            f.write(line + \"\\n\")\n\nprint(\"200 images + labels saved\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T13:52:43.442797Z","iopub.execute_input":"2025-12-17T13:52:43.443482Z","iopub.status.idle":"2025-12-17T13:53:06.772896Z","shell.execute_reply.started":"2025-12-17T13:52:43.443453Z","shell.execute_reply":"2025-12-17T13:53:06.772142Z"}},"outputs":[],"execution_count":null}]}