class_docstr: Class which encapsulates logit of the master.
docstr: Saves statistics about each submission.
  
  Saved statistics include score; number of completed and failed batches;
  min, max, average and median time needed to run one batch.
  
  Args:
    run_stats: dictionary with runtime statistics for submissions,
      can be generated by WorkPiecesBase.compute_work_statistics
    scores: dictionary mapping submission ids to scores
    num_processed_images: dictionary with number of successfully processed
      images by each submission, one of the outputs of
      ClassificationBatches.compute_classification_results
    filename: output filename
code: def _save_work_results(
      self, run_stats, scores, num_processed_images, filename
  ):
      """Saves statistics about each submission.
  
      Saved statistics include score; number of completed and failed batches;
      min, max, average and median time needed to run one batch.
  
      Args:
        run_stats: dictionary with runtime statistics for submissions,
          can be generated by WorkPiecesBase.compute_work_statistics
        scores: dictionary mapping submission ids to scores
        num_processed_images: dictionary with number of successfully processed
          images by each submission, one of the outputs of
          ClassificationBatches.compute_classification_results
        filename: output filename
      """
      with open(filename, "w") as f:
          writer = csv.writer(f)
          writer.writerow(
              [
                  "SubmissionID",
                  "ExternalSubmissionId",
                  "Score",
                  "CompletedBatches",
                  "BatchesWithError",
                  "ProcessedImages",
                  "MinEvalTime",
                  "MaxEvalTime",
                  "MedianEvalTime",
                  "MeanEvalTime",
                  "ErrorMsg",
              ]
          )
          for submission_id in sorted(iterkeys(run_stats)):
              stat = run_stats.get(
                  submission_id,
                  collections.defaultdict(lambda: float("NaN")),
              )
              external_id = self.submissions.get_external_id(
                  submission_id
              )
              error_msg = ""
              while not error_msg and stat["error_messages"]:
                  error_msg = stat["error_messages"].pop()
                  if error_msg.startswith(
                      "Cant copy adversarial batch locally"
                  ):
                      error_msg = ""
              writer.writerow(
                  [
                      submission_id,
                      external_id,
                      scores.get(submission_id, None),
                      stat["completed"],
                      stat["num_errors"],
                      num_processed_images.get(submission_id, None),
                      stat["min_eval_time"],
                      stat["max_eval_time"],
                      stat["median_eval_time"],
                      stat["mean_eval_time"],
                      error_msg,
                  ]
              )
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import argparse
  import collections
  from collections import defaultdict
  import csv
  from io import BytesIO
  import logging
  import os
  import pickle
  import random
  import time
  from six import iteritems
  from six import iterkeys
  from six import itervalues
  from six.moves import input
  import eval_lib
label_desc: Use image node_id 5 for calling the EvaluationMaster obj's underlying member method code with example usage: obj._save_work_results(run_stats, scores, num_processed_images, filename) without return types