# Buggy code
def _generate_examples(self, images, annotations, subdir, image_ids):
    """Yields images and annotations.

    Args:
      images: object that iterates over the archive of images.
      annotations: object that iterates over the archive of annotations.
      subdir: subdirectory from which to extract images and annotations, e.g.
        training or testing.
      image_ids: file ids for images in this split.

    Yields:
      A tuple containing the example's key, and the example.
    """
    cv2 = tfds.core.lazy_imports.cv2

    all_annotations = dict()
    for fpath, fobj in annotations:
        prefix, ext = os.path.splitext(fpath)
        if ext != ".txt":
            continue
        if prefix.split("/")[0] != subdir:
            continue

        # Key is the datapoint id. E.g. training/label_2/label_000016 -> 16.
        all_annotations[int(prefix[-6:])] = _parse_kitti_annotations(fobj)

    for fpath, fobj in images:
        prefix, ext = os.path.splitext(fpath)
        if ext != ".png":
            continue
        if prefix.split("/")[0] != subdir:
            continue
        image_id = int(prefix[-6:])
        if image_id not in image_ids:
            continue
        annotations = all_annotations[image_id]
        img = cv2.imdecode(np.fromstring(fobj.read(), dtype=np.uint8), cv2.IMREAD_COLOR)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        height, width, _ = img.shape
        for obj in annotations:
            obj["bbox"] = _build_bounding_box(obj["bbox_raw"], height, width)
            del obj["bbox_raw"]
        _, fname = os.path.split(fpath)
        record = {"image": img, "image/file_name": fname, "objects": annotations}
        yield fname, record


# Traceback (AssertionError)
AssertionError                            Traceback (most recent call last)
<ipython-input-1-0cac24b5abed> in <module>
      1 import tensorflow_datasets as tfds
      2 
----> 3 ds, ds_info = tfds.load("caltech_birds2011", with_info=True)
      4 print(ds_info)

~\Desktop\TF_TFDS\datasets\tensorflow_datasets\core\api_utils.py in disallow_positional_args_dec(fn, instance, args, kwargs)
     51     _check_no_positional(fn, args, ismethod, allowed=allowed)
     52     _check_required(fn, kwargs)
---> 53     return fn(*args, **kwargs)
     54 
     55   return disallow_positional_args_dec(wrapped)  # pylint: disable=no-value-for-parameter

~\Desktop\TF_TFDS\datasets\tensorflow_datasets\core\registered.py in load(name, split, data_dir, batch_size, in_memory, shuffle_files, download, as_supervised, decoders, read_config, with_info, builder_kwargs, download_and_prepare_kwargs, as_dataset_kwargs, try_gcs)
    307   if download:
    308     download_and_prepare_kwargs = download_and_prepare_kwargs or {}
--> 309     dbuilder.download_and_prepare(**download_and_prepare_kwargs)
    310 
    311   if as_dataset_kwargs is None:

~\Desktop\TF_TFDS\datasets\tensorflow_datasets\core\api_utils.py in disallow_positional_args_dec(fn, instance, args, kwargs)
     51     _check_no_positional(fn, args, ismethod, allowed=allowed)
     52     _check_required(fn, kwargs)
---> 53     return fn(*args, **kwargs)
     54 
     55   return disallow_positional_args_dec(wrapped)  # pylint: disable=no-value-for-parameter

~\Desktop\TF_TFDS\datasets\tensorflow_datasets\core\dataset_builder.py in download_and_prepare(self, download_dir, download_config)
    339           self._download_and_prepare(
    340               dl_manager=dl_manager,
--> 341               download_config=download_config)
    342 
    343           # NOTE: If modifying the lines below to put additional information in

~\Desktop\TF_TFDS\datasets\tensorflow_datasets\core\dataset_builder.py in _download_and_prepare(self, dl_manager, download_config)
   1077     super(GeneratorBasedBuilder, self)._download_and_prepare(
   1078         dl_manager=dl_manager,
-> 1079         max_examples_per_split=download_config.max_examples_per_split,
   1080     )
   1081 

~\Desktop\TF_TFDS\datasets\tensorflow_datasets\core\dataset_builder.py in _download_and_prepare(self, dl_manager, **prepare_split_kwargs)
    930 
    931       # Prepare split will record examples associated to the split
--> 932       self._prepare_split(split_generator, **prepare_split_kwargs)
    933 
    934     # Update the info object with the splits.

~\Desktop\TF_TFDS\datasets\tensorflow_datasets\core\dataset_builder.py in _prepare_split(self, split_generator, max_examples_per_split)
   1105       example = self.info.features.encode_example(record)
   1106       writer.write(key, example)
-> 1107     shard_lengths, total_size = writer.finalize()
   1108     split_generator.split_info.shard_lengths.extend(shard_lengths)
   1109     split_generator.split_info.num_bytes = total_size

~\Desktop\TF_TFDS\datasets\tensorflow_datasets\core\tfrecords_writer.py in finalize(self)
    210     print("Shuffling and writing examples to %s" % self._path)
    211     shard_specs = _get_shard_specs(self._num_examples, self._shuffler.size,
--> 212                                    self._shuffler.bucket_lengths, self._path)
    213     # Here we just loop over the examples, and don't use the instructions, just
    214     # the final number of examples in every shard. Instructions could be used to

~\Desktop\TF_TFDS\datasets\tensorflow_datasets\core\tfrecords_writer.py in _get_shard_specs(num_examples, total_size, bucket_lengths, path)
     87   """
     88   num_shards = _get_number_shards(total_size, num_examples)
---> 89   shard_boundaries = _get_shard_boundaries(num_examples, num_shards)
     90   shard_specs = []
     91   bucket_indexes = list(range(len(bucket_lengths)))

~\Desktop\TF_TFDS\datasets\tensorflow_datasets\core\tfrecords_writer.py in _get_shard_boundaries(num_examples, number_of_shards)
    106 def _get_shard_boundaries(num_examples, number_of_shards):
    107   if num_examples == 0:
--> 108     raise AssertionError("No examples were yielded.")
    109   if num_examples < number_of_shards:
    110     raise AssertionError("num_examples ({}) < number_of_shards ({})".format(

AssertionError: No examples were yielded.

# Fixed code
def _generate_examples(self, images, annotations, subdir, image_ids):
    """Yields images and annotations.

    Args:
      images: object that iterates over the archive of images.
      annotations: object that iterates over the archive of annotations.
      subdir: subdirectory from which to extract images and annotations, e.g.
        training or testing.
      image_ids: file ids for images in this split.

    Yields:
      A tuple containing the example's key, and the example.
    """
    cv2 = tfds.core.lazy_imports.cv2

    all_annotations = dict()
    for fpath, fobj in annotations:
        prefix, ext = os.path.splitext(fpath)
        if ext != ".txt":
            continue
        if prefix.split(os.path.sep)[0] != subdir:
            continue

        # Key is the datapoint id. E.g. training/label_2/label_000016 -> 16.
        all_annotations[int(prefix[-6:])] = _parse_kitti_annotations(fobj)

    for fpath, fobj in images:
        prefix, ext = os.path.splitext(fpath)
        if ext != ".png":
            continue
        if prefix.split(os.path.sep)[0] != subdir:
            continue
        image_id = int(prefix[-6:])
        if image_id not in image_ids:
            continue
        annotations = all_annotations[image_id]
        img = cv2.imdecode(np.fromstring(fobj.read(), dtype=np.uint8), cv2.IMREAD_COLOR)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        height, width, _ = img.shape
        for obj in annotations:
            obj["bbox"] = _build_bounding_box(obj["bbox_raw"], height, width)
            del obj["bbox_raw"]
        _, fname = os.path.split(fpath)
        record = {"image": img, "image/file_name": fname, "objects": annotations}
        yield fname, record