class_docstr: This is just the gym environment, without extra functionality
class_docstr_tok: ["This","is","just","the","gym","environment",",","without","extra","functionality"]
code: def step(self, action):
      if isinstance(action, np.ndarray):
          action = action.item()
      assert (
          0 <= action and action <= self.num_arms
      ), f"out-of-bounds action {action}."
      reached_max_steps = self.num_steps >= self.max_steps
      self.num_steps += 1
  
      # idle action
      if action == self.num_arms:
          # simply return new state, without updating distributions
          # this is ideal when there aren't any legal actions, this
          # would generate a new batch of legal actions
          return self.state, IDLE_PENALTY, reached_max_steps, None
  
      # illegal action
      if action not in self.legal_indices:
          return self.state, INVALID_MOVE_PENALTY, True, None
  
      # update states for only the action selected
      prev = self.mus[action].item()
      self.mus[action] = prev + self.mu_changes[action]
      if self.mus[action] <= MU_LOW:
          self.legal_indices_mask[action] = 0
  
      reward = prev - self.mus[action].item()
      return self.state, reward, reached_max_steps, None
  
imports: import random
  import gym
  import numpy
  import reagent.core.types
  import torch
  from reagent.core.dataclasses import dataclass
  from reagent.core.parameters import NormalizationData, NormalizationKey
  from reagent.gym.envs.env_wrapper import EnvWrapper
  from reagent.gym.normalizers import only_continuous_normalizer
label_desc: Use image node_id 2 for calling the ChangingArmsEnv obj's underlying member method code with example usage: obj.step(action) and returns: self,  reward,  reached_max_steps,  None, self,  IDLE_PENALTY,  reached_max_steps,  None, self,  INVALID_MOVE_PENALTY,  True,  None