code: def update_episode_statistics(self, episode):
      episode_discounted_returns = []
      for i in range(episode.length()):
          transition = episode.get_transition(i)
          episode_discounted_returns.append(
              transition.n_step_discounted_rewards
          )
          self.num_episodes_where_step_has_been_seen[i] += 1
          self.mean_return_over_multiple_episodes[i] -= (
              self.mean_return_over_multiple_episodes[i]
              / self.num_episodes_where_step_has_been_seen[i]
          )
          self.mean_return_over_multiple_episodes[i] += (
              transition.n_step_discounted_rewards
              / self.num_episodes_where_step_has_been_seen[i]
          )
      self.mean_discounted_return = np.mean(episode_discounted_returns)
      self.std_discounted_return = np.std(episode_discounted_returns)
  
file_path: coach/rl_coach/agents/policy_optimization_agent.py
imports: from collections import OrderedDict
  from enum import Enum
  from typing import Union
  import numpy
  from rl_coach.agents.agent import Agent
  from rl_coach.core_types import Batch, ActionInfo
  from rl_coach.logger import screen
  from rl_coach.spaces import DiscreteActionSpace, BoxActionSpace
  from rl_coach.utils import eps
label_desc: Use image node_id 3 for calling the PolicyOptimizationAgent obj's underlying member method code with example usage: obj.update_episode_statistics(episode) without return types