How to Create an Auto-Correcting Variable

Sorry for the kind-of vague title. I can’t think of a better way to put it.

So I made a Discord bot in Python using Discord.py, and in it I made a background task using the @tasks function. I need the task to run every minute, but it needs to run ON the minute. (E.g., if the time is 5 minutes 30 seconds, it needs to sleep for 30 seconds. If the time is 60 seconds/0 seconds, it needs to sleep for 60 seconds.

But I can’t find a way to make the variable update once the cog has been loaded. Any ideas? Here’s a sample of my current code:

class GenericCog(commands.Cog):
    def __init__(self, bot):
      self.bot = bot
      self.task.start()

    now = datetime.datetime.now()
    timeToSleep = 60 - now.second
     
    @tasks.loop(seconds=timeToSleep)
    async def task(self):
        global timeToSleep
        if timeToSleep != 60:
            timeToSleep = 60 - now.second
        else:
            timeToSleep = 60

timeToSleep can’t be updated once the loop starts.

So I confess I don’t know decorators or async well enough to totally comprehend what’s happening at the bottom of your code there, but have you considered using the time.sleep() function to pause your program?

So for example, to ensure your program starts on the minute, I think you could write something like:

from time import sleep
from datetime import datetime

while True:
    now = datetime.now()
    if now.second == 0:
        break
# Have your bot do its thing
sleep(60) #Pauses your program for 60 seconds
# Have your bot do its thing again

This article may give you some ideas as well: Python sleep(): How to Add Time Delays to Your Code – Real Python

Again, I apologize if I missed something obvious due to not being familiar as of yet with decorators or async, but I hope something in here is of some benefit to you. Good luck.

Doing this works in threading, but not with Discord.py tasks, sadly.
But I figured it out with kind of the same method!
Instead of trying to update the un-updatable variable that is the time to sleep, I simply put an if statement that counteracts the current amount of seconds in the init function!

My code:

def __init__(self, bot):
      self.bot = bot
      now = datetime.datetime.now()
      if now.second != 60:
        sleep(60 - now.second)
        self.checkevents.start()
      else:
        self.checkevents.start()

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.