prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  reminder: remove debug logging code before final release
  
  ### Observed behavior
  
  #5223 introduced some verbose logging code
  
  ### Expected behavior
  
  remove before release
  
  ### User-facing consequences
  
  logs will get swamped
  
  ### Errors and logs
  <!--
  Relevant logs from:
   * the command line
   * ~/.kolibri/kolibri.log
   * the browser console
  
  Please wrap errors in triple backticks for clean formatting like this:
  ```
  01:10 info: something happened
  01:12 error: something bad happened
  ```
  -->
  
  …
  
  ### Steps to reproduce
  <!--
  Precise steps that someone else can follow in order to see this behavior
  -->
  
  …
  
  ### Context
  <!--
  Tell us about your environment, including:
   * Kolibri version
   * Operating system
   * Browser
  -->
  
  …
  
  
  </issue>
  <code>
  [start of kolibri/core/notifications/tasks.py]
  1 import logging as logger
  2 import threading
  3 import time
  4 
  5 from django.db import connection
  6 from django.db import transaction
  7 
  8 logging = logger.getLogger(__name__)
  9 
  10 
  11 class AsyncNotificationQueue():
  12 
  13     def __init__(self):
  14 
  15         # Value in seconds to determine the sleep time between log saving batches
  16         self.log_saving_interval = 5
  17 
  18         # Where new log saving functions are appended
  19         self.queue = []
  20 
  21         # Where the to be executed log saving functions are stored
  22         # once a batch save has been invoked
  23         self.running = []
  24 
  25     def append(self, fn):
  26         """
  27         Convenience method to append log saving function to the current queue
  28         """
  29         self.queue.append(fn)
  30 
  31     def toggle_queue(self):
  32         """
  33         Method to swap the queue and running, to allow new log saving functions
  34         to be added to the queue while previously added functions are being executed
  35         and cleared without fear of race conditions dropping saves.
  36         """
  37         old_queue = self.queue
  38         new_queue = self.running
  39         self.queue = new_queue
  40         self.running = old_queue
  41 
  42     def clear_running(self):
  43         """
  44         Reset the running list to drop references to already executed log saving functions
  45         """
  46         self.running = []
  47 
  48     def run(self):
  49         """
  50         Execute any log saving functions in the self.running list
  51         """
  52         if self.running:
  53             # Do this conditionally to avoid opening an unnecessary transaction
  54             with transaction.atomic():
  55                 for fn in self.running:
  56                     try:
  57                         logging.warn('>>>>>> AsyncNotificationQueue.run try')
  58                         fn()
  59                     except Exception as e:
  60                         # Catch all exceptions and log, otherwise the background process will end
  61                         # and no more logs will be saved!
  62                         logging.warn('>>>>>> AsyncNotificationQueue.run except {}'.format(e))
  63                         logging.debug("Exception raised during background notification calculation: ", e)
  64             connection.close()
  65 
  66     def start(self):
  67         while True:
  68             logging.warn('>>>>>> AsyncNotificationQueue.start: {}'.format(threading.currentThread().ident))
  69             logging.warn('\t\t len(self.running): {}'.format(self.running))
  70             logging.warn('\t\t len(self.queue): {}'.format(self.queue))
  71             self.toggle_queue()
  72             self.run()
  73             self.clear_running()
  74             time.sleep(self.log_saving_interval)
  75 
  76 
  77 log_queue = AsyncNotificationQueue()
  78 
  79 
  80 def add_to_save_queue(fn):
  81     log_queue.append(fn)
  82 
  83 
  84 def wrap_to_save_queue(fn, *args):
  85     def wrapper():
  86         fn(*args)
  87     log_queue.append(wrapper)
  88 
  89 
  90 class AsyncNotificationsThread(threading.Thread):
  91 
  92     @classmethod
  93     def start_command(cls):
  94         logging.warn('>>>>>> AsyncNotificationsThread.start_command: {}'.format(threading.currentThread().ident))
  95         thread = cls()
  96         thread.daemon = True
  97         thread.start()
  98 
  99     def run(self):
  100         logging.info("Initializing background log saving process")
  101         logging.warn('>>>>>> AsyncNotificationsThread.run: {}'.format(threading.currentThread().ident))
  102         log_queue.start()
  103
  [end of kolibri/core/notifications/tasks.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/kolibri/core/notifications/tasks.py b/kolibri/core/notifications/tasks.py
  --- a/kolibri/core/notifications/tasks.py
  +++ b/kolibri/core/notifications/tasks.py
  @@ -54,20 +54,15 @@
               with transaction.atomic():
                   for fn in self.running:
                       try:
  -                        logging.warn('>>>>>> AsyncNotificationQueue.run try')
                           fn()
                       except Exception as e:
                           # Catch all exceptions and log, otherwise the background process will end
                           # and no more logs will be saved!
  -                        logging.warn('>>>>>> AsyncNotificationQueue.run except {}'.format(e))
  -                        logging.debug("Exception raised during background notification calculation: ", e)
  +                        logging.warn("Exception raised during background notification calculation: ", e)
               connection.close()
   
       def start(self):
           while True:
  -            logging.warn('>>>>>> AsyncNotificationQueue.start: {}'.format(threading.currentThread().ident))
  -            logging.warn('\t\t len(self.running): {}'.format(self.running))
  -            logging.warn('\t\t len(self.queue): {}'.format(self.queue))
               self.toggle_queue()
               self.run()
               self.clear_running()
  @@ -91,12 +86,10 @@
   
       @classmethod
       def start_command(cls):
  -        logging.warn('>>>>>> AsyncNotificationsThread.start_command: {}'.format(threading.currentThread().ident))
           thread = cls()
           thread.daemon = True
           thread.start()
   
       def run(self):
           logging.info("Initializing background log saving process")
  -        logging.warn('>>>>>> AsyncNotificationsThread.run: {}'.format(threading.currentThread().ident))
           log_queue.start()
  
verification_info: {"golden_diff": "diff --git a/kolibri/core/notifications/tasks.py b/kolibri/core/notifications/tasks.py\n--- a/kolibri/core/notifications/tasks.py\n+++ b/kolibri/core/notifications/tasks.py\n@@ -54,20 +54,15 @@\n             with transaction.atomic():\n                 for fn in self.running:\n                     try:\n-                        logging.warn('>>>>>> AsyncNotificationQueue.run try')\n                         fn()\n                     except Exception as e:\n                         # Catch all exceptions and log, otherwise the background process will end\n                         # and no more logs will be saved!\n-                        logging.warn('>>>>>> AsyncNotificationQueue.run except {}'.format(e))\n-                        logging.debug(\"Exception raised during background notification calculation: \", e)\n+                        logging.warn(\"Exception raised during background notification calculation: \", e)\n             connection.close()\n \n     def start(self):\n         while True:\n-            logging.warn('>>>>>> AsyncNotificationQueue.start: {}'.format(threading.currentThread().ident))\n-            logging.warn('\\t\\t len(self.running): {}'.format(self.running))\n-            logging.warn('\\t\\t len(self.queue): {}'.format(self.queue))\n             self.toggle_queue()\n             self.run()\n             self.clear_running()\n@@ -91,12 +86,10 @@\n \n     @classmethod\n     def start_command(cls):\n-        logging.warn('>>>>>> AsyncNotificationsThread.start_command: {}'.format(threading.currentThread().ident))\n         thread = cls()\n         thread.daemon = True\n         thread.start()\n \n     def run(self):\n         logging.info(\"Initializing background log saving process\")\n-        logging.warn('>>>>>> AsyncNotificationsThread.run: {}'.format(threading.currentThread().ident))\n         log_queue.start()\n", "issue": "reminder: remove debug logging code before final release\n\r\n### Observed behavior\r\n\r\n#5223 introduced some verbose logging code\r\n\r\n### Expected behavior\r\n\r\nremove before release\r\n\r\n### User-facing consequences\r\n\r\nlogs will get swamped\r\n\r\n### Errors and logs\r\n<!--\r\nRelevant logs from:\r\n * the command line\r\n * ~/.kolibri/kolibri.log\r\n * the browser console\r\n\r\nPlease wrap errors in triple backticks for clean formatting like this:\r\n```\r\n01:10 info: something happened\r\n01:12 error: something bad happened\r\n```\r\n-->\r\n\r\n\u2026\r\n\r\n### Steps to reproduce\r\n<!--\r\nPrecise steps that someone else can follow in order to see this behavior\r\n-->\r\n\r\n\u2026\r\n\r\n### Context\r\n<!--\r\nTell us about your environment, including:\r\n * Kolibri version\r\n * Operating system\r\n * Browser\r\n-->\r\n\r\n\u2026\r\n\n", "before_files": [{"content": "import logging as logger\nimport threading\nimport time\n\nfrom django.db import connection\nfrom django.db import transaction\n\nlogging = logger.getLogger(__name__)\n\n\nclass AsyncNotificationQueue():\n\n    def __init__(self):\n\n        # Value in seconds to determine the sleep time between log saving batches\n        self.log_saving_interval = 5\n\n        # Where new log saving functions are appended\n        self.queue = []\n\n        # Where the to be executed log saving functions are stored\n        # once a batch save has been invoked\n        self.running = []\n\n    def append(self, fn):\n        \"\"\"\n        Convenience method to append log saving function to the current queue\n        \"\"\"\n        self.queue.append(fn)\n\n    def toggle_queue(self):\n        \"\"\"\n        Method to swap the queue and running, to allow new log saving functions\n        to be added to the queue while previously added functions are being executed\n        and cleared without fear of race conditions dropping saves.\n        \"\"\"\n        old_queue = self.queue\n        new_queue = self.running\n        self.queue = new_queue\n        self.running = old_queue\n\n    def clear_running(self):\n        \"\"\"\n        Reset the running list to drop references to already executed log saving functions\n        \"\"\"\n        self.running = []\n\n    def run(self):\n        \"\"\"\n        Execute any log saving functions in the self.running list\n        \"\"\"\n        if self.running:\n            # Do this conditionally to avoid opening an unnecessary transaction\n            with transaction.atomic():\n                for fn in self.running:\n                    try:\n                        logging.warn('>>>>>> AsyncNotificationQueue.run try')\n                        fn()\n                    except Exception as e:\n                        # Catch all exceptions and log, otherwise the background process will end\n                        # and no more logs will be saved!\n                        logging.warn('>>>>>> AsyncNotificationQueue.run except {}'.format(e))\n                        logging.debug(\"Exception raised during background notification calculation: \", e)\n            connection.close()\n\n    def start(self):\n        while True:\n            logging.warn('>>>>>> AsyncNotificationQueue.start: {}'.format(threading.currentThread().ident))\n            logging.warn('\\t\\t len(self.running): {}'.format(self.running))\n            logging.warn('\\t\\t len(self.queue): {}'.format(self.queue))\n            self.toggle_queue()\n            self.run()\n            self.clear_running()\n            time.sleep(self.log_saving_interval)\n\n\nlog_queue = AsyncNotificationQueue()\n\n\ndef add_to_save_queue(fn):\n    log_queue.append(fn)\n\n\ndef wrap_to_save_queue(fn, *args):\n    def wrapper():\n        fn(*args)\n    log_queue.append(wrapper)\n\n\nclass AsyncNotificationsThread(threading.Thread):\n\n    @classmethod\n    def start_command(cls):\n        logging.warn('>>>>>> AsyncNotificationsThread.start_command: {}'.format(threading.currentThread().ident))\n        thread = cls()\n        thread.daemon = True\n        thread.start()\n\n    def run(self):\n        logging.info(\"Initializing background log saving process\")\n        logging.warn('>>>>>> AsyncNotificationsThread.run: {}'.format(threading.currentThread().ident))\n        log_queue.start()\n", "path": "kolibri/core/notifications/tasks.py"}]}