class_docstr: A shuffler to shuffle items and create batches.
  
  This class is used internally by :class:`ItemSampler` to shuffle items and
  create batches. It is not supposed to be used directly. The intention of
  this class is to avoid time-consuming iteration over :class:`ItemSet`. As
  an optimization, it slices from the :class:`ItemSet` via indexing first,
  then shuffle and create batches.
  
  Parameters
  ----------
  item_set : ItemSet
      Data to be iterated.
  shuffle : bool
      Option to shuffle before batching.
  batch_size : int
      The size of each batch.
  drop_last : bool
      Option to drop the last batch if it's not full.
  buffer_size : int
      The size of the buffer to store items sliced from the :class:`ItemSet`
      or :class:`ItemSetDict`.
  distributed : bool
      Option to apply on :class:`DistributedItemSampler`.
  drop_uneven_inputs : bool
      Option to make sure the numbers of batches for each replica are the
      same. Applies only when `distributed` is True.
  world_size : int
      The number of model replicas that will be created during Distributed
      Data Parallel (DDP) training. It should be the same as the real world
      size, otherwise it could cause errors. Applies only when `distributed`
      is True.
  rank : int
      The rank of the current replica. Applies only when `distributed` is
      True.
code: def __iter__(self):
      worker_info = torch.utils.data.get_worker_info()
      if worker_info is not None:
          num_workers = worker_info.num_workers
          worker_id = worker_info.id
      else:
          num_workers = 1
          worker_id = 0
      buffer = None
      total = len(self._item_set)
      start_offset, assigned_count, output_count = calculate_range(
          self._distributed,
          total,
          self._num_replicas,
          self._rank,
          num_workers,
          worker_id,
          self._batch_size,
          self._drop_last,
          self._drop_uneven_inputs,
      )
      start = 0
      while start < assigned_count:
          end = min(start + self._buffer_size, assigned_count)
          buffer = self._item_set[
              start_offset + start : start_offset + end
          ]
          indices = torch.arange(end - start)
          if self._shuffle:
              np.random.shuffle(indices.numpy())
          offsets = self._calculate_offsets(buffer)
          for i in range(0, len(indices), self._batch_size):
              if output_count <= 0:
                  break
              batch_indices = indices[
                  i : i + min(self._batch_size, output_count)
              ]
              output_count -= self._batch_size
              yield self._collate_batch(buffer, batch_indices, offsets)
          buffer = None
          start = end
  
imports: from collections.abc import Mapping
  from functools import partial
  from typing import Callable, Iterator, Optional, Union
  import numpy
  import torch
  import torch.distributed
  from torch.utils.data import default_collate
  from torchdata.datapipes.iter import IterableWrapper, IterDataPipe
  from ..base import dgl_warning
  from ..batch import batch
  from ..heterograph import DGLGraph
  from .internal import calculate_range
  from .itemset import ItemSet, ItemSetDict
  from .minibatch import MiniBatch
label_desc: Use image node_id 4 for calling the ItemShufflerAndBatcher obj's underlying member method code with example usage: obj.__iter__() without return types