class_docstr: A simple RL environment loop.
  
  This takes `Environment` and `Actor` instances and coordinates their
  interaction. Agent is updated if `should_update=True`. This can be used as:
  
    loop = EnvironmentLoop(environment, actor)
    loop.run(num_episodes)
  
  A `Counter` instance can optionally be given in order to maintain counts
  between different Acme components. If not given a local Counter will be
  created to maintain counts between calls to the `run` method.
  
  A `Logger` instance can also be passed in order to control the output of the
  loop. If not given a platform-specific default logger will be used as defined
  by utils.loggers.make_default_logger. A string `label` can be passed to easily
  change the label associated with the default logger; this is ignored if a
  `Logger` instance is given.
  
  A list of 'Observer' instances can be specified to generate additional metrics
  to be logged by the logger. They have access to the 'Environment' instance,
  the current timestep datastruct and the current action.
class_docstr_tok: ["A","simple","RL","environment","loop",".","This","takes","`","Environment","`","and","`","Actor","`","instances","and","coordinates","their","interaction",".","Agent","is","updated","if","`","should_update=True","`",".","This","can","be","used","as",":","loop","=","EnvironmentLoop","(","environment",",","actor",")","loop.run","(","num_episodes",")","A","`","Counter","`","instance","can","optionally","be","given","in","order","to","maintain","counts","between","different","Acme","components",".","If","not","given","a","local","Counter","will","be","created","to","maintain","counts","between","calls","to","the","`","run","`","method",".","A","`","Logger","`","instance","can","also","be","passed","in","order","to","control","the","output","of","the","loop",".","If","not","given","a","platform-specific","default","logger","will","be","used","as","defined","by","utils.loggers.make_default_logger",".","A","string","`","label","`","can","be","passed","to","easily","change","the","label","associated","with","the","default","logger",";","this","is","ignored","if","a","`","Logger","`","instance","is","given",".","A","list","of","'Observer","'","instances","can","be","specified","to","generate","additional","metrics","to","be","logged","by","the","logger",".","They","have","access","to","the","'Environment","'","instance",",","the","current","timestep","datastruct","and","the","current","action","."]
docstr: Perform the run loop.
  
  Run the environment loop either for `num_episodes` episodes or for at
  least `num_steps` steps (the last episode is always run until completion,
  so the total number of steps may be slightly more than `num_steps`).
  At least one of these two arguments has to be None.
  
  Upon termination of an episode a new episode will be started. If the number
  of episodes and the number of steps are not given then this will interact
  with the environment infinitely.
  
  Args:
    num_episodes: number of episodes to run the loop for.
    num_steps: minimal number of steps to run the loop for.
  
  Returns:
    Actual number of steps the loop executed.
  
  Raises:
    ValueError: If both 'num_episodes' and 'num_steps' are not None.
docstr_tok: ["Perform","the","run","loop",".","Run","the","environment","loop","either","for","`","num_episodes","`","episodes","or","for","at","least","`","num_steps","`","steps","(","the","last","episode","is","always","run","until","completion",",","so","the","total","number","of","steps","may","be","slightly","more","than","`","num_steps","`",")",".","At","least","one","of","these","two","arguments","has","to","be","None",".","Upon","termination","of","an","episode","a","new","episode","will","be","started",".","If","the","number","of","episodes","and","the","number","of","steps","are","not","given","then","this","will","interact","with","the","environment","infinitely",".","Args",":","num_episodes",":","number","of","episodes","to","run","the","loop","for",".","num_steps",":","minimal","number","of","steps","to","run","the","loop","for",".","Returns",":","Actual","number","of","steps","the","loop","executed",".","Raises",":","ValueError",":","If","both","'num_episodes","'","and","'num_steps","'","are","not","None","."]
code: def run(
      self,
      num_episodes: Optional[int] = None,
      num_steps: Optional[int] = None,
  ) -> int:
      """Perform the run loop.
  
      Run the environment loop either for `num_episodes` episodes or for at
      least `num_steps` steps (the last episode is always run until completion,
      so the total number of steps may be slightly more than `num_steps`).
      At least one of these two arguments has to be None.
  
      Upon termination of an episode a new episode will be started. If the number
      of episodes and the number of steps are not given then this will interact
      with the environment infinitely.
  
      Args:
        num_episodes: number of episodes to run the loop for.
        num_steps: minimal number of steps to run the loop for.
  
      Returns:
        Actual number of steps the loop executed.
  
      Raises:
        ValueError: If both 'num_episodes' and 'num_steps' are not None.
      """
  
      if not (num_episodes is None or num_steps is None):
          raise ValueError(
              'Either "num_episodes" or "num_steps" should be None.'
          )
  
      def should_terminate(episode_count: int, step_count: int) -> bool:
          return (
              num_episodes is not None and episode_count >= num_episodes
          ) or (num_steps is not None and step_count >= num_steps)
  
      episode_count: int = 0
      step_count: int = 0
      with signals.runtime_terminator():
          while not should_terminate(episode_count, step_count):
              episode_start = time.time()
              result = self.run_episode()
              result = {
                  **result,
                  **{"episode_duration": time.time() - episode_start},
              }
              episode_count += 1
              step_count += int(result["episode_length"])
              # Log the given episode results.
              self._logger.write(result)
  
      return step_count
  
file_path: acme/acme/environment_loop.py
imports: import operator
  import time
  from typing import List, Optional, Sequence
  from acme import core
  from acme.utils import counting
  from acme.utils import loggers
  from acme.utils import observers
  from acme.utils import signals
  import dm_env
  from dm_env import specs
  import numpy
  import tree
label_desc: Use image node_id 3 for calling the EnvironmentLoop obj's underlying member method code with example usage: obj.run(num_episodes, num_steps) and returns: step_count, unknown