code: def sample(self, batch_size, beta):
          
          assert beta > 0
  
          idxes = self._sample_proportional(batch_size)
  
          weights = []
          p_min = self._it_min.min() / self._it_sum.sum()
          max_weight = (p_min * len(self._storage)) ** (-beta)
  
          for idx in idxes:
              p_sample = self._it_sum[idx] / self._it_sum.sum()
              weight = (p_sample * len(self._storage)) ** (-beta)
              weights.append(weight / max_weight)
          weights = np.array(weights)
          encoded_sample = self._encode_sample(idxes)
          return tuple(list(encoded_sample) + [weights, idxes])
docs: Sample a batch of experiences.
  
          compared to ReplayBuffer.sample
          it also returns importance weights and idxes
          of sampled experiences.
  
  
          Parameters
          ----------
          batch_size: int
              How many transitions to sample.
          beta: float
              To what degree to use importance weights
              (0 - no corrections, 1 - full correction)
  
          Returns
          -------
          obs_batch: np.array
              batch of observations
          act_batch: np.array
              batch of actions executed given obs_batch
          rew_batch: np.array
              rewards received as results of executing act_batch
          next_obs_batch: np.array
              next set of observations seen after executing act_batch
          done_mask: np.array
              done_mask[i] = 1 if executing act_batch[i] resulted in
              the end of an episode and 0 otherwise.
          weights: np.array
              Array of shape (batch_size,) and dtype np.float32
              denoting importance weight of each sampled transition
          idxes: np.array
              Array of shape (batch_size,) and dtype np.int32
              idexes in buffer of sampled experiences