def __init__(self, *, complete: Optional[bool]=True, rollout_info=None, data_format: Optional[str]=None, done: Optional[np.ndarray]=None, continuous: Optional[bool]=True, rollout_bounds=None, rewards: Sequence, observations: Sequence, actions: Sequence, **data):
    "\n        Constructor\n\n        :param complete: `False` if the rollout is incomplete, i.e. as part of a mini-batch\n        :param rollout_info: data staying constant through the whole episode\n        :param data_format: 'torch' to use Tensors, 'numpy' to use ndarrays.\n                             Will use Tensors if any data argument does, else ndarrays\n        :param done: boolean ndarray, specifying for each step whether it led to termination.\n                     The last step of continuous rollouts, i.e. not mini-batches, is done if `complete` is `True`.\n        :param continuous: true if the steps form one continuous sequence.\n        :param rewards: sequence of reward values, determines sequence length\n        :param observations: sequence of observation values, the length must be `len(rewards) + 1`\n        :param actions: sequence of action values, the length must be `len(rewards)`\n        :param data: additional data lists, their length must be `len(rewards)` or `len(rewards) + 1`\n        "
    self.length = len(rewards)
    if (self.length == 0):
        raise pyrado.ShapeErr(msg='StepSequence cannot be empty!')
    self.rollout_info = rollout_info
    self.continuous = continuous
    if (data_format is None):
        for value in data.values():
            if (isinstance(value, to.Tensor) or (isinstance(value, list) and isinstance(value[0], to.Tensor))):
                data_format = 'torch'
                break
        else:
            data_format = 'numpy'
    self._data_format = data_format
    missing_fields = (StepSequence.required_fields - data.keys())
    if missing_fields:
        raise ValueError(f'Missing required data fields: {missing_fields}')
    self._data_names = []
    self.add_data('rewards', rewards)
    self.add_data('observations', observations)
    self.add_data('actions', actions)
    for (name, value) in data.items():
        self.add_data(name, value)
    if (done is None):
        done = np.zeros(self.length, dtype=np.bool)
        if (complete and continuous):
            done[(- 1)] = True
    else:
        done = np.asarray(done, dtype=np.bool)
        assert (done.shape[0] == self.length)
    self.done = done
    if continuous:
        if (rollout_bounds is None):
            rollout_bounds = [0]
            rollout_bounds.extend((np.flatnonzero(done) + 1))
            if (not done[(- 1)]):
                rollout_bounds.append(self.length)
        else:
            for i in range((len(rollout_bounds) - 1)):
                assert (rollout_bounds[i] < rollout_bounds[(i + 1)])
            assert (rollout_bounds[0] == 0)
            assert (rollout_bounds[(- 1)] == self.length)
        self._rollout_bounds = np.array(rollout_bounds)
    else:
        self._rollout_bounds = None
Constructor

:param complete: `False` if the rollout is incomplete, i.e. as part of a mini-batch
:param rollout_info: data staying constant through the whole episode
:param data_format: 'torch' to use Tensors, 'numpy' to use ndarrays.
                     Will use Tensors if any data argument does, else ndarrays
:param done: boolean ndarray, specifying for each step whether it led to termination.
             The last step of continuous rollouts, i.e. not mini-batches, is done if `complete` is `True`.
:param continuous: true if the steps form one continuous sequence.
:param rewards: sequence of reward values, determines sequence length
:param observations: sequence of observation values, the length must be `len(rewards) + 1`
:param actions: sequence of action values, the length must be `len(rewards)`
:param data: additional data lists, their length must be `len(rewards)` or `len(rewards) + 1`
def __init__(self, *, complete: Optional[bool]=True, rollout_info=None, data_format: Optional[str]=None, done: Optional[np.ndarray]=None, continuous: Optional[bool]=True, rollout_bounds=None, rewards: Sequence, observations: Sequence, actions: Sequence, **data):
    "\n        Constructor\n\n        :param complete: `False` if the rollout is incomplete, i.e. as part of a mini-batch\n        :param rollout_info: data staying constant through the whole episode\n        :param data_format: 'torch' to use Tensors, 'numpy' to use ndarrays.\n                             Will use Tensors if any data argument does, else ndarrays\n        :param done: boolean ndarray, specifying for each step whether it led to termination.\n                     The last step of continuous rollouts, i.e. not mini-batches, is done if `complete` is `True`.\n        :param continuous: true if the steps form one continuous sequence.\n        :param rewards: sequence of reward values, determines sequence length\n        :param observations: sequence of observation values, the length must be `len(rewards) + 1`\n        :param actions: sequence of action values, the length must be `len(rewards)`\n        :param data: additional data lists, their length must be `len(rewards)` or `len(rewards) + 1`\n        "
    self.length = len(rewards)
    if (self.length == 0):
        raise pyrado.ShapeErr(msg='StepSequence cannot be empty!')
    self.rollout_info = rollout_info
    self.continuous = continuous
    if (data_format is None):
        for value in data.values():
            if (isinstance(value, to.Tensor) or (isinstance(value, list) and isinstance(value[0], to.Tensor))):
                data_format = 'torch'
                break
        else:
            data_format = 'numpy'
    self._data_format = data_format
    missing_fields = (StepSequence.required_fields - data.keys())
    if missing_fields:
        raise ValueError(f'Missing required data fields: {missing_fields}')
    self._data_names = []
    self.add_data('rewards', rewards)
    self.add_data('observations', observations)
    self.add_data('actions', actions)
    for (name, value) in data.items():
        self.add_data(name, value)
    if (done is None):
        done = np.zeros(self.length, dtype=np.bool)
        if (complete and continuous):
            done[(- 1)] = True
    else:
        done = np.asarray(done, dtype=np.bool)
        assert (done.shape[0] == self.length)
    self.done = done
    if continuous:
        if (rollout_bounds is None):
            rollout_bounds = [0]
            rollout_bounds.extend((np.flatnonzero(done) + 1))
            if (not done[(- 1)]):
                rollout_bounds.append(self.length)
        else:
            for i in range((len(rollout_bounds) - 1)):
                assert (rollout_bounds[i] < rollout_bounds[(i + 1)])
            assert (rollout_bounds[0] == 0)
            assert (rollout_bounds[(- 1)] == self.length)
        self._rollout_bounds = np.array(rollout_bounds)
    else:
        self._rollout_bounds = None