<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def run_defenses(self):
 """Method which evaluates all defense work. In a loop this method queries not completed defense work, picks one defense work and runs it. """

    logging.info('******** Start evaluation of defenses ********')
    prev_submission_id = None
    need_reload_work = True
    while True:
      # wait until work is available
      if need_reload_work:
        if self.num_defense_shards:
          shard_with_work = self.defense_work.read_undone_from_datastore(
              shard_id=(self.worker_id % self.num_defense_shards),
              num_shards=self.num_defense_shards)
        else:
          shard_with_work = self.defense_work.read_undone_from_datastore()
        logging.info('Loaded %d records of undone work from shard %s',
                     len(self.defense_work), str(shard_with_work))
      if not self.defense_work.work:
        logging.info('Work is not populated, waiting...')
        time.sleep(SLEEP_TIME)
        continue
      if self.defense_work.is_all_work_competed():
        logging.info('All defense work completed.')
        break
      # download all defense data and dataset
      self.fetch_defense_data()
      need_reload_work = False
      # pick piece of work
      work_id = self.defense_work.try_pick_piece_of_work(
          self.worker_id, submission_id=prev_submission_id)
      if not work_id:
        need_reload_work = True
        logging.info('Failed to pick work, waiting...')
        time.sleep(SLEEP_TIME_SHORT)
        continue
      logging.info('Selected work_id: %s', work_id)
      # execute work
      try:
        elapsed_time_sec, prev_submission_id, batch_result = (
            self.run_defense_work(work_id))
        logging.info('Work %s is done', work_id)
        # indicate that work is completed
        is_work_update = self.defense_work.update_work_as_completed(
            self.worker_id, work_id,
            other_values={'elapsed_time': elapsed_time_sec,
                          'stat_correct': batch_result[0],
                          'stat_error': batch_result[1],
                          'stat_target_class': batch_result[2],
                          'stat_num_images': batch_result[3]})
      except WorkerError as e:
        logging.info('Failed to run work:\n%s', str(e))
        if str(e).startswith('Docker returned non-zero retval'):
          logging.info('Running nvidia-docker to ensure that GPU works')
          shell_call(['nvidia-docker', 'run', '--rm', 'nvidia/cuda',
                      'nvidia-smi'])
        is_work_update = self.defense_work.update_work_as_completed(
            self.worker_id, work_id, error=str(e))
      if not is_work_update:
        logging.warning('Can''t update work "%s" as completed by worker %d',
                        work_id, self.worker_id)
        need_reload_work = True
    logging.info('******** Finished evaluation of defenses ********')