class_docstr: Class for logging time progress against a goal.
class_docstr_tok: ["Class","for","logging","time","progress","against","a","goal","."]
docstr: Log report, time elapsed, and percentage progress towards goal.
  
  :param done: number of examples completed so far
  :param total: total number of elements to be completed. if total > 0,
                calculates the time remaining and percentage complete.
  :param report: dict of pairs to log
  
  :returns: tuple log string, log dict
      log string contains time elapsed and string representation of
      the log dict
      log dict contains pairs of all items to log, which includes
      percentage complete and projected time left if total > 0
docstr_tok: ["Log","report",",","time","elapsed",",","and","percentage","progress","towards","goal",".",":","param","done",":","number","of","examples","completed","so","far",":","param","total",":","total","number","of","elements","to","be","completed",".","if","total",">","0",",","calculates","the","time","remaining","and","percentage","complete",".",":","param","report",":","dict","of","pairs","to","log",":","returns",":","tuple","log","string",",","log","dict","log","string","contains","time","elapsed","and","string","representation","of","the","log","dict","log","dict","contains","pairs","of","all","items","to","log",",","which","includes","percentage","complete","and","projected","time","left","if","total",">","0"]
code: def log(self, done, total, report=None):
      """
      Log report, time elapsed, and percentage progress towards goal.
  
      :param done: number of examples completed so far
      :param total: total number of elements to be completed. if total > 0,
                    calculates the time remaining and percentage complete.
      :param report: dict of pairs to log
  
      :returns: tuple log string, log dict
          log string contains time elapsed and string representation of
          the log dict
          log dict contains pairs of all items to log, which includes
          percentage complete and projected time left if total > 0
      """
      from parlai.core.metrics import (
          Metric,
      )  # delay import to prevent circular dep
  
      if isinstance(done, Metric):
          done = done.value()
      self.tot_time += self.timer.time()
      self.timer.reset()
      if report:
          report["exs"] = done
      if total > 0 and done > 0:
          progress = done / total
          seconds_left = max(
              0, self.tot_time / progress - self.tot_time
          )
          eta = timedelta(seconds=int(seconds_left + 0.5))
      else:
          progress = 0
          eta = "unknown"
      elapsed = timedelta(seconds=int(self.tot_time))
  
      text = (
          f"{progress:.1%} complete ({done:,d} / {total:,d}), "
          f"{elapsed} elapsed, {eta} eta"
      )
      if report:
          report_s = nice_report(report)
          text = f"{text}\n{report_s}"
      return text, report
  
imports: from collections import deque, OrderedDict
  from typing import Union, Optional, Set, Any, Dict, List, Tuple
  from datetime import timedelta
  import functools
  import math
  import time
  import re
  import shutil
  import json
  import os
  from parlai.core.message import Message
  from parlai.utils.strings import colorize
  from parlai.utils.io import PathManager
  import parlai.utils.logging
label_desc: Use image node_id 4 for calling the TimeLogger obj's underlying member method code with example usage: obj.log(done, total, report) and returns: text,  report