code: def run_simulation(
      self,
      vw,
      num_iterations,
      users,
      times_of_day,
      actions,
      cost_function,
      do_learn=True,
      shift=1,
  ):
      for i in range(shift, shift + num_iterations):
          # 1. In each simulation choose a user
          user = self.choose_user(users)
          # 2. Choose time of day for a given user
          time_of_day = self.choose_time_of_day(times_of_day)
  
          # 3. Pass context to vw to get an action
          context = {"user": user, "time_of_day": time_of_day}
          action, prob = self.get_action(vw, context, actions)
  
          # 4. Get cost of the action we chose
          cost = cost_function(context, action)
          self.cost_sum += cost
  
          if do_learn:
              # 5. Inform VW of what happened so we can learn from it
              # if (cost == 0):
              #     print(actions.index(action))
              vw_format = vw.parse(
                  self.to_vw_example_format(
                      context, actions, (action, cost, prob)
                  ),
                  vowpalwabbit.LabelType.CONTEXTUAL_BANDIT,
              )
              # 6. Learn
              vw.learn(vw_format)
              # 7. Let VW know you're done with these objects
              vw.finish_example(vw_format)
  
          # We negate this so that on the plot instead of minimizing cost, we are maximizing reward
          self.ctr.append(-1 * self.cost_sum / i)
  
          if self.has_automl and i % 1 == 0:
              metrics = vw.get_learner_metrics()
              self.process_metrics(i, metrics)
  
      return self.ctr
  
imports: import vowpalwabbit
  from distributionally_robust_data import OnlineCressieRead
  import collections
  import os
  import random
  import os
label_desc: Use image node_id 9 for calling the Simulator obj's underlying member method code with example usage: obj.run_simulation(vw, num_iterations, users, times_of_day, actions, cost_function, do_learn, shift) and returns: self