prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  tqm_logger: metric_names is currently not optional 
  Hi,
  
  https://github.com/pytorch/ignite/blob/master/ignite/contrib/handlers/tqdm_logger.py#L75
  This line should be modified to make `metric_names` optional. Here is a suggestion:
  ```
  if metric_names is not None and not isinstance(metric_names, list):
      raise TypeError("metric_names should be a list, got {} instead".format(type(metric_names)))
  ```
  
  Thanks
  
  </issue>
  <code>
  [start of ignite/contrib/handlers/tqdm_logger.py]
  1 try:
  2     from tqdm import tqdm
  3 except ImportError:
  4     raise RuntimeError("This contrib module requires tqdm to be installed")
  5 
  6 from ignite.engine import Events
  7 
  8 
  9 class ProgressBar:
  10     """
  11     TQDM progress bar handler to log training progress and computed metrics.
  12 
  13     Examples:
  14 
  15         Create a progress bar that shows you some metrics as they are computed,
  16         by simply attaching the progress bar object to your engine.
  17 
  18         .. code-block:: python
  19 
  20             pbar = ProgressBar()
  21             pbar.attach(trainer, ['loss'])
  22 
  23     Note:
  24         When adding attaching the progress bar to an engine, it is recommend that you replace
  25         every print operation in the engine's handlers triggered every iteration with
  26         ``pbar.log_message`` to guarantee the correct format of the stdout.
  27     """
  28 
  29     def __init__(self):
  30         self.pbar = None
  31 
  32     def _reset(self, engine):
  33         self.pbar = tqdm(
  34             total=len(engine.state.dataloader),
  35             leave=False,
  36             bar_format='{desc}[{n_fmt}/{total_fmt}] {percentage:3.0f}%|{bar}{postfix} [{elapsed}<{remaining}]')
  37 
  38     def _close(self, engine):
  39         self.pbar.close()
  40         self.pbar = None
  41 
  42     def _update(self, engine, metric_names=None):
  43         if self.pbar is None:
  44             self._reset(engine)
  45 
  46         self.pbar.set_description('Epoch {}'.format(engine.state.epoch))
  47 
  48         if metric_names is not None:
  49             if not all(metric in engine.state.metrics for metric in metric_names):
  50                 raise KeyError("metrics not found in engine.state.metrics")
  51 
  52             metrics = {name: '{:.2e}'.format(engine.state.metrics[name]) for name in metric_names}
  53             self.pbar.set_postfix(**metrics)
  54 
  55         self.pbar.update()
  56 
  57     @staticmethod
  58     def log_message(message):
  59         """
  60         Logs a message, preserving the progress bar correct output format
  61 
  62         Args:
  63             message (str): string you wish to log
  64         """
  65         tqdm.write(message)
  66 
  67     def attach(self, engine, metric_names=None):
  68         """
  69         Attaches the progress bar to an engine object
  70 
  71         Args:
  72             engine (Engine): engine object
  73             metric_names (list): (Optional) list of the metrics names to log as the bar progresses
  74         """
  75         if not isinstance(metric_names, list):
  76             raise TypeError("metric_names should be a list, got {} instead".format(type(metric_names)))
  77 
  78         engine.add_event_handler(Events.EPOCH_COMPLETED, self._close)
  79         engine.add_event_handler(Events.ITERATION_COMPLETED, self._update, metric_names)
  80
  [end of ignite/contrib/handlers/tqdm_logger.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/ignite/contrib/handlers/tqdm_logger.py b/ignite/contrib/handlers/tqdm_logger.py
  --- a/ignite/contrib/handlers/tqdm_logger.py
  +++ b/ignite/contrib/handlers/tqdm_logger.py
  @@ -47,6 +47,7 @@
   
           if metric_names is not None:
               if not all(metric in engine.state.metrics for metric in metric_names):
  +                self._close(engine)
                   raise KeyError("metrics not found in engine.state.metrics")
   
               metrics = {name: '{:.2e}'.format(engine.state.metrics[name]) for name in metric_names}
  @@ -72,7 +73,7 @@
               engine (Engine): engine object
               metric_names (list): (Optional) list of the metrics names to log as the bar progresses
           """
  -        if not isinstance(metric_names, list):
  +        if metric_names is not None and not isinstance(metric_names, list):
               raise TypeError("metric_names should be a list, got {} instead".format(type(metric_names)))
   
           engine.add_event_handler(Events.EPOCH_COMPLETED, self._close)
  
verification_info: {"golden_diff": "diff --git a/ignite/contrib/handlers/tqdm_logger.py b/ignite/contrib/handlers/tqdm_logger.py\n--- a/ignite/contrib/handlers/tqdm_logger.py\n+++ b/ignite/contrib/handlers/tqdm_logger.py\n@@ -47,6 +47,7 @@\n \n         if metric_names is not None:\n             if not all(metric in engine.state.metrics for metric in metric_names):\n+                self._close(engine)\n                 raise KeyError(\"metrics not found in engine.state.metrics\")\n \n             metrics = {name: '{:.2e}'.format(engine.state.metrics[name]) for name in metric_names}\n@@ -72,7 +73,7 @@\n             engine (Engine): engine object\n             metric_names (list): (Optional) list of the metrics names to log as the bar progresses\n         \"\"\"\n-        if not isinstance(metric_names, list):\n+        if metric_names is not None and not isinstance(metric_names, list):\n             raise TypeError(\"metric_names should be a list, got {} instead\".format(type(metric_names)))\n \n         engine.add_event_handler(Events.EPOCH_COMPLETED, self._close)\n", "issue": "tqm_logger: metric_names is currently not optional \nHi,\r\n\r\nhttps://github.com/pytorch/ignite/blob/master/ignite/contrib/handlers/tqdm_logger.py#L75\r\nThis line should be modified to make `metric_names` optional. Here is a suggestion:\r\n```\r\nif metric_names is not None and not isinstance(metric_names, list):\r\n    raise TypeError(\"metric_names should be a list, got {} instead\".format(type(metric_names)))\r\n```\r\n\r\nThanks\n", "before_files": [{"content": "try:\n    from tqdm import tqdm\nexcept ImportError:\n    raise RuntimeError(\"This contrib module requires tqdm to be installed\")\n\nfrom ignite.engine import Events\n\n\nclass ProgressBar:\n    \"\"\"\n    TQDM progress bar handler to log training progress and computed metrics.\n\n    Examples:\n\n        Create a progress bar that shows you some metrics as they are computed,\n        by simply attaching the progress bar object to your engine.\n\n        .. code-block:: python\n\n            pbar = ProgressBar()\n            pbar.attach(trainer, ['loss'])\n\n    Note:\n        When adding attaching the progress bar to an engine, it is recommend that you replace\n        every print operation in the engine's handlers triggered every iteration with\n        ``pbar.log_message`` to guarantee the correct format of the stdout.\n    \"\"\"\n\n    def __init__(self):\n        self.pbar = None\n\n    def _reset(self, engine):\n        self.pbar = tqdm(\n            total=len(engine.state.dataloader),\n            leave=False,\n            bar_format='{desc}[{n_fmt}/{total_fmt}] {percentage:3.0f}%|{bar}{postfix} [{elapsed}<{remaining}]')\n\n    def _close(self, engine):\n        self.pbar.close()\n        self.pbar = None\n\n    def _update(self, engine, metric_names=None):\n        if self.pbar is None:\n            self._reset(engine)\n\n        self.pbar.set_description('Epoch {}'.format(engine.state.epoch))\n\n        if metric_names is not None:\n            if not all(metric in engine.state.metrics for metric in metric_names):\n                raise KeyError(\"metrics not found in engine.state.metrics\")\n\n            metrics = {name: '{:.2e}'.format(engine.state.metrics[name]) for name in metric_names}\n            self.pbar.set_postfix(**metrics)\n\n        self.pbar.update()\n\n    @staticmethod\n    def log_message(message):\n        \"\"\"\n        Logs a message, preserving the progress bar correct output format\n\n        Args:\n            message (str): string you wish to log\n        \"\"\"\n        tqdm.write(message)\n\n    def attach(self, engine, metric_names=None):\n        \"\"\"\n        Attaches the progress bar to an engine object\n\n        Args:\n            engine (Engine): engine object\n            metric_names (list): (Optional) list of the metrics names to log as the bar progresses\n        \"\"\"\n        if not isinstance(metric_names, list):\n            raise TypeError(\"metric_names should be a list, got {} instead\".format(type(metric_names)))\n\n        engine.add_event_handler(Events.EPOCH_COMPLETED, self._close)\n        engine.add_event_handler(Events.ITERATION_COMPLETED, self._update, metric_names)\n", "path": "ignite/contrib/handlers/tqdm_logger.py"}]}