'Get a random batch of data from the specified bucket, prepare for step.
To feed data in step(..) it must be a list of batch-major vectors, while
data here contains single length-major cases. So the main logic of this
function is to re-index data cases to be in the proper format for feeding.
Args:
data: a tuple of size len(self.buckets) in which each element contains
lists of pairs of input and output data that we use to create a batch.
bucket_id: integer, which bucket to get the batch for.
Returns:
The triple (encoder_inputs, decoder_inputs, target_weights) for
the constructed batch that has the proper format to call step(...) later.'

def get_batch(self, data, bucket_id):

    (encoder_size, decoder_size) = self.buckets[bucket_id]
    (encoder_inputs, decoder_inputs) = ([], [])
    for _ in xrange(self.batch_size):
        (encoder_input, decoder_input) = random.choice(data[bucket_id])
        encoder_pad = ([data_utils.PAD_ID] * (encoder_size - len(encoder_input)))
        encoder_inputs.append(list(reversed((encoder_input + encoder_pad))))
        decoder_pad_size = ((decoder_size - len(decoder_input)) - 1)
        decoder_inputs.append((([data_utils.GO_ID] + decoder_input) + ([data_utils.PAD_ID] * decoder_pad_size)))
    (batch_encoder_inputs, batch_decoder_inputs, batch_weights) = ([], [], [])
    for length_idx in xrange(encoder_size):
        batch_encoder_inputs.append(np.array([encoder_inputs[batch_idx][length_idx] for batch_idx in xrange(self.batch_size)], dtype=np.int32))
    for length_idx in xrange(decoder_size):
        batch_decoder_inputs.append(np.array([decoder_inputs[batch_idx][length_idx] for batch_idx in xrange(self.batch_size)], dtype=np.int32))
        batch_weight = np.ones(self.batch_size, dtype=np.float32)
        for batch_idx in xrange(self.batch_size):
            if (length_idx < (decoder_size - 1)):
                target = decoder_inputs[batch_idx][(length_idx + 1)]
            if ((length_idx == (decoder_size - 1)) or (target == data_utils.PAD_ID)):
                batch_weight[batch_idx] = 0.0
        batch_weights.append(batch_weight)
    return (batch_encoder_inputs, batch_decoder_inputs, batch_weights)
