Learn on the current dataset, either for many timesteps and even
        episodes (batchMode = True) or for a single timestep
        (batchMode = False). Batch mode is possible, because Q-Learning is an
        off-policy method.

        In batchMode, the algorithm goes through all the samples in the history
        and performs an update on each of them. if batchMode is False, only the
        last data sample is considered. The user himself has to make sure to
        keep the dataset consistent with the agent's history.

def learn(self):
        """ Learn on the current dataset, either for many timesteps and even
        episodes (batchMode = True) or for a single timestep
        (batchMode = False). Batch mode is possible, because Q-Learning is an
        off-policy method.

        In batchMode, the algorithm goes through all the samples in the history
        and performs an update on each of them. if batchMode is False, only the
        last data sample is considered. The user himself has to make sure to
        keep the dataset consistent with the agent's history.
        """
        if self.batchMode:
            samples = self.dataset
        else:
            samples = [[self.dataset.getSample()]]

        for seq in samples:
            for lastState, lastAction, reward in seq:
                self._updatePropensities(int(lastState), int(lastAction), reward)