{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.models import Sequential","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:46.97349Z","iopub.execute_input":"2023-01-27T07:54:46.97378Z","iopub.status.idle":"2023-01-27T07:54:46.978714Z","shell.execute_reply.started":"2023-01-27T07:54:46.973748Z","shell.execute_reply":"2023-01-27T07:54:46.977891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load the data\n\n# Get current working directory\ncurrent_dir = os.getcwd() \n\n# Append data/mnist.npz to the previous path to get the full path\ndata_path = \"/kaggle/input/rsna-breast-cancer-detection/train_images\"","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:46.985012Z","iopub.execute_input":"2023-01-27T07:54:46.9853Z","iopub.status.idle":"2023-01-27T07:54:46.992427Z","shell.execute_reply.started":"2023-01-27T07:54:46.985271Z","shell.execute_reply":"2023-01-27T07:54:46.991594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def reshape_and_normalize(images):\n    \n    # Reshape the images to add an extra dimension\n    # images = images[..., np.newaxis]\n    \n    # Normalize pixel values\n    images = images / 255.0\n    \n    ### END CODE HERE\n    return images","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:46.994183Z","iopub.execute_input":"2023-01-27T07:54:46.995282Z","iopub.status.idle":"2023-01-27T07:54:47.003063Z","shell.execute_reply.started":"2023-01-27T07:54:46.995244Z","shell.execute_reply":"2023-01-27T07:54:47.002154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_csv = pd.read_csv(\"/kaggle/input/rsna-breast-cancer-detection/train.csv\")\ntest_csv = pd.read_csv(\"/kaggle/input/rsna-breast-cancer-detection/test.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.004601Z","iopub.execute_input":"2023-01-27T07:54:47.005109Z","iopub.status.idle":"2023-01-27T07:54:47.112081Z","shell.execute_reply.started":"2023-01-27T07:54:47.00507Z","shell.execute_reply":"2023-01-27T07:54:47.111263Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_csv","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.114864Z","iopub.execute_input":"2023-01-27T07:54:47.115452Z","iopub.status.idle":"2023-01-27T07:54:47.149794Z","shell.execute_reply.started":"2023-01-27T07:54:47.115411Z","shell.execute_reply":"2023-01-27T07:54:47.14871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_csv","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.151668Z","iopub.execute_input":"2023-01-27T07:54:47.152011Z","iopub.status.idle":"2023-01-27T07:54:47.167807Z","shell.execute_reply.started":"2023-01-27T07:54:47.151961Z","shell.execute_reply":"2023-01-27T07:54:47.166731Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_csv.columns","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.169929Z","iopub.execute_input":"2023-01-27T07:54:47.17029Z","iopub.status.idle":"2023-01-27T07:54:47.180956Z","shell.execute_reply.started":"2023-01-27T07:54:47.170245Z","shell.execute_reply":"2023-01-27T07:54:47.180066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_csv.cancer.value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.182876Z","iopub.execute_input":"2023-01-27T07:54:47.183687Z","iopub.status.idle":"2023-01-27T07:54:47.198958Z","shell.execute_reply.started":"2023-01-27T07:54:47.183523Z","shell.execute_reply":"2023-01-27T07:54:47.197738Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(set(train_csv.patient_id))","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.202781Z","iopub.execute_input":"2023-01-27T07:54:47.203051Z","iopub.status.idle":"2023-01-27T07:54:47.215908Z","shell.execute_reply.started":"2023-01-27T07:54:47.203018Z","shell.execute_reply":"2023-01-27T07:54:47.215119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_csv.age.hist()","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.21751Z","iopub.execute_input":"2023-01-27T07:54:47.218068Z","iopub.status.idle":"2023-01-27T07:54:47.498291Z","shell.execute_reply.started":"2023-01-27T07:54:47.218027Z","shell.execute_reply":"2023-01-27T07:54:47.497533Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_csv.laterality.value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.499782Z","iopub.execute_input":"2023-01-27T07:54:47.500268Z","iopub.status.idle":"2023-01-27T07:54:47.513155Z","shell.execute_reply.started":"2023-01-27T07:54:47.500228Z","shell.execute_reply":"2023-01-27T07:54:47.512127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_subset_0 = train_csv[train_csv.cancer == 0]\ntrain_subset_1 = train_csv[train_csv.cancer == 1]\nprint(train_subset_0.shape, train_subset_1.shape)\nprint(train_subset_0.laterality.value_counts())\nprint(train_subset_1.laterality.value_counts())","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.514865Z","iopub.execute_input":"2023-01-27T07:54:47.515176Z","iopub.status.idle":"2023-01-27T07:54:47.541696Z","shell.execute_reply.started":"2023-01-27T07:54:47.515135Z","shell.execute_reply":"2023-01-27T07:54:47.54044Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_subset_0_L = train_subset_0[train_subset_0.laterality == \"L\"].iloc[:588,]\ntrain_subset_0_R = train_subset_0[train_subset_0.laterality == \"R\"].iloc[:570,]\ntrain_subset_main = pd.concat([train_subset_0_L, train_subset_0_R, train_subset_1])","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.543001Z","iopub.execute_input":"2023-01-27T07:54:47.544803Z","iopub.status.idle":"2023-01-27T07:54:47.568699Z","shell.execute_reply.started":"2023-01-27T07:54:47.544766Z","shell.execute_reply":"2023-01-27T07:54:47.567824Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_subset_main","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.570253Z","iopub.execute_input":"2023-01-27T07:54:47.57058Z","iopub.status.idle":"2023-01-27T07:54:47.604118Z","shell.execute_reply.started":"2023-01-27T07:54:47.570538Z","shell.execute_reply":"2023-01-27T07:54:47.603101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_subset_main.laterality.value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.605484Z","iopub.execute_input":"2023-01-27T07:54:47.605864Z","iopub.status.idle":"2023-01-27T07:54:47.615389Z","shell.execute_reply.started":"2023-01-27T07:54:47.60582Z","shell.execute_reply":"2023-01-27T07:54:47.614218Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_subset_main.shape","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.617507Z","iopub.execute_input":"2023-01-27T07:54:47.618184Z","iopub.status.idle":"2023-01-27T07:54:47.626338Z","shell.execute_reply.started":"2023-01-27T07:54:47.618137Z","shell.execute_reply":"2023-01-27T07:54:47.625417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not os.path.exists('/kaggle/working/input_transformed/'):\n   os.mkdir('/kaggle/working/input_transformed/')\n#os.mkdir('/kaggle/working/input_transformed/')","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.628076Z","iopub.execute_input":"2023-01-27T07:54:47.628726Z","iopub.status.idle":"2023-01-27T07:54:47.637374Z","shell.execute_reply.started":"2023-01-27T07:54:47.628681Z","shell.execute_reply":"2023-01-27T07:54:47.636524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not os.path.exists('/kaggle/working/input_transformed/0/'):\n   os.mkdir('/kaggle/working/input_transformed/0/')\nif not os.path.exists('/kaggle/working/input_transformed/1/'):\n   os.mkdir('/kaggle/working/input_transformed/1/')","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.639229Z","iopub.execute_input":"2023-01-27T07:54:47.639591Z","iopub.status.idle":"2023-01-27T07:54:47.648159Z","shell.execute_reply.started":"2023-01-27T07:54:47.639548Z","shell.execute_reply":"2023-01-27T07:54:47.647255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import shutil\nfrom tqdm import tqdm\n# shutil.copyfile(src, dst)","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.650076Z","iopub.execute_input":"2023-01-27T07:54:47.650429Z","iopub.status.idle":"2023-01-27T07:54:47.658641Z","shell.execute_reply.started":"2023-01-27T07:54:47.650389Z","shell.execute_reply":"2023-01-27T07:54:47.657661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"p_id = train_subset_main.patient_id\ni_id = train_subset_main.image_id\ncncr = train_subset_main.cancer\nfor pp, ii, cc in tqdm(zip(p_id, i_id, cncr)):\n    tmpFile = str(pp) + \"_\" + str(ii) + \".png\"\n    tmpSrc = \"/kaggle/input/rsna-breast-cancer-512-pngs/\" + tmpFile\n    #print('temp src: ',tmpSrc)\n    tmpDst = \"/kaggle/working/input_transformed/\" + str(cc) + \"/\" + tmpFile\n    #print('temp dst; ',tmpDst)\n    shutil.copy(tmpSrc, tmpDst)","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:47.660861Z","iopub.execute_input":"2023-01-27T07:54:47.661105Z","iopub.status.idle":"2023-01-27T07:54:53.976606Z","shell.execute_reply.started":"2023-01-27T07:54:47.661077Z","shell.execute_reply":"2023-01-27T07:54:53.975763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_ds = tf.keras.preprocessing.image_dataset_from_directory(\n    \"/kaggle/working/input_transformed/\",\n    color_mode='rgb',\n    image_size=(512, 512),\n    batch_size = 8,\n    shuffle=True,\n    validation_split=0.2,\n    subset=\"training\",\n    seed=2023)","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:53.980345Z","iopub.execute_input":"2023-01-27T07:54:53.980582Z","iopub.status.idle":"2023-01-27T07:54:54.109934Z","shell.execute_reply.started":"2023-01-27T07:54:53.980553Z","shell.execute_reply":"2023-01-27T07:54:54.109087Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_ds = tf.keras.preprocessing.image_dataset_from_directory(\n    \"/kaggle/working/input_transformed/\",\n    color_mode='rgb',\n    image_size=(512, 512),\n    shuffle=True,\n    batch_size = 8, \n    validation_split=0.2,\n    subset=\"validation\",\n    seed=2023)","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:54.111665Z","iopub.execute_input":"2023-01-27T07:54:54.112134Z","iopub.status.idle":"2023-01-27T07:54:54.23785Z","shell.execute_reply.started":"2023-01-27T07:54:54.11209Z","shell.execute_reply":"2023-01-27T07:54:54.237038Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense,Conv2D,Flatten,MaxPooling2D\nfrom tensorflow.keras.callbacks import EarlyStopping,ReduceLROnPlateau\n#inputs = tf.keras.layers.Input(inp_dim)\ninputs = tf.keras.layers.experimental.preprocessing.Rescaling(1./255, input_shape=(512, 512, 3))\nmodel = Sequential()\nmodel.add(Conv2D(32, (3, 3), activation=\"relu\", input_shape=(512,512,3)))\nmodel.add(MaxPooling2D(pool_size = (2, 2)))\nmodel.add(Conv2D(32, (3, 3), activation=\"relu\", input_shape=(256,256,3)))\nmodel.add(MaxPooling2D(pool_size = (2, 2)))\nmodel.add(Conv2D(32, (3, 3), activation=\"relu\", input_shape=(256,256,1)))\nmodel.add(MaxPooling2D(pool_size = (2, 2)))\nmodel.add(Conv2D(32, (3, 3), activation=\"relu\", input_shape=(256,256,1)))\nmodel.add(MaxPooling2D(pool_size = (2, 2)))\nmodel.add(Conv2D(64, (3, 3), activation=\"relu\", input_shape=(256,256,1)))\nmodel.add(MaxPooling2D(pool_size = (2, 2)))\nmodel.add(Conv2D(64, (3, 3), activation=\"relu\", input_shape=(256,256,1)))\nmodel.add(MaxPooling2D(pool_size = (2, 2)))\nmodel.add(Flatten())\nmodel.add(Dense(activation = 'relu', units = 128))\nmodel.add(Dense(activation = 'relu', units = 64))\nmodel.add(Dense(activation = 'relu', units = 32))\nmodel.add(Dense(activation = 'relu', units = 16))\nmodel.add(Dense(activation = 'sigmoid', units = 1))\n\n\nmodel.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])\n\n","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:54.23948Z","iopub.execute_input":"2023-01-27T07:54:54.239728Z","iopub.status.idle":"2023-01-27T07:54:54.374231Z","shell.execute_reply.started":"2023-01-27T07:54:54.239683Z","shell.execute_reply":"2023-01-27T07:54:54.373388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model.compile(optimizer='adam',\n#               loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n#               metrics=['accuracy'])\n","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:54.375825Z","iopub.execute_input":"2023-01-27T07:54:54.376132Z","iopub.status.idle":"2023-01-27T07:54:54.380609Z","shell.execute_reply.started":"2023-01-27T07:54:54.376093Z","shell.execute_reply":"2023-01-27T07:54:54.379353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class myCallback(tf.keras.callbacks.Callback):\n    # Define the method that checks the accuracy at the end of each epoch\n    def on_epoch_end(self, epoch, logs={}):\n        if logs.get('accuracy') is not None and logs.get('accuracy') >= 0.95:\n            print(\"\\nReached 99.5% accuracy so cancelling training!\") \n            # Stop training once the above condition is met\n            self.model.stop_training = True","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:54.382467Z","iopub.execute_input":"2023-01-27T07:54:54.382815Z","iopub.status.idle":"2023-01-27T07:54:54.391494Z","shell.execute_reply.started":"2023-01-27T07:54:54.382775Z","shell.execute_reply":"2023-01-27T07:54:54.390752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs=20\nhistory = model.fit(\n  train_ds,\n  validation_data=valid_ds,\n  epochs=epochs\n)","metadata":{"execution":{"iopub.status.busy":"2023-01-27T07:54:54.393118Z","iopub.execute_input":"2023-01-27T07:54:54.393525Z","iopub.status.idle":"2023-01-27T08:02:01.237961Z","shell.execute_reply.started":"2023-01-27T07:54:54.393486Z","shell.execute_reply":"2023-01-27T08:02:01.233871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nacc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs_range = range(epochs)\n\nplt.figure(figsize=(8, 8))\nplt.subplot(1, 2, 1)\nplt.plot(epochs_range, acc, label='Training Accuracy')\nplt.plot(epochs_range, val_acc, label='Validation Accuracy')\nplt.legend(loc='lower right')\nplt.title('Training and Validation Accuracy')\n\nplt.subplot(1, 2, 2)\nplt.plot(epochs_range, loss, label='Training Loss')\nplt.plot(epochs_range, val_loss, label='Validation Loss')\nplt.legend(loc='upper right')\nplt.title('Training and Validation Loss')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-01-27T08:02:01.242459Z","iopub.execute_input":"2023-01-27T08:02:01.242763Z","iopub.status.idle":"2023-01-27T08:02:01.646006Z","shell.execute_reply.started":"2023-01-27T08:02:01.242726Z","shell.execute_reply":"2023-01-27T08:02:01.645221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if  os.path.exists('/kaggle/working/input_transformed'):\n    shutil.rmtree(\"/kaggle/working/input_transformed/\")","metadata":{"execution":{"iopub.status.busy":"2023-01-27T08:02:01.647243Z","iopub.execute_input":"2023-01-27T08:02:01.648113Z","iopub.status.idle":"2023-01-27T08:02:01.757521Z","shell.execute_reply.started":"2023-01-27T08:02:01.648068Z","shell.execute_reply":"2023-01-27T08:02:01.756712Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image\nimport numpy as np\nfrom skimage import transform\ndef load(filename):\n   np_image = Image.open(filename)\n   np_image = np.array(np_image).astype('float32')/255\n   np_image = transform.resize(np_image, (512, 512, 3))\n   np_image = np.expand_dims(np_image, axis=0)\n   return np_image","metadata":{"execution":{"iopub.status.busy":"2023-01-27T08:02:01.759896Z","iopub.execute_input":"2023-01-27T08:02:01.760276Z","iopub.status.idle":"2023-01-27T08:02:01.765914Z","shell.execute_reply.started":"2023-01-27T08:02:01.760226Z","shell.execute_reply":"2023-01-27T08:02:01.764854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"testdata_path = \"/kaggle/input/rsna-screen-breast-cancer-detect-testdata-512x512\"\npred_dict = dict()\nfor ii in os.listdir(testdata_path):\n    tmpPath = testdata_path + \"/\" + ii\n    image = load(tmpPath)\n    predictions = model.predict(image)\n    score = predictions\n    pred_dict[ii] = float(max(score))","metadata":{"execution":{"iopub.status.busy":"2023-01-27T08:02:01.767373Z","iopub.execute_input":"2023-01-27T08:02:01.767856Z","iopub.status.idle":"2023-01-27T08:02:02.819291Z","shell.execute_reply.started":"2023-01-27T08:02:01.767818Z","shell.execute_reply":"2023-01-27T08:02:02.818521Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from pprint import pprint\ntestD = {\"10008_L\":{\"736471439.png\":0, \"1591370361.png\":0}, \n         \"10008_R\":{\"68070693.png\":0,\"361203119.png\":0}}\n\nfor k1 in testD:\n    for k2 in testD[k1]:\n        testD[k1][k2] = pred_dict[k2]\n\npprint(testD)","metadata":{"execution":{"iopub.status.busy":"2023-01-27T08:02:02.820544Z","iopub.execute_input":"2023-01-27T08:02:02.82273Z","iopub.status.idle":"2023-01-27T08:02:02.830933Z","shell.execute_reply.started":"2023-01-27T08:02:02.822699Z","shell.execute_reply":"2023-01-27T08:02:02.830037Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.read_csv(\"/kaggle/input/rsna-breast-cancer-detection/sample_submission.csv\")\nsubmission","metadata":{"execution":{"iopub.status.busy":"2023-01-27T08:02:02.832832Z","iopub.execute_input":"2023-01-27T08:02:02.833519Z","iopub.status.idle":"2023-01-27T08:02:02.872223Z","shell.execute_reply.started":"2023-01-27T08:02:02.833457Z","shell.execute_reply":"2023-01-27T08:02:02.871357Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for jj in range(submission.shape[0]):\n    tmpKey = submission.prediction_id.iloc[jj]\n    submission.cancer.iloc[jj] = np.mean(list(testD[tmpKey].values()))\nprint(submission)","metadata":{"execution":{"iopub.status.busy":"2023-01-27T08:02:02.874004Z","iopub.execute_input":"2023-01-27T08:02:02.874343Z","iopub.status.idle":"2023-01-27T08:02:02.888292Z","shell.execute_reply.started":"2023-01-27T08:02:02.874282Z","shell.execute_reply":"2023-01-27T08:02:02.887104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv('submission.csv', columns=['prediction_id','cancer'],index=False)\ndisplay(pd.read_csv('submission.csv').head())","metadata":{"execution":{"iopub.status.busy":"2023-01-27T08:02:02.890144Z","iopub.execute_input":"2023-01-27T08:02:02.890492Z","iopub.status.idle":"2023-01-27T08:02:02.923129Z","shell.execute_reply.started":"2023-01-27T08:02:02.890451Z","shell.execute_reply":"2023-01-27T08:02:02.922339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}