code: def _unpack_obs(obs, space, tensorlib=tf):
      
  
      if (isinstance(space, gym.spaces.Dict)
              or isinstance(space, gym.spaces.Tuple)):
          prep = get_preprocessor(space)(space)
          if len(obs.shape) != 2 or obs.shape[1] != prep.shape[0]:
              raise ValueError(
                  "Expected flattened obs shape of [None, {}], got {}".format(
                      prep.shape[0], obs.shape))
          assert len(prep.preprocessors) == len(space.spaces), \
              (len(prep.preprocessors) == len(space.spaces))
          offset = 0
          if isinstance(space, gym.spaces.Tuple):
              u = []
              for p, v in zip(prep.preprocessors, space.spaces):
                  obs_slice = obs[:, offset:offset + p.size]
                  offset += p.size
                  u.append(
                      _unpack_obs(
                          tensorlib.reshape(obs_slice, [-1] + list(p.shape)),
                          v,
                          tensorlib=tensorlib))
          else:
              u = OrderedDict()
              for p, (k, v) in zip(prep.preprocessors, space.spaces.items()):
                  obs_slice = obs[:, offset:offset + p.size]
                  offset += p.size
                  u[k] = _unpack_obs(
                      tensorlib.reshape(obs_slice, [-1] + list(p.shape)),
                      v,
                      tensorlib=tensorlib)
          return u
      else:
          return obs
docs: Unpack a flattened Dict or Tuple observation array/tensor.
  
      Arguments:
          obs: The flattened observation tensor
          space: The original space prior to flattening
          tensorlib: The library used to unflatten (reshape) the array/tensor