code: def takeexactly(iterable, size):
      
      total = 0
      for block in iterable:
          n = min(len(block), size - total)
          block = block[:n]
          if block:
              yield block
          total += len(block)
          if total >= size:
              break
      if total < size:
          raise ValueError('not enough data (yielded {} of {})')
  
      # sanity check; this should never happen
      if total != size:  # pragma: no cover
          raise ValueError('yielded too much data')
docs: Yield blocks from `iterable` until exactly len(size) have been returned.
  
      Args:
          iterable (iterable): Any iterable that yields sliceable objects that
                               have length.
          size (int): How much data to consume
  
      Yields:
          blocks from `iterable` such that
          sum(len(block) for block in takeexactly(iterable, size)) == size
  
      Raises:
          ValueError if there is less than `size` data in `iterable`