class_docstr: Object that is responsible for evaluating a given agent.
  
  Args:
      agent (Agent): Agent to evaluate.
      env (Env): Env to evaluate the agent on.
      n_steps (int): Number of timesteps used in each evaluation.
      n_episodes (int): Number of episodes used in each evaluation.
      eval_interval (int): Interval of evaluations in steps.
      outdir (str): Path to a directory to save things.
      max_episode_len (int): Maximum length of episodes used in evaluations.
      step_offset (int): Offset of steps used to schedule evaluations.
      save_best_so_far_agent (bool): If set to True, after each evaluation,
          if the score (= mean of returns in evaluation episodes) exceeds
          the best-so-far score, the current agent is saved.
class_docstr_tok: ["Object","that","is","responsible","for","evaluating","a","given","agent",".","Args",":","agent","(","Agent",")",":","Agent","to","evaluate",".","env","(","Env",")",":","Env","to","evaluate","the","agent","on",".","n_steps","(","int",")",":","Number","of","timesteps","used","in","each","evaluation",".","n_episodes","(","int",")",":","Number","of","episodes","used","in","each","evaluation",".","eval_interval","(","int",")",":","Interval","of","evaluations","in","steps",".","outdir","(","str",")",":","Path","to","a","directory","to","save","things",".","max_episode_len","(","int",")",":","Maximum","length","of","episodes","used","in","evaluations",".","step_offset","(","int",")",":","Offset","of","steps","used","to","schedule","evaluations",".","save_best_so_far_agent","(","bool",")",":","If","set","to","True",",","after","each","evaluation",",","if","the","score","(","=","mean","of","returns","in","evaluation","episodes",")","exceeds","the","best-so-far","score",",","the","current","agent","is","saved","."]
code: def __init__(
      self,
      agent,
      env,
      n_steps,
      n_episodes,
      eval_interval,
      outdir,
      max_episode_len=None,
      step_offset=0,
      save_best_so_far_agent=True,
      logger=None,
  ):
      assert (n_steps is None) != (n_episodes is None), (
          "One of n_steps or n_episodes must be None. "
          + "Either we evaluate for a specified number "
          + "of episodes or for a specified number of timesteps."
      )
      self.agent = agent
      self.env = env
      self.max_score = np.finfo(np.float32).min
      self.start_time = time.time()
      self.n_steps = n_steps
      self.n_episodes = n_episodes
      self.eval_interval = eval_interval
      self.outdir = outdir
      self.max_episode_len = max_episode_len
      self.step_offset = step_offset
      self.prev_eval_t = (
          self.step_offset - self.step_offset % self.eval_interval
      )
      self.save_best_so_far_agent = save_best_so_far_agent
      self.logger = logger or logging.getLogger(__name__)
  
      # Write a header line first
      with open(os.path.join(self.outdir, "scores.txt"), "w") as f:
          custom_columns = tuple(
              t[0] for t in self.agent.get_statistics()
          )
          column_names = _basic_columns + custom_columns
          print("\t".join(column_names), file=f)
  
imports: import logging
  import multiprocessing
  import os
  import statistics
  import time
  import numpy
  import chainerrl
label_desc: Use image node_id 1 to create a new Evaluator object from inherited base classes: object with example: obj = Evaluator(agent, env, n_steps, n_episodes, eval_interval, outdir, max_episode_len, step_offset, save_best_so_far_agent, logger)