{"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":14315,"databundleVersionId":862230,"sourceType":"competition"}],"dockerImageVersionId":31089,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","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","trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:35:46.252243Z","iopub.execute_input":"2025-09-01T02:35:46.252572Z","iopub.status.idle":"2025-09-01T02:38:39.633885Z","shell.execute_reply.started":"2025-09-01T02:35:46.252522Z","shell.execute_reply":"2025-09-01T02:38:39.632877Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# For running inference on the TF-Hub module.\nimport tensorflow as tf\n\nimport tensorflow_hub as hub\n\n# For downloading the image.\nimport matplotlib.pyplot as plt\nimport tempfile\nfrom six.moves.urllib.request import urlopen\nfrom six import BytesIO\n\n# For drawing onto the image.\nimport numpy as np\nfrom PIL import Image\nfrom PIL import ImageColor\nfrom PIL import ImageDraw\nfrom PIL import ImageFont\nfrom PIL import ImageOps\n\n# For measuring the inference time.\nimport time\n\n# Print Tensorflow version\nprint(tf.__version__)\n\n# Check available GPU devices.\nprint(\"The following GPU devices are available: %s\" % tf.test.gpu_device_name())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:38:39.634936Z","iopub.execute_input":"2025-09-01T02:38:39.635357Z","iopub.status.idle":"2025-09-01T02:38:59.682891Z","shell.execute_reply.started":"2025-09-01T02:38:39.635332Z","shell.execute_reply":"2025-09-01T02:38:59.681532Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install https://github.com/OlafenwaMoses/ImageAI/releases/download/2.0.3/imageai-2.0.3-py3-none-any.whl","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:38:59.684180Z","iopub.execute_input":"2025-09-01T02:38:59.684894Z","iopub.status.idle":"2025-09-01T02:39:03.987573Z","shell.execute_reply.started":"2025-09-01T02:38:59.684857Z","shell.execute_reply":"2025-09-01T02:39:03.986457Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!wget https://github.com/OlafenwaMoses/ImageAI/releases/download/1.0/yolo.h5","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:39:03.989236Z","iopub.execute_input":"2025-09-01T02:39:03.989595Z","iopub.status.idle":"2025-09-01T02:39:08.534808Z","shell.execute_reply.started":"2025-09-01T02:39:03.989532Z","shell.execute_reply":"2025-09-01T02:39:08.533605Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!wget https://storage.googleapis.com/openimages/v5/class-descriptions-boxable.csv","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:39:08.536232Z","iopub.execute_input":"2025-09-01T02:39:08.536645Z","iopub.status.idle":"2025-09-01T02:39:08.764008Z","shell.execute_reply.started":"2025-09-01T02:39:08.536601Z","shell.execute_reply":"2025-09-01T02:39:08.762796Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:39:08.767218Z","iopub.execute_input":"2025-09-01T02:39:08.767529Z","iopub.status.idle":"2025-09-01T02:39:08.773053Z","shell.execute_reply.started":"2025-09-01T02:39:08.767499Z","shell.execute_reply":"2025-09-01T02:39:08.772187Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# <p style=\"padding:15px; background-color:orchid; font-family:arial; font-weight:bold; color:white; font-size:100%; letter-spacing: 2px; text-align:left; border-radius: 10px 10px\"> Data</p>","metadata":{}},{"cell_type":"code","source":"submission = pd.read_csv('/kaggle/input/open-images-2019-object-detection/sample_submission.csv')\nsubmission.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:39:08.774172Z","iopub.execute_input":"2025-09-01T02:39:08.774611Z","iopub.status.idle":"2025-09-01T02:39:09.038340Z","shell.execute_reply.started":"2025-09-01T02:39:08.774575Z","shell.execute_reply":"2025-09-01T02:39:09.037562Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_filename = os.listdir('/kaggle/input/open-images-2019-object-detection/test')\ntest_filename[:5]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:39:09.039150Z","iopub.execute_input":"2025-09-01T02:39:09.039383Z","iopub.status.idle":"2025-09-01T02:39:09.771872Z","shell.execute_reply.started":"2025-09-01T02:39:09.039363Z","shell.execute_reply":"2025-09-01T02:39:09.770963Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"labelMap = pd.read_csv('class-descriptions-boxable.csv', header=None, names=['labelName', 'Label'])\nlabelMap.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:39:09.773221Z","iopub.execute_input":"2025-09-01T02:39:09.773733Z","iopub.status.idle":"2025-09-01T02:39:09.787670Z","shell.execute_reply.started":"2025-09-01T02:39:09.773694Z","shell.execute_reply":"2025-09-01T02:39:09.786717Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# <p style=\"padding:15px; background-color:burlywood; font-family:arial; font-weight:bold; color:white; font-size:100%; letter-spacing: 2px; text-align:left; border-radius: 10px 10px\"> Functions For Downloading Images & For Visualization</p>","metadata":{}},{"cell_type":"code","source":"def display_image(image):\n  fig = plt.figure(figsize=(20, 15))\n  plt.grid(False)\n  plt.imshow(image)\n\n\ndef download_and_resize_image(url, new_width=256, new_height=256,\n                              display=False):\n  _, filename = tempfile.mkstemp(suffix=\".jpg\")\n  response = urlopen(url)\n  image_data = response.read()\n  image_data = BytesIO(image_data)\n  pil_image = Image.open(image_data)\n  pil_image = ImageOps.fit(pil_image, (new_width, new_height), Image.LANCZOS)\n  pil_image_rgb = pil_image.convert(\"RGB\")\n  pil_image_rgb.save(filename, format=\"JPEG\", quality=90)\n  print(\"Image downloaded to %s.\" % filename)\n  if display:\n    display_image(pil_image)\n  return filename\n\n\ndef draw_bounding_box_on_image(image,\n                               ymin,\n                               xmin,\n                               ymax,\n                               xmax,\n                               color,\n                               font,\n                               thickness=4,\n                               display_str_list=()):\n  \"\"\"Adds a bounding box to an image.\"\"\"\n  draw = ImageDraw.Draw(image)\n  im_width, im_height = image.size\n  (left, right, top, bottom) = (xmin * im_width, xmax * im_width,\n                                ymin * im_height, ymax * im_height)\n  draw.line([(left, top), (left, bottom), (right, bottom), (right, top),\n             (left, top)],\n            width=thickness,\n            fill=color)\n\n  # If the total height of the display strings added to the top of the bounding\n  # box exceeds the top of the image, stack the strings below the bounding box\n  # instead of above.\n  display_str_heights = [font.getbbox(ds)[3] for ds in display_str_list]\n  # Each display_str has a top and bottom margin of 0.05x.\n  total_display_str_height = (1 + 2 * 0.05) * sum(display_str_heights)\n\n  if top > total_display_str_height:\n    text_bottom = top\n  else:\n    text_bottom = top + total_display_str_height\n  # Reverse list and print from bottom to top.\n  for display_str in display_str_list[::-1]:\n    bbox = font.getbbox(display_str)\n    text_width, text_height = bbox[2], bbox[3]\n    margin = np.ceil(0.05 * text_height)\n    draw.rectangle([(left, text_bottom - text_height - 2 * margin),\n                    (left + text_width, text_bottom)],\n                   fill=color)\n    draw.text((left + margin, text_bottom - text_height - margin),\n              display_str,\n              fill=\"black\",\n              font=font)\n    text_bottom -= text_height - 2 * margin\n\n\ndef draw_boxes(image, boxes, class_names, scores, max_boxes=10, min_score=0.1):\n  \"\"\"Overlay labeled boxes on an image with formatted scores and label names.\"\"\"\n  colors = list(ImageColor.colormap.values())\n\n  try:\n    font = ImageFont.truetype(\"/usr/share/fonts/truetype/liberation/LiberationSansNarrow-Regular.ttf\",\n                              25)\n  except IOError:\n    print(\"Font not found, using default font.\")\n    font = ImageFont.load_default()\n\n  for i in range(min(boxes.shape[0], max_boxes)):\n    if scores[i] >= min_score:\n      ymin, xmin, ymax, xmax = tuple(boxes[i])\n      display_str = \"{}: {}%\".format(class_names[i].decode(\"ascii\"),\n                                     int(100 * scores[i]))\n      color = colors[hash(class_names[i]) % len(colors)]\n      image_pil = Image.fromarray(np.uint8(image)).convert(\"RGB\")\n      draw_bounding_box_on_image(\n          image_pil,\n          ymin,\n          xmin,\n          ymax,\n          xmax,\n          color,\n          font,\n          display_str_list=[display_str])\n      np.copyto(image, np.array(image_pil))\n  return image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:39:09.788714Z","iopub.execute_input":"2025-09-01T02:39:09.789175Z","iopub.status.idle":"2025-09-01T02:39:10.126883Z","shell.execute_reply.started":"2025-09-01T02:39:09.789142Z","shell.execute_reply":"2025-09-01T02:39:10.125952Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# <p style=\"padding:15px; background-color:lightsalmon; font-family:arial; font-weight:bold; color:white; font-size:100%; letter-spacing: 2px; text-align:left; border-radius: 10px 10px\">ApplyModule</p>","metadata":{}},{"cell_type":"code","source":"# By Heiko Gorski, Source: https://commons.wikimedia.org/wiki/File:Naxos_Taverna.jpg\nimage_url = \"https://c7.staticflickr.com/6/5499/10245691204_98dce75b5a_o.jpg\" \ndownloaded_image_path = download_and_resize_image(image_url, 1280, 856, True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:39:10.127884Z","iopub.execute_input":"2025-09-01T02:39:10.128168Z","iopub.status.idle":"2025-09-01T02:39:12.041245Z","shell.execute_reply.started":"2025-09-01T02:39:10.128144Z","shell.execute_reply":"2025-09-01T02:39:12.039692Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# <p style=\"padding:15px; background-color:burlywood; font-family:arial; font-weight:bold; color:white; font-size:100%; letter-spacing: 2px; text-align:left; border-radius: 10px 10px\"> Object Detection Module</p>","metadata":{}},{"cell_type":"code","source":"module_handle = \"https://tfhub.dev/google/faster_rcnn/openimages_v4/inception_resnet_v2/1\"\n\ndetector = hub.load(module_handle).signatures['default']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:39:12.042253Z","iopub.execute_input":"2025-09-01T02:39:12.043010Z","iopub.status.idle":"2025-09-01T02:42:33.813059Z","shell.execute_reply.started":"2025-09-01T02:39:12.042983Z","shell.execute_reply":"2025-09-01T02:42:33.811994Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def load_img(path):\n  img = tf.io.read_file(path)\n  img = tf.image.decode_jpeg(img, channels=3)\n  return img","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:42:33.814294Z","iopub.execute_input":"2025-09-01T02:42:33.814668Z","iopub.status.idle":"2025-09-01T02:42:33.820005Z","shell.execute_reply.started":"2025-09-01T02:42:33.814637Z","shell.execute_reply":"2025-09-01T02:42:33.818601Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def run_detector(detector, path):\n  img = load_img(path)\n\n  converted_img  = tf.image.convert_image_dtype(img, tf.float32)[tf.newaxis, ...]\n  start_time = time.time()\n  result = detector(converted_img)\n  end_time = time.time()\n\n  result = {key:value.numpy() for key,value in result.items()}\n\n  print(\"Found %d objects.\" % len(result[\"detection_scores\"]))\n  print(\"Inference time: \", end_time-start_time)\n\n  image_with_boxes = draw_boxes(\n      img.numpy(), result[\"detection_boxes\"],\n      result[\"detection_class_entities\"], result[\"detection_scores\"])\n\n  display_image(image_with_boxes)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:42:33.820882Z","iopub.execute_input":"2025-09-01T02:42:33.821140Z","iopub.status.idle":"2025-09-01T02:42:33.844235Z","shell.execute_reply.started":"2025-09-01T02:42:33.821120Z","shell.execute_reply":"2025-09-01T02:42:33.843244Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"run_detector(detector, downloaded_image_path)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:42:33.845150Z","iopub.execute_input":"2025-09-01T02:42:33.845447Z","iopub.status.idle":"2025-09-01T02:43:44.844451Z","shell.execute_reply.started":"2025-09-01T02:42:33.845387Z","shell.execute_reply":"2025-09-01T02:43:44.842869Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<p style=\"padding:15px; background-color:rebeccapurple; font-family:arial; font-weight:bold; color:white; font-size:100%; letter-spacing: 2px; text-align:left; border-radius: 10px 10px\">Perform inference on some additional images with time tracking</p>","metadata":{}},{"cell_type":"code","source":"image_urls = [\n  # Source: https://commons.wikimedia.org/wiki/File:The_Coleoptera_of_the_British_islands_(Plate_125)_(8592917784).jpg\n  #\"https://farm6.staticflickr.com/4126/5145819744_b4a7871064_o.jpg\t\",\n  \"https://c1.staticflickr.com/8/7617/16767947440_68d558453b_o.jpg\",\n  #\"https://farm4.staticflickr.com/3873/14152766838_f978e4b93e_o.jpg\"\n  # By Américo Toledano, Source: https://commons.wikimedia.org/wiki/File:Biblioteca_Maim%C3%B3nides,_Campus_Universitario_de_Rabanales_007.jpg\n  \"https://c5.staticflickr.com/1/6/9857059_f2cf399ff3_o.jpg\",\n  # Source: https://commons.wikimedia.org/wiki/File:The_smaller_British_birds_(8053836633).jpg\n  #\"https://c6.staticflickr.com/4/3836/15059991712_d02d910225_o.jpg\"\n  \"https://farm8.staticflickr.com/6210/6099515726_6b72f1abf0_o.jpg\",\n  \"https://farm2.staticflickr.com/3917/14589191718_5bc1209260_o.jpg\",\n  \"https://farm7.staticflickr.com/7416/9940862744_4ef1834d86_o.jpg\"\n  ]\n\ndef detect_img(image_url):\n  start_time = time.time()\n  image_path = download_and_resize_image(image_url, 640, 480)\n  run_detector(detector, image_path)\n  end_time = time.time()\n  print(\"Inference time:\",end_time-start_time)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:43:44.845982Z","iopub.execute_input":"2025-09-01T02:43:44.846261Z","iopub.status.idle":"2025-09-01T02:43:44.852238Z","shell.execute_reply.started":"2025-09-01T02:43:44.846238Z","shell.execute_reply":"2025-09-01T02:43:44.850960Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"detect_img(image_urls[0])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:43:44.853451Z","iopub.execute_input":"2025-09-01T02:43:44.853866Z","iopub.status.idle":"2025-09-01T02:44:01.455383Z","shell.execute_reply.started":"2025-09-01T02:43:44.853832Z","shell.execute_reply":"2025-09-01T02:44:01.454054Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"detect_img(image_urls[1])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:44:01.456591Z","iopub.execute_input":"2025-09-01T02:44:01.456924Z","iopub.status.idle":"2025-09-01T02:44:17.405337Z","shell.execute_reply.started":"2025-09-01T02:44:01.456899Z","shell.execute_reply":"2025-09-01T02:44:17.404259Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"detect_img(image_urls[3])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:44:17.406366Z","iopub.execute_input":"2025-09-01T02:44:17.406731Z","iopub.status.idle":"2025-09-01T02:44:33.931311Z","shell.execute_reply.started":"2025-09-01T02:44:17.406703Z","shell.execute_reply":"2025-09-01T02:44:33.930202Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"detect_img(image_urls[4])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:44:33.932347Z","iopub.execute_input":"2025-09-01T02:44:33.932642Z","iopub.status.idle":"2025-09-01T02:44:49.788324Z","shell.execute_reply.started":"2025-09-01T02:44:33.932620Z","shell.execute_reply":"2025-09-01T02:44:49.787048Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<p style=\"padding:15px; background-color:fuchsia; font-family:arial; font-weight:bold; color:white; font-size:100%; letter-spacing: 2px; text-align:left; border-radius: 10px 10px\">Apply On Test Images</p>","metadata":{}},{"cell_type":"code","source":"#detect test images\n\nimage_urls = [\n    \"https://c4.staticflickr.com/1/52/129983132_b668be4a47_o.jpg\",\n    \"https://farm2.staticflickr.com/7221/7223448196_7927874f3e_o.jpg\",\n    \"https://c3.staticflickr.com/4/3372/3557249560_fa83b3c878_o.jpg\",\t\n    \"https://c1.staticflickr.com/4/3837/14230768839_436bc3cf5e_o.jpg\",\t\n    \"https://c7.staticflickr.com/6/5293/5519261614_021d7bc5a2_o.jpg\",\t\n    \"https://c1.staticflickr.com/6/5302/5604843970_cb23ec78c5_o.jpg\",\t\n    \"https://c4.staticflickr.com/1/55/155642663_7e28e8b2ff_o.jpg\"\t\n  ]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:44:49.791641Z","iopub.execute_input":"2025-09-01T02:44:49.792013Z","iopub.status.idle":"2025-09-01T02:44:49.797485Z","shell.execute_reply.started":"2025-09-01T02:44:49.791989Z","shell.execute_reply":"2025-09-01T02:44:49.796439Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"detect_img(image_urls[0])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:44:49.798973Z","iopub.execute_input":"2025-09-01T02:44:49.799322Z","iopub.status.idle":"2025-09-01T02:45:05.640012Z","shell.execute_reply.started":"2025-09-01T02:44:49.799294Z","shell.execute_reply":"2025-09-01T02:45:05.638829Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"detect_img(image_urls[1])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:45:05.641139Z","iopub.execute_input":"2025-09-01T02:45:05.641480Z","iopub.status.idle":"2025-09-01T02:45:22.124201Z","shell.execute_reply.started":"2025-09-01T02:45:05.641452Z","shell.execute_reply":"2025-09-01T02:45:22.122870Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"detect_img(image_urls[2])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:45:22.125478Z","iopub.execute_input":"2025-09-01T02:45:22.125861Z","iopub.status.idle":"2025-09-01T02:45:38.822395Z","shell.execute_reply.started":"2025-09-01T02:45:22.125836Z","shell.execute_reply":"2025-09-01T02:45:38.821234Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"detect_img(image_urls[3])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:45:38.823535Z","iopub.execute_input":"2025-09-01T02:45:38.823835Z","iopub.status.idle":"2025-09-01T02:45:55.354266Z","shell.execute_reply.started":"2025-09-01T02:45:38.823813Z","shell.execute_reply":"2025-09-01T02:45:55.352947Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"detect_img(image_urls[4])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:45:55.355516Z","iopub.execute_input":"2025-09-01T02:45:55.355843Z","iopub.status.idle":"2025-09-01T02:46:12.239100Z","shell.execute_reply.started":"2025-09-01T02:45:55.355819Z","shell.execute_reply":"2025-09-01T02:46:12.237376Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"detect_img(image_urls[6])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-01T02:46:12.240536Z","iopub.execute_input":"2025-09-01T02:46:12.240933Z","iopub.status.idle":"2025-09-01T02:46:28.648348Z","shell.execute_reply.started":"2025-09-01T02:46:12.240905Z","shell.execute_reply":"2025-09-01T02:46:28.647298Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}