prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Refactor logging statements to use lazy % formatting
  Example of logging statements that we want to refactor:
  
  https://github.com/mozilla/bugbug/blob/d53595391dbd75379bb49bff12dee4821e4b956c/bugbug/github.py#L61
  
  https://github.com/mozilla/bugbug/blob/69972a1684f788319bf5c2944bbe8eeb79428c7d/scripts/regressor_finder.py#L396
  
  More details can be found in the [pylint docs](https://pylint.readthedocs.io/en/latest/user_guide/messages/warning/logging-fstring-interpolation.html).
  
  </issue>
  <code>
  [start of scripts/retrieve_training_metrics.py]
  1 # -*- coding: utf-8 -*-
  2 # This Source Code Form is subject to the terms of the Mozilla Public
  3 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
  4 # You can obtain one at http://mozilla.org/MPL/2.0/.
  5 
  6 import argparse
  7 import logging
  8 import os
  9 import sys
  10 from os.path import abspath, join
  11 
  12 import requests
  13 import taskcluster
  14 
  15 from bugbug.utils import get_taskcluster_options
  16 
  17 ROOT_URI = "train_{}.per_date"
  18 DATE_URI = "train_{}.per_date.{}"
  19 BASE_URL = "https://community-tc.services.mozilla.com/api/index/v1/task/{}/artifacts/public/metrics.json"
  20 NAMESPACE_URI = "project.bugbug.{}"
  21 
  22 LOGGER = logging.getLogger(__name__)
  23 
  24 logging.basicConfig(level=logging.INFO)
  25 
  26 
  27 def get_task_metrics_from_uri(index_uri):
  28     index_url = BASE_URL.format(index_uri)
  29     LOGGER.info("Retrieving metrics from %s", index_url)
  30     r = requests.get(index_url)
  31 
  32     if r.status_code == 404:
  33         LOGGER.error(f"File not found for URL {index_url}, check your arguments")
  34         sys.exit(1)
  35 
  36     r.raise_for_status()
  37 
  38     return r
  39 
  40 
  41 def get_namespaces(index, index_uri):
  42     index_namespaces = index.listNamespaces(index_uri)
  43 
  44     return index_namespaces["namespaces"]
  45 
  46 
  47 def is_later_or_equal(partial_date, from_date):
  48     for partial_date_part, from_date_part in zip(partial_date, from_date):
  49         if int(partial_date_part) > int(from_date_part):
  50             return True
  51         elif int(partial_date_part) < int(from_date_part):
  52             return False
  53         else:
  54             continue
  55 
  56     return True
  57 
  58 
  59 def get_task_metrics_from_date(model, date, output_directory):
  60     options = get_taskcluster_options()
  61 
  62     index = taskcluster.Index(options)
  63 
  64     index.ping()
  65 
  66     # Split the date
  67     from_date = date.split(".")
  68 
  69     namespaces = []
  70 
  71     # Start at the root level
  72     # We need an empty list in order to append namespaces part to it
  73     namespaces.append([])
  74 
  75     # Recursively list all namespaces greater or equals than the given date
  76     while namespaces:
  77         current_ns = namespaces.pop()
  78 
  79         # Handle version level namespaces
  80         if not current_ns:
  81             ns_uri = ROOT_URI.format(model)
  82         else:
  83             current_ns_date = ".".join(current_ns)
  84             ns_uri = DATE_URI.format(model, current_ns_date)
  85 
  86         ns_full_uri = NAMESPACE_URI.format(ns_uri)
  87 
  88         tasks = index.listTasks(ns_full_uri)
  89         for task in tasks["tasks"]:
  90             task_uri = task["namespace"]
  91             r = get_task_metrics_from_uri(task_uri)
  92 
  93             # Write the file on disk
  94             file_name = f"metric_{'_'.join(task_uri.split('.'))}.json"
  95             file_path = abspath(join(output_directory, file_name))
  96             with open(file_path, "w") as metric_file:
  97                 metric_file.write(r.text)
  98             LOGGER.info(f"Metrics saved to {file_path!r}")
  99 
  100         for namespace in get_namespaces(index, ns_full_uri):
  101             new_ns = current_ns.copy()
  102             new_ns.append(namespace["name"])
  103 
  104             if not is_later_or_equal(new_ns, from_date):
  105                 LOGGER.debug("NEW namespace %s is before %s", new_ns, from_date)
  106                 continue
  107 
  108             # Might not be efficient but size of `namespaces` shouldn't be too
  109             # big as we are doing a depth-first traversal
  110             if new_ns not in namespaces:
  111                 namespaces.append(new_ns)
  112 
  113 
  114 def main():
  115     description = "Retrieve a model training metrics"
  116     parser = argparse.ArgumentParser(description=description)
  117 
  118     parser.add_argument(
  119         "-d",
  120         "--output-directory",
  121         default=os.getcwd(),
  122         help="In which directory the script should save the metrics file. The directory must exists",
  123     )
  124     parser.add_argument("model", help="Which model to retrieve training metrics from.")
  125     parser.add_argument(
  126         "date",
  127         nargs="?",
  128         help="Which date should we retrieve training metrics from. Default to latest",
  129     )
  130 
  131     args = parser.parse_args()
  132 
  133     get_task_metrics_from_date(args.model, args.date, args.output_directory)
  134 
  135 
  136 if __name__ == "__main__":
  137     main()
  138
  [end of scripts/retrieve_training_metrics.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/scripts/retrieve_training_metrics.py b/scripts/retrieve_training_metrics.py
  --- a/scripts/retrieve_training_metrics.py
  +++ b/scripts/retrieve_training_metrics.py
  @@ -95,7 +95,7 @@
               file_path = abspath(join(output_directory, file_name))
               with open(file_path, "w") as metric_file:
                   metric_file.write(r.text)
  -            LOGGER.info(f"Metrics saved to {file_path!r}")
  +            LOGGER.info("Metrics saved to %r", file_path)
   
           for namespace in get_namespaces(index, ns_full_uri):
               new_ns = current_ns.copy()
  
verification_info: {"golden_diff": "diff --git a/scripts/retrieve_training_metrics.py b/scripts/retrieve_training_metrics.py\n--- a/scripts/retrieve_training_metrics.py\n+++ b/scripts/retrieve_training_metrics.py\n@@ -95,7 +95,7 @@\n             file_path = abspath(join(output_directory, file_name))\n             with open(file_path, \"w\") as metric_file:\n                 metric_file.write(r.text)\n-            LOGGER.info(f\"Metrics saved to {file_path!r}\")\n+            LOGGER.info(\"Metrics saved to %r\", file_path)\n \n         for namespace in get_namespaces(index, ns_full_uri):\n             new_ns = current_ns.copy()\n", "issue": "Refactor logging statements to use lazy % formatting\nExample of logging statements that we want to refactor:\r\n\r\nhttps://github.com/mozilla/bugbug/blob/d53595391dbd75379bb49bff12dee4821e4b956c/bugbug/github.py#L61\r\n\r\nhttps://github.com/mozilla/bugbug/blob/69972a1684f788319bf5c2944bbe8eeb79428c7d/scripts/regressor_finder.py#L396\r\n\r\nMore details can be found in the [pylint docs](https://pylint.readthedocs.io/en/latest/user_guide/messages/warning/logging-fstring-interpolation.html).\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this file,\n# You can obtain one at http://mozilla.org/MPL/2.0/.\n\nimport argparse\nimport logging\nimport os\nimport sys\nfrom os.path import abspath, join\n\nimport requests\nimport taskcluster\n\nfrom bugbug.utils import get_taskcluster_options\n\nROOT_URI = \"train_{}.per_date\"\nDATE_URI = \"train_{}.per_date.{}\"\nBASE_URL = \"https://community-tc.services.mozilla.com/api/index/v1/task/{}/artifacts/public/metrics.json\"\nNAMESPACE_URI = \"project.bugbug.{}\"\n\nLOGGER = logging.getLogger(__name__)\n\nlogging.basicConfig(level=logging.INFO)\n\n\ndef get_task_metrics_from_uri(index_uri):\n    index_url = BASE_URL.format(index_uri)\n    LOGGER.info(\"Retrieving metrics from %s\", index_url)\n    r = requests.get(index_url)\n\n    if r.status_code == 404:\n        LOGGER.error(f\"File not found for URL {index_url}, check your arguments\")\n        sys.exit(1)\n\n    r.raise_for_status()\n\n    return r\n\n\ndef get_namespaces(index, index_uri):\n    index_namespaces = index.listNamespaces(index_uri)\n\n    return index_namespaces[\"namespaces\"]\n\n\ndef is_later_or_equal(partial_date, from_date):\n    for partial_date_part, from_date_part in zip(partial_date, from_date):\n        if int(partial_date_part) > int(from_date_part):\n            return True\n        elif int(partial_date_part) < int(from_date_part):\n            return False\n        else:\n            continue\n\n    return True\n\n\ndef get_task_metrics_from_date(model, date, output_directory):\n    options = get_taskcluster_options()\n\n    index = taskcluster.Index(options)\n\n    index.ping()\n\n    # Split the date\n    from_date = date.split(\".\")\n\n    namespaces = []\n\n    # Start at the root level\n    # We need an empty list in order to append namespaces part to it\n    namespaces.append([])\n\n    # Recursively list all namespaces greater or equals than the given date\n    while namespaces:\n        current_ns = namespaces.pop()\n\n        # Handle version level namespaces\n        if not current_ns:\n            ns_uri = ROOT_URI.format(model)\n        else:\n            current_ns_date = \".\".join(current_ns)\n            ns_uri = DATE_URI.format(model, current_ns_date)\n\n        ns_full_uri = NAMESPACE_URI.format(ns_uri)\n\n        tasks = index.listTasks(ns_full_uri)\n        for task in tasks[\"tasks\"]:\n            task_uri = task[\"namespace\"]\n            r = get_task_metrics_from_uri(task_uri)\n\n            # Write the file on disk\n            file_name = f\"metric_{'_'.join(task_uri.split('.'))}.json\"\n            file_path = abspath(join(output_directory, file_name))\n            with open(file_path, \"w\") as metric_file:\n                metric_file.write(r.text)\n            LOGGER.info(f\"Metrics saved to {file_path!r}\")\n\n        for namespace in get_namespaces(index, ns_full_uri):\n            new_ns = current_ns.copy()\n            new_ns.append(namespace[\"name\"])\n\n            if not is_later_or_equal(new_ns, from_date):\n                LOGGER.debug(\"NEW namespace %s is before %s\", new_ns, from_date)\n                continue\n\n            # Might not be efficient but size of `namespaces` shouldn't be too\n            # big as we are doing a depth-first traversal\n            if new_ns not in namespaces:\n                namespaces.append(new_ns)\n\n\ndef main():\n    description = \"Retrieve a model training metrics\"\n    parser = argparse.ArgumentParser(description=description)\n\n    parser.add_argument(\n        \"-d\",\n        \"--output-directory\",\n        default=os.getcwd(),\n        help=\"In which directory the script should save the metrics file. The directory must exists\",\n    )\n    parser.add_argument(\"model\", help=\"Which model to retrieve training metrics from.\")\n    parser.add_argument(\n        \"date\",\n        nargs=\"?\",\n        help=\"Which date should we retrieve training metrics from. Default to latest\",\n    )\n\n    args = parser.parse_args()\n\n    get_task_metrics_from_date(args.model, args.date, args.output_directory)\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "scripts/retrieve_training_metrics.py"}]}