code: def on_train_result(self, *, algorithm, result, **kwargs):
      # Make sure we always run exactly the given evaluation duration,
      # no matter what the other settings are (such as
      # `evaluation_num_workers` or `evaluation_parallel_to_training`).
      if (
          "evaluation" in result
          and "hist_stats" in result["evaluation"]
      ):
          hist_stats = result["evaluation"]["hist_stats"]
          # We count in episodes.
          if algorithm.config.evaluation_duration_unit == "episodes":
              num_episodes_done = len(hist_stats["episode_lengths"])
              # Compare number of entries in episode_lengths (this is the
              # number of episodes actually run) with desired number of
              # episodes from the config.
              if isinstance(algorithm.config.evaluation_duration, int):
                  assert (
                      num_episodes_done
                      == algorithm.config.evaluation_duration
                  )
              # If auto-episodes: Expect at least as many episode as workers
              # (each worker's `sample()` is at least called once).
              else:
                  assert algorithm.config.evaluation_duration == "auto"
                  assert (
                      num_episodes_done
                      >= algorithm.config.evaluation_num_workers
                  )
              print(
                  "Number of run evaluation episodes: "
                  f"{num_episodes_done} (ok)!"
              )
          # We count in timesteps.
          else:
              num_timesteps_reported = result["evaluation"][
                  "timesteps_this_iter"
              ]
              num_timesteps_wanted = (
                  algorithm.config.evaluation_duration
              )
              if num_timesteps_wanted != "auto":
                  delta = num_timesteps_wanted - num_timesteps_reported
                  # Expect roughly the same (desired // num-eval-workers).
                  assert abs(delta) < 20, (
                      delta,
                      num_timesteps_wanted,
                      num_timesteps_reported,
                  )
              print(
                  "Number of run evaluation timesteps: "
                  f"{num_timesteps_reported} (ok)!"
              )
  
          print(f"R={result['evaluation']['episode_reward_mean']}")
  
file_path: ray/python/ray/rllib/examples/parallel_evaluation_and_training.py
imports: import argparse
  import os
  from ray.rllib.algorithms.callbacks import DefaultCallbacks
  from ray.rllib.utils.test_utils import check_learning_achieved
  from ray.tune.registry import get_trainable_cls
label_desc: Use image node_id 1 for calling the AssertEvalCallback obj's underlying member method code with example usage: obj.on_train_result() without return types