{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.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":8900,"databundleVersionId":862232,"sourceType":"competition"}],"dockerImageVersionId":31153,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"code","source":"import numpy as np\nimport librosa\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.utils.class_weight import compute_class_weight\nimport pandas as pd\nimport os\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T12:25:49.438570Z","iopub.execute_input":"2025-10-22T12:25:49.439200Z","iopub.status.idle":"2025-10-22T12:26:10.477356Z","shell.execute_reply.started":"2025-10-22T12:25:49.439169Z","shell.execute_reply":"2025-10-22T12:26:10.476044Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"AUDIO_DIR = \"/kaggle/input/freesound-audio-tagging/audio_train\"\nCSV_PATH = \"/kaggle/input/freesound-audio-tagging/train.csv\"     \nSAMPLE_RATE = 22050\nN_MELs = 90","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T12:44:40.792030Z","iopub.execute_input":"2025-10-22T12:44:40.792435Z","iopub.status.idle":"2025-10-22T12:44:40.797801Z","shell.execute_reply.started":"2025-10-22T12:44:40.792403Z","shell.execute_reply":"2025-10-22T12:44:40.796499Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def load_dataset_from_csv(audio_dir, csv_path):\n    # Read CSV file\n    df = pd.read_csv(csv_path)\n    print(f\"Loaded CSV with {len(df)} entries\")\n    print(f\"CSV columns: {df.columns.tolist()}\")\n    \n    filename_col = 'fname'\n    label_col = 'label'\n    \n    classes = sorted(df[label_col].unique())\n    print(f\"Found {len(classes)} classes: {classes}\")\n    \n    features = []\n    labels = []\n    file_paths = []\n    durations = []\n    missing_files = []\n    \n    # Create label to index mapping\n    class_to_index = {class_name: idx for idx, class_name in enumerate(classes)}\n    print(\"Class to index mapping:\", class_to_index)\n    \n    for _, row in df.iterrows():\n        filename = row[filename_col]\n        class_name = row[label_col]\n        file_path = os.path.join(audio_dir, filename)\n        \n        # Check if file exists\n        if not os.path.exists(file_path):\n            missing_files.append(filename)\n            continue\n            \n        # Get duration for analysis\n        try:\n            duration = librosa.get_duration(filename=file_path)\n            durations.append(duration)\n            \n            # Process audio file\n            audio, sr = load_and_preprocess_audio(file_path)\n            if audio is None:\n                continue\n                \n            feature = extract_features_from_audio(audio, sr, N_MELs)\n            \n            if feature is not None:\n                features.append(feature)\n                labels.append(class_to_index[class_name])\n                file_paths.append(file_path)\n                \n        except Exception as e:\n            print(f\"Error processing {filename}: {str(e)}\")\n            continue\n    \n    if missing_files:\n        print(f\"Warning: {len(missing_files)} files from CSV not found in audio folder\")\n        print(\"Sample missing files:\", missing_files[:5])\n    \n    print(f\"\\nSuccessfully processed {len(features)} files\")\n    print(f\"Audio Duration Statistics:\")\n    print(f\"Min: {min(durations):.2f}s, Max: {max(durations):.2f}s, Mean: {np.mean(durations):.2f}s\")\n    \n    return np.array(features), np.array(labels), file_paths, classes, durations","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T12:29:03.865779Z","iopub.execute_input":"2025-10-22T12:29:03.866096Z","iopub.status.idle":"2025-10-22T12:29:03.877775Z","shell.execute_reply.started":"2025-10-22T12:29:03.866073Z","shell.execute_reply":"2025-10-22T12:29:03.876524Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def load_and_preprocess_audio(file_path):\n    try:\n        # Load audio file\n        audio, sr = librosa.load(file_path, sr=SAMPLE_RATE)\n        \n        return audio, sr\n    except Exception as e:\n        print(f\"Error loading {file_path}: {str(e)}\")\n        return None, None","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T12:29:13.740290Z","iopub.execute_input":"2025-10-22T12:29:13.740613Z","iopub.status.idle":"2025-10-22T12:29:13.746154Z","shell.execute_reply.started":"2025-10-22T12:29:13.740588Z","shell.execute_reply":"2025-10-22T12:29:13.745027Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def extract_features_from_audio(audio, sr, n_mels=64):\n    \n    mel_spectrogram = librosa.feature.melspectrogram(y=audio, sr=sr, n_mels=n_mels, n_fft=4096, hop_length=512)\n    log_mel_spec = librosa.power_to_db(mel_spectrogram)\n    log_mel_spec = normalize(log_mel_spec)\n    \n    if log_mel_spec.shape[1] < 300:\n        pad_width = 300 - log_mel_spec.shape[1]\n        log_mel_spec = np.pad(log_mel_spec, pad_width=((0, 0), (0, pad_width)), mode='constant')\n    elif log_mel_spec.shape[1] > 300:\n        log_mel_spec = log_mel_spec[:, :300]  \n\n    return log_mel_spec","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T12:38:08.779806Z","iopub.execute_input":"2025-10-22T12:38:08.780221Z","iopub.status.idle":"2025-10-22T12:38:08.788450Z","shell.execute_reply.started":"2025-10-22T12:38:08.780193Z","shell.execute_reply":"2025-10-22T12:38:08.787309Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def normalize(spec):\n    std = np.std(spec)\n    if std == 0:\n        std = 1e-10\n    return (spec - np.mean(spec)) / np.std(spec)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T12:38:20.298832Z","iopub.execute_input":"2025-10-22T12:38:20.299451Z","iopub.status.idle":"2025-10-22T12:38:20.307247Z","shell.execute_reply.started":"2025-10-22T12:38:20.299418Z","shell.execute_reply":"2025-10-22T12:38:20.305405Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def create_variable_length_model(input_shape, num_classes):\n    inputs = keras.Input(shape=input_shape)\n\n    # First conv block\n    x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(inputs)\n    x = layers.MaxPooling2D((2, 2))(x)\n    x = layers.Dropout(0.25)(x)\n    \n    # Second conv block\n    x = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(x)\n    x = layers.MaxPooling2D((2, 2))(x)\n    x = layers.Dropout(0.25)(x)\n    \n    # Third conv block\n    x = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(x)\n    x = layers.MaxPooling2D((2, 2))(x)\n    x = layers.Dropout(0.25)(x)\n    \n    x = layers.Flatten()(x)\n    \n    x = layers.Dense(256, activation='relu')(x)\n    x = layers.Dropout(0.5)(x)\n    \n    outputs = layers.Dense(num_classes, activation='softmax')(x)\n    \n    model = keras.Model(inputs, outputs)\n    return model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T12:38:35.066885Z","iopub.execute_input":"2025-10-22T12:38:35.067222Z","iopub.status.idle":"2025-10-22T12:38:35.075839Z","shell.execute_reply.started":"2025-10-22T12:38:35.067199Z","shell.execute_reply":"2025-10-22T12:38:35.074513Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def augment_features(features):\n    if np.random.random() > 0.5:\n        max_mask_pct = 0.2\n        mask_size = int(features.shape[1] * max_mask_pct * np.random.random())\n        mask_start = np.random.randint(0, features.shape[1] - mask_size)\n        features[:, mask_start:mask_start + mask_size] = 0\n    \n    # Frequency masking\n    if np.random.random() > 0.5:\n        max_mask_pct = 0.15\n        mask_size = int(features.shape[0] * max_mask_pct * np.random.random())\n        mask_start = np.random.randint(0, features.shape[0] - mask_size)\n        features[mask_start:mask_start + mask_size, :] = 0\n    \n    return features","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T12:39:32.739537Z","iopub.execute_input":"2025-10-22T12:39:32.739890Z","iopub.status.idle":"2025-10-22T12:39:32.747359Z","shell.execute_reply.started":"2025-10-22T12:39:32.739863Z","shell.execute_reply":"2025-10-22T12:39:32.745916Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def create_data_generator(features, labels, batch_size=32, augment=False):\n    num_samples = len(features)\n    \n    while True:\n        indices = np.random.permutation(num_samples)\n        \n        for start in range(0, num_samples, batch_size):\n            end = min(start + batch_size, num_samples)\n            batch_indices = indices[start:end]\n            \n            batch_features = []\n            batch_labels = []\n            \n            for idx in batch_indices:\n                feature = features[idx].copy()\n\n                if augment:\n                    feature = augment_features(feature)\n                \n                batch_features.append(feature)\n                batch_labels.append(labels[idx])\n            \n            # Convert to numpy arrays and add channel dimension\n            batch_features = np.array(batch_features)\n            batch_features = batch_features[..., np.newaxis]  # Add channel dimension\n            \n            batch_labels = keras.utils.to_categorical(batch_labels, num_classes=len(np.unique(labels)))\n            \n            yield batch_features, batch_labels","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T12:40:19.707479Z","iopub.execute_input":"2025-10-22T12:40:19.707835Z","iopub.status.idle":"2025-10-22T12:40:19.715791Z","shell.execute_reply.started":"2025-10-22T12:40:19.707812Z","shell.execute_reply":"2025-10-22T12:40:19.714696Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X, y, file_paths, classes, durations = load_dataset_from_csv(AUDIO_DIR, CSV_PATH)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T12:44:44.490148Z","iopub.execute_input":"2025-10-22T12:44:44.490529Z","iopub.status.idle":"2025-10-22T13:06:21.382694Z","shell.execute_reply.started":"2025-10-22T12:44:44.490502Z","shell.execute_reply":"2025-10-22T13:06:21.380871Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class_weights = compute_class_weight('balanced', classes=np.unique(y), y=y)\nclass_weight_dict = {i: weight for i, weight in enumerate(class_weights)}\nprint(\"Class weights:\", class_weight_dict)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T13:06:32.866633Z","iopub.execute_input":"2025-10-22T13:06:32.868385Z","iopub.status.idle":"2025-10-22T13:06:32.886839Z","shell.execute_reply.started":"2025-10-22T13:06:32.868348Z","shell.execute_reply":"2025-10-22T13:06:32.885388Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_categorical = keras.utils.to_categorical(y, num_classes=len(classes))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T13:06:47.833574Z","iopub.execute_input":"2025-10-22T13:06:47.834012Z","iopub.status.idle":"2025-10-22T13:06:47.843140Z","shell.execute_reply.started":"2025-10-22T13:06:47.833983Z","shell.execute_reply":"2025-10-22T13:06:47.841598Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train, X_test, y_train, y_test, paths_train, paths_test = train_test_split(\n    X, y_categorical, file_paths, test_size=0.2, random_state=42, stratify=y\n)\n\nX_train, X_val, y_train, y_val = train_test_split(\n    X_train, y_train, test_size=0.2, random_state=42, stratify=np.argmax(y_train, axis=1)\n)\n\nprint(f\"Training set: {len(X_train)} samples\")\nprint(f\"Validation set: {len(X_val)} samples\")\nprint(f\"Test set: {len(X_test)} samples\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T13:06:54.250055Z","iopub.execute_input":"2025-10-22T13:06:54.250510Z","iopub.status.idle":"2025-10-22T13:06:55.114195Z","shell.execute_reply.started":"2025-10-22T13:06:54.250484Z","shell.execute_reply":"2025-10-22T13:06:55.112948Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"input_shape = (X[0].shape[0], X[0].shape[1], 1)\nprint(f\"Input shape: {input_shape}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T13:07:01.041135Z","iopub.execute_input":"2025-10-22T13:07:01.041462Z","iopub.status.idle":"2025-10-22T13:07:01.047850Z","shell.execute_reply.started":"2025-10-22T13:07:01.041436Z","shell.execute_reply":"2025-10-22T13:07:01.046102Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = create_variable_length_model(input_shape, len(classes))\n    \nmodel.compile(\n    optimizer=keras.optimizers.Adam(learning_rate=0.001),\n    loss='categorical_crossentropy',\n    metrics=['accuracy']\n)\n\ncallbacks = [\n    keras.callbacks.EarlyStopping(\n        patience=15,\n        restore_best_weights=True,\n        monitor='val_accuracy',\n        mode='max'\n    ),\n    keras.callbacks.ReduceLROnPlateau(\n        patience=8,\n        factor=0.5,\n        min_lr=1e-7,\n        verbose=1\n    ),\n    keras.callbacks.ModelCheckpoint(\n        'best_audio_model.keras',\n        save_best_only=True,\n        monitor='val_accuracy',\n        mode='max'\n    )\n]\n\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T13:07:10.313266Z","iopub.execute_input":"2025-10-22T13:07:10.313639Z","iopub.status.idle":"2025-10-22T13:07:10.913694Z","shell.execute_reply.started":"2025-10-22T13:07:10.313586Z","shell.execute_reply":"2025-10-22T13:07:10.912489Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"batch_size = 32\ntrain_gen = create_data_generator(X_train, np.argmax(y_train, axis=1), \n                                batch_size=batch_size, augment=True)\nval_gen = create_data_generator(X_val, np.argmax(y_val, axis=1), \n                              batch_size=batch_size)\n\n# Calculate steps per epoch\nsteps_per_epoch = len(X_train) // batch_size\nvalidation_steps = len(X_val) // batch_size","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T13:07:41.201805Z","iopub.execute_input":"2025-10-22T13:07:41.202191Z","iopub.status.idle":"2025-10-22T13:07:41.212680Z","shell.execute_reply.started":"2025-10-22T13:07:41.202165Z","shell.execute_reply":"2025-10-22T13:07:41.210514Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Training model...\")\nhistory = model.fit(\n    train_gen,\n    steps_per_epoch=steps_per_epoch,\n    epochs=20,\n    validation_data=val_gen,\n    validation_steps=validation_steps,\n    callbacks=callbacks,\n    verbose=1 )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T13:07:48.088688Z","iopub.execute_input":"2025-10-22T13:07:48.089103Z","iopub.status.idle":"2025-10-22T14:28:50.133826Z","shell.execute_reply.started":"2025-10-22T13:07:48.089075Z","shell.execute_reply":"2025-10-22T14:28:50.131030Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"\\nEvaluating on test set...\")\nX_test_processed = np.array([x[..., np.newaxis] for x in X_test])\n\ny_pred = model.predict(X_test_processed)\ny_pred_classes = np.argmax(y_pred, axis=1)\ny_true_classes = np.argmax(y_test, axis=1)\n\n# Calculate accuracy\naccuracy = np.sum(y_pred_classes == y_true_classes) / len(y_true_classes)\nprint(f\"FINAL TEST ACCURACY: {accuracy:.4f} ({accuracy*100:.2f}%)\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T14:30:53.576923Z","iopub.execute_input":"2025-10-22T14:30:53.577588Z","iopub.status.idle":"2025-10-22T14:31:13.423575Z","shell.execute_reply.started":"2025-10-22T14:30:53.577501Z","shell.execute_reply":"2025-10-22T14:31:13.422574Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nfig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 5))\n\n# Accuracy\nax1.plot(history.history['accuracy'], label='Training Accuracy')\nax1.plot(history.history['val_accuracy'], label='Validation Accuracy')\nax1.set_title('Model Accuracy')\nax1.set_xlabel('Epoch')\nax1.set_ylabel('Accuracy')\nax1.legend()\nax1.grid(True)\n\n# Loss\nax2.plot(history.history['loss'], label='Training Loss')\nax2.plot(history.history['val_loss'], label='Validation Loss')\nax2.set_title('Model Loss')\nax2.set_xlabel('Epoch')\nax2.set_ylabel('Loss')\nax2.legend()\nax2.grid(True)\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T14:32:20.555827Z","iopub.execute_input":"2025-10-22T14:32:20.556208Z","iopub.status.idle":"2025-10-22T14:32:21.294399Z","shell.execute_reply.started":"2025-10-22T14:32:20.556182Z","shell.execute_reply":"2025-10-22T14:32:21.292919Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"TEST_AUDIO_DIR = \"/kaggle/input/freesound-audio-tagging/audio_test\"\nTEST_CSV_PATH = \"/kaggle/input/freesound-audio-tagging/sample_submission.csv\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T14:33:42.645166Z","iopub.execute_input":"2025-10-22T14:33:42.645585Z","iopub.status.idle":"2025-10-22T14:33:42.651262Z","shell.execute_reply.started":"2025-10-22T14:33:42.645553Z","shell.execute_reply":"2025-10-22T14:33:42.650143Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_Test, _, file_paths, _, durations = load_dataset_from_csv(TEST_AUDIO_DIR, TEST_CSV_PATH)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T14:33:50.692495Z","iopub.execute_input":"2025-10-22T14:33:50.692898Z","iopub.status.idle":"2025-10-22T14:55:03.111128Z","shell.execute_reply.started":"2025-10-22T14:33:50.692867Z","shell.execute_reply":"2025-10-22T14:55:03.109629Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"input_shape = (X_Test[0].shape[0], X_Test[0].shape[1], 1)\nprint(f\"Input shape: {input_shape}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T15:00:10.031180Z","iopub.execute_input":"2025-10-22T15:00:10.032965Z","iopub.status.idle":"2025-10-22T15:00:10.047864Z","shell.execute_reply.started":"2025-10-22T15:00:10.032927Z","shell.execute_reply":"2025-10-22T15:00:10.046504Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fnames = [os.path.basename(p) for p in file_paths]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T15:00:31.065224Z","iopub.execute_input":"2025-10-22T15:00:31.065621Z","iopub.status.idle":"2025-10-22T15:00:31.092739Z","shell.execute_reply.started":"2025-10-22T15:00:31.065595Z","shell.execute_reply":"2025-10-22T15:00:31.091592Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def predict_and_save(model, features, fnames, classes, output_csv=\"submission.csv\"):\n    # Predict\n    preds = model.predict(features)\n    predicted_indices = np.argmax(preds, axis=1)\n    predicted_labels = [classes[i] for i in predicted_indices]\n\n    # Save to CSV\n    submission_df = pd.DataFrame({\n        'fname': fnames,\n        'label': predicted_labels\n    })\n    submission_df.to_csv(output_csv, index=False)\n    print(f\"Saved predictions to {output_csv}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T15:00:57.211522Z","iopub.execute_input":"2025-10-22T15:00:57.211925Z","iopub.status.idle":"2025-10-22T15:00:57.220384Z","shell.execute_reply.started":"2025-10-22T15:00:57.211898Z","shell.execute_reply":"2025-10-22T15:00:57.219241Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"Test_features = np.array(X_Test)\nTest_features = Test_features[..., np.newaxis]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T15:01:07.381789Z","iopub.execute_input":"2025-10-22T15:01:07.382368Z","iopub.status.idle":"2025-10-22T15:01:08.812328Z","shell.execute_reply.started":"2025-10-22T15:01:07.382333Z","shell.execute_reply":"2025-10-22T15:01:08.810828Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predict_and_save(model, Test_features, fnames, classes)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-22T15:01:27.330449Z","iopub.execute_input":"2025-10-22T15:01:27.330804Z","iopub.status.idle":"2025-10-22T15:03:30.563949Z","shell.execute_reply.started":"2025-10-22T15:01:27.330783Z","shell.execute_reply":"2025-10-22T15:03:30.561949Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}