prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Create small random change of position to resume the Bot after some time off
  When you stop the Bot (by more than X hours for example) does not return the exact same position. It is strange to stay a few hours without running the bot and it resumes in the same previous position.
  
  
  </issue>
  <code>
  [start of pokemongo_bot/cell_workers/sleep_schedule.py]
  1 from datetime import datetime, timedelta
  2 from time import sleep
  3 from random import uniform
  4 from pokemongo_bot.base_task import BaseTask
  5 
  6 
  7 class SleepSchedule(BaseTask):
  8     """Pauses the execution of the bot every day for some time
  9 
  10     Simulates the user going to sleep every day for some time, the sleep time
  11     and the duration is changed every day by a random offset defined in the
  12     config file
  13     Example Config:
  14     {
  15         "type": "SleepSchedule",
  16         "config": {
  17           "time": "12:00",
  18           "duration":"5:30",
  19           "time_random_offset": "00:30",
  20           "duration_random_offset": "00:30"
  21         }
  22     }
  23     time: (HH:MM) local time that the bot should sleep
  24     duration: (HH:MM) the duration of sleep
  25     time_random_offset: (HH:MM) random offset of time that the sleep will start
  26                         for this example the possible start time is 11:30-12:30
  27     duration_random_offset: (HH:MM) random offset of duration of sleep
  28                         for this example the possible duration is 5:00-6:00
  29     """
  30     SUPPORTED_TASK_API_VERSION = 1
  31 
  32     LOG_INTERVAL_SECONDS = 600
  33     SCHEDULING_MARGIN = timedelta(minutes=10)    # Skip if next sleep is RESCHEDULING_MARGIN from now
  34 
  35     def initialize(self):
  36         # self.bot.event_manager.register_event('sleeper_scheduled', parameters=('datetime',))
  37         self._process_config()
  38         self._schedule_next_sleep()
  39         self._calculate_current_sleep()
  40 
  41     def work(self):
  42         if self._should_sleep_now():
  43             self._sleep()
  44             self._schedule_next_sleep()
  45             self.bot.login()
  46 
  47     def _process_config(self):
  48         self.time = datetime.strptime(self.config.get('time', '01:00'), '%H:%M')
  49 
  50         # Using datetime for easier stripping of timedeltas
  51         duration = datetime.strptime(self.config.get('duration', '07:00'), '%H:%M')
  52         self.duration = int(timedelta(hours=duration.hour, minutes=duration.minute).total_seconds())
  53 
  54         time_random_offset = datetime.strptime(self.config.get('time_random_offset', '01:00'), '%H:%M')
  55         self.time_random_offset = int(
  56             timedelta(
  57                 hours=time_random_offset.hour, minutes=time_random_offset.minute).total_seconds())
  58 
  59         duration_random_offset = datetime.strptime(self.config.get('duration_random_offset', '00:30'), '%H:%M')
  60         self.duration_random_offset = int(
  61             timedelta(
  62                 hours=duration_random_offset.hour, minutes=duration_random_offset.minute).total_seconds())
  63 
  64     def _schedule_next_sleep(self):
  65         self._next_sleep = self._get_next_sleep_schedule()
  66         self._next_duration = self._get_next_duration()
  67         self.emit_event(
  68             'next_sleep',
  69             formatted="Next sleep at {time}",
  70             data={
  71                 'time': str(self._next_sleep)
  72             }
  73         )
  74 
  75     def _calculate_current_sleep(self):
  76         self._current_sleep = self._next_sleep - timedelta(days=1)
  77         current_duration = self._get_next_duration()
  78         self._current_end = self._current_sleep + timedelta(seconds = current_duration)
  79 
  80     def _should_sleep_now(self):
  81         if datetime.now() >= self._next_sleep:
  82             return True
  83         if datetime.now() >= self._current_sleep and datetime.now() < self._current_end:
  84             self._next_duration = (self._current_end - datetime.now()).total_seconds()
  85             return True
  86 
  87         return False
  88 
  89     def _get_next_sleep_schedule(self):
  90         now = datetime.now() + self.SCHEDULING_MARGIN
  91         next_time = now.replace(hour=self.time.hour, minute=self.time.minute)
  92 
  93         next_time += timedelta(seconds=self._get_random_offset(self.time_random_offset))
  94 
  95         # If sleep time is passed add one day
  96         if next_time <= now:
  97             next_time += timedelta(days=1)
  98 
  99         return next_time
  100 
  101     def _get_next_duration(self):
  102         duration = self.duration + self._get_random_offset(self.duration_random_offset)
  103         return duration
  104 
  105     def _get_random_offset(self, max_offset):
  106         offset = uniform(-max_offset, max_offset)
  107         return int(offset)
  108 
  109     def _sleep(self):
  110         sleep_to_go = self._next_duration
  111 
  112         sleep_m, sleep_s = divmod(sleep_to_go, 60)
  113         sleep_h, sleep_m = divmod(sleep_m, 60)
  114         sleep_hms = '%02d:%02d:%02d' % (sleep_h, sleep_m, sleep_s)
  115 
  116         now = datetime.now()
  117         wake = str(now + timedelta(seconds=sleep_to_go))
  118 
  119         self.emit_event(
  120             'bot_sleep',
  121             formatted="Sleeping for {time_hms}, wake at {wake}",
  122             data={
  123                 'time_hms': sleep_hms,
  124                 'wake': wake
  125             }
  126         )
  127         while sleep_to_go > 0:
  128             if sleep_to_go < self.LOG_INTERVAL_SECONDS:
  129                 sleep(sleep_to_go)
  130                 sleep_to_go = 0
  131             else:
  132                 sleep(self.LOG_INTERVAL_SECONDS)
  133                 sleep_to_go -= self.LOG_INTERVAL_SECONDS
  134
  [end of pokemongo_bot/cell_workers/sleep_schedule.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/pokemongo_bot/cell_workers/sleep_schedule.py b/pokemongo_bot/cell_workers/sleep_schedule.py
  --- a/pokemongo_bot/cell_workers/sleep_schedule.py
  +++ b/pokemongo_bot/cell_workers/sleep_schedule.py
  @@ -18,6 +18,7 @@
             "duration":"5:30",
             "time_random_offset": "00:30",
             "duration_random_offset": "00:30"
  +          "wake_up_at_location": ""
           }
       }
       time: (HH:MM) local time that the bot should sleep
  @@ -26,7 +27,8 @@
                           for this example the possible start time is 11:30-12:30
       duration_random_offset: (HH:MM) random offset of duration of sleep
                           for this example the possible duration is 5:00-6:00
  -    """
  +    wake_up_at_location: (lat, long | lat, long, alt | "") the location at which the bot wake up 
  +    *Note that an empty string ("") will not change the location*.    """
       SUPPORTED_TASK_API_VERSION = 1
   
       LOG_INTERVAL_SECONDS = 600
  @@ -42,6 +44,9 @@
           if self._should_sleep_now():
               self._sleep()
               self._schedule_next_sleep()
  +            wake_up_at_location = self.config.get("wake_up_at_location", "")
  +            if wake_up_at_location:
  +                self.bot.api.set_position(self.wake_up_at_location[0],self.wake_up_at_location[1],self.wake_up_at_location[2])
               self.bot.login()
   
       def _process_config(self):
  @@ -60,6 +65,21 @@
           self.duration_random_offset = int(
               timedelta(
                   hours=duration_random_offset.hour, minutes=duration_random_offset.minute).total_seconds())
  +        
  +        wake_up_at_location = self.config.get("wake_up_at_location", "")
  +        if wake_up_at_location:
  +            try:
  +                wake_up_at_location = wake_up_at_location.split(',',2)               
  +                lat=float(wake_up_at_location[0])
  +                lng=float(wake_up_at_location[1])
  +                if len(wake_up_at_location) == 3:
  +                    alt=float(wake_up_at_location[2])
  +                else:
  +                    alt = uniform(self.bot.config.alt_min, self.bot.config.alt_max)
  +            except ValueError:
  +                raise ValueError('SleepSchedule wake_up_at_location, parsing error in location') #TODO there must be a more elegant way to do it...
  +
  +            self.wake_up_at_location = [lat, lng, alt]
   
       def _schedule_next_sleep(self):
           self._next_sleep = self._get_next_sleep_schedule()
  
verification_info: {"golden_diff": "diff --git a/pokemongo_bot/cell_workers/sleep_schedule.py b/pokemongo_bot/cell_workers/sleep_schedule.py\n--- a/pokemongo_bot/cell_workers/sleep_schedule.py\n+++ b/pokemongo_bot/cell_workers/sleep_schedule.py\n@@ -18,6 +18,7 @@\n           \"duration\":\"5:30\",\n           \"time_random_offset\": \"00:30\",\n           \"duration_random_offset\": \"00:30\"\n+          \"wake_up_at_location\": \"\"\n         }\n     }\n     time: (HH:MM) local time that the bot should sleep\n@@ -26,7 +27,8 @@\n                         for this example the possible start time is 11:30-12:30\n     duration_random_offset: (HH:MM) random offset of duration of sleep\n                         for this example the possible duration is 5:00-6:00\n-    \"\"\"\n+    wake_up_at_location: (lat, long | lat, long, alt | \"\") the location at which the bot wake up \n+    *Note that an empty string (\"\") will not change the location*.    \"\"\"\n     SUPPORTED_TASK_API_VERSION = 1\n \n     LOG_INTERVAL_SECONDS = 600\n@@ -42,6 +44,9 @@\n         if self._should_sleep_now():\n             self._sleep()\n             self._schedule_next_sleep()\n+            wake_up_at_location = self.config.get(\"wake_up_at_location\", \"\")\n+            if wake_up_at_location:\n+                self.bot.api.set_position(self.wake_up_at_location[0],self.wake_up_at_location[1],self.wake_up_at_location[2])\n             self.bot.login()\n \n     def _process_config(self):\n@@ -60,6 +65,21 @@\n         self.duration_random_offset = int(\n             timedelta(\n                 hours=duration_random_offset.hour, minutes=duration_random_offset.minute).total_seconds())\n+        \n+        wake_up_at_location = self.config.get(\"wake_up_at_location\", \"\")\n+        if wake_up_at_location:\n+            try:\n+                wake_up_at_location = wake_up_at_location.split(',',2)               \n+                lat=float(wake_up_at_location[0])\n+                lng=float(wake_up_at_location[1])\n+                if len(wake_up_at_location) == 3:\n+                    alt=float(wake_up_at_location[2])\n+                else:\n+                    alt = uniform(self.bot.config.alt_min, self.bot.config.alt_max)\n+            except ValueError:\n+                raise ValueError('SleepSchedule wake_up_at_location, parsing error in location') #TODO there must be a more elegant way to do it...\n+\n+            self.wake_up_at_location = [lat, lng, alt]\n \n     def _schedule_next_sleep(self):\n         self._next_sleep = self._get_next_sleep_schedule()\n", "issue": "Create small random change of position to resume the Bot after some time off\nWhen you stop the Bot (by more than X hours for example) does not return the exact same position. It is strange to stay a few hours without running the bot and it resumes in the same previous position.\n\n", "before_files": [{"content": "from datetime import datetime, timedelta\nfrom time import sleep\nfrom random import uniform\nfrom pokemongo_bot.base_task import BaseTask\n\n\nclass SleepSchedule(BaseTask):\n    \"\"\"Pauses the execution of the bot every day for some time\n\n    Simulates the user going to sleep every day for some time, the sleep time\n    and the duration is changed every day by a random offset defined in the\n    config file\n    Example Config:\n    {\n        \"type\": \"SleepSchedule\",\n        \"config\": {\n          \"time\": \"12:00\",\n          \"duration\":\"5:30\",\n          \"time_random_offset\": \"00:30\",\n          \"duration_random_offset\": \"00:30\"\n        }\n    }\n    time: (HH:MM) local time that the bot should sleep\n    duration: (HH:MM) the duration of sleep\n    time_random_offset: (HH:MM) random offset of time that the sleep will start\n                        for this example the possible start time is 11:30-12:30\n    duration_random_offset: (HH:MM) random offset of duration of sleep\n                        for this example the possible duration is 5:00-6:00\n    \"\"\"\n    SUPPORTED_TASK_API_VERSION = 1\n\n    LOG_INTERVAL_SECONDS = 600\n    SCHEDULING_MARGIN = timedelta(minutes=10)    # Skip if next sleep is RESCHEDULING_MARGIN from now\n\n    def initialize(self):\n        # self.bot.event_manager.register_event('sleeper_scheduled', parameters=('datetime',))\n        self._process_config()\n        self._schedule_next_sleep()\n        self._calculate_current_sleep()\n\n    def work(self):\n        if self._should_sleep_now():\n            self._sleep()\n            self._schedule_next_sleep()\n            self.bot.login()\n\n    def _process_config(self):\n        self.time = datetime.strptime(self.config.get('time', '01:00'), '%H:%M')\n\n        # Using datetime for easier stripping of timedeltas\n        duration = datetime.strptime(self.config.get('duration', '07:00'), '%H:%M')\n        self.duration = int(timedelta(hours=duration.hour, minutes=duration.minute).total_seconds())\n\n        time_random_offset = datetime.strptime(self.config.get('time_random_offset', '01:00'), '%H:%M')\n        self.time_random_offset = int(\n            timedelta(\n                hours=time_random_offset.hour, minutes=time_random_offset.minute).total_seconds())\n\n        duration_random_offset = datetime.strptime(self.config.get('duration_random_offset', '00:30'), '%H:%M')\n        self.duration_random_offset = int(\n            timedelta(\n                hours=duration_random_offset.hour, minutes=duration_random_offset.minute).total_seconds())\n\n    def _schedule_next_sleep(self):\n        self._next_sleep = self._get_next_sleep_schedule()\n        self._next_duration = self._get_next_duration()\n        self.emit_event(\n            'next_sleep',\n            formatted=\"Next sleep at {time}\",\n            data={\n                'time': str(self._next_sleep)\n            }\n        )\n\n    def _calculate_current_sleep(self):\n        self._current_sleep = self._next_sleep - timedelta(days=1)\n        current_duration = self._get_next_duration()\n        self._current_end = self._current_sleep + timedelta(seconds = current_duration)\n\n    def _should_sleep_now(self):\n        if datetime.now() >= self._next_sleep:\n            return True\n        if datetime.now() >= self._current_sleep and datetime.now() < self._current_end:\n            self._next_duration = (self._current_end - datetime.now()).total_seconds()\n            return True\n\n        return False\n\n    def _get_next_sleep_schedule(self):\n        now = datetime.now() + self.SCHEDULING_MARGIN\n        next_time = now.replace(hour=self.time.hour, minute=self.time.minute)\n\n        next_time += timedelta(seconds=self._get_random_offset(self.time_random_offset))\n\n        # If sleep time is passed add one day\n        if next_time <= now:\n            next_time += timedelta(days=1)\n\n        return next_time\n\n    def _get_next_duration(self):\n        duration = self.duration + self._get_random_offset(self.duration_random_offset)\n        return duration\n\n    def _get_random_offset(self, max_offset):\n        offset = uniform(-max_offset, max_offset)\n        return int(offset)\n\n    def _sleep(self):\n        sleep_to_go = self._next_duration\n\n        sleep_m, sleep_s = divmod(sleep_to_go, 60)\n        sleep_h, sleep_m = divmod(sleep_m, 60)\n        sleep_hms = '%02d:%02d:%02d' % (sleep_h, sleep_m, sleep_s)\n\n        now = datetime.now()\n        wake = str(now + timedelta(seconds=sleep_to_go))\n\n        self.emit_event(\n            'bot_sleep',\n            formatted=\"Sleeping for {time_hms}, wake at {wake}\",\n            data={\n                'time_hms': sleep_hms,\n                'wake': wake\n            }\n        )\n        while sleep_to_go > 0:\n            if sleep_to_go < self.LOG_INTERVAL_SECONDS:\n                sleep(sleep_to_go)\n                sleep_to_go = 0\n            else:\n                sleep(self.LOG_INTERVAL_SECONDS)\n                sleep_to_go -= self.LOG_INTERVAL_SECONDS\n", "path": "pokemongo_bot/cell_workers/sleep_schedule.py"}]}