code: def test_slices(self):
      # TEST #1: even split (50/50)
      episode = self._create_episode(100)
      self.assertTrue(episode.t == 100 and episode.t_started == 0)
  
      # Convert to numpy before splitting.
      episode.finalize()
  
      # Create two 50/50 episode chunks.
      e1 = episode[:50]
      self.assertTrue(e1.is_finalized)
      e2 = episode.slice(slice(50, None))
      self.assertTrue(e2.is_finalized)
  
      # Make sure, `e1` and `e2` make sense.
      self.assertTrue(len(e1) == 50)
      self.assertTrue(len(e2) == 50)
      self.assertTrue(e1.id_ == e2.id_)
      self.assertTrue(e1.t_started == 0)
      self.assertTrue(e1.t == 50)
      self.assertTrue(e2.t_started == 50)
      self.assertTrue(e2.t == 100)
      # Make sure the chunks are not identical, but last obs of `e1` matches
      # last obs of `e2`.
      check(e1.get_observations(-1), e2.get_observations(0))
      check(e1.observations[4], e2.observations[4], false=True)
      check(e1.observations[10], e2.observations[10], false=True)
  
      # TEST #2: Uneven split (33/66).
      episode = self._create_episode(99)
      self.assertTrue(episode.t == 99 and episode.t_started == 0)
  
      # Convert to numpy before splitting.
      episode.finalize()
  
      # Create two 50/50 episode chunks.
      e1 = episode.slice(slice(None, 33))
      self.assertTrue(e1.is_finalized)
      e2 = episode[33:]
      self.assertTrue(e2.is_finalized)
  
      # Make sure, `e1` and `e2` chunk make sense.
      self.assertTrue(len(e1) == 33)
      self.assertTrue(len(e2) == 66)
      self.assertTrue(e1.id_ == e2.id_)
      self.assertTrue(e1.t_started == 0)
      self.assertTrue(e1.t == 33)
      self.assertTrue(e2.t_started == 33)
      self.assertTrue(e2.t == 99)
      # Make sure the chunks are not identical, but last obs of `e1` matches
      # last obs of `e2`.
      check(e1.get_observations(-1), e2.get_observations(0))
      check(e1.observations[4], e2.observations[4], false=True)
      check(e1.observations[10], e2.observations[10], false=True)
  
      # TEST #3: Split with lookback buffer (buffer=10, split=20/30).
      len_lookback_buffer = 10
      episode = self._create_episode(
          num_data=60,
          t_started=15,
          len_lookback_buffer=len_lookback_buffer,
      )
      self.assertTrue(episode.t == 65 and episode.t_started == 15)
  
      # Convert to numpy before splitting.
      episode.finalize()
  
      # Create two 20/30 episode chunks.
      e1 = episode.slice(slice(None, 20))
      self.assertTrue(e1.is_finalized)
      e2 = episode[20:]
      self.assertTrue(e2.is_finalized)
  
      # Make sure, `e1` and `e2` make sense.
      self.assertTrue(len(e1) == 20)
      self.assertTrue(len(e2) == 30)
      self.assertTrue(e1.id_ == e2.id_)
      self.assertTrue(e1.t_started == 15)
      self.assertTrue(e1.t == 35)
      self.assertTrue(e2.t_started == 35)
      self.assertTrue(e2.t == 65)
      # Make sure the chunks are not identical, but last obs of `e1` matches
      # last obs of `e2`.
      check(e1.get_observations(-1), e2.get_observations(0))
      check(e1.observations[5], e2.observations[5], false=True)
      check(e1.observations[11], e2.observations[11], false=True)
      # Make sure the lookback buffers of both chunks are still working.
      check(
          e1.get_observations(-1, neg_indices_left_of_zero=True),
          episode.observations.data[len_lookback_buffer - 1],
      )
      check(
          e1.get_actions(-1, neg_indices_left_of_zero=True),
          episode.actions.data[len_lookback_buffer - 1],
      )
      check(
          e2.get_observations([-5, -2], neg_indices_left_of_zero=True),
          [
              episode.observations.data[20 + len_lookback_buffer - 5],
              episode.observations.data[20 + len_lookback_buffer - 2],
          ],
      )
      check(
          e2.get_rewards([-5, -2], neg_indices_left_of_zero=True),
          [
              episode.rewards.data[20 + len_lookback_buffer - 5],
              episode.rewards.data[20 + len_lookback_buffer - 2],
          ],
      )
  
imports: from collections import defaultdict
  from typing import Any, Dict, Optional, SupportsFloat, Tuple
  import unittest
  import gymnasium
  from gymnasium.core import ActType, ObsType
  import numpy
  from ray.rllib.env.single_agent_episode import SingleAgentEpisode
  from ray.rllib.utils.test_utils import check
label_desc: Use image node_id 5 for calling the TestSingelAgentEpisode obj's underlying member method code with example usage: obj.test_slices() without return types