How to decrease value of variable over time

Question:

I’m very new to python and am creating a pet simulator. I want the hunger and sleep variable of the pet to decrease by 1 over time. So perhaps each variable decreases by 1 every 5 minutes while the user is in the program.

class pet(object):
    age: 0
    excitement_reduce = 3
    excitement_max = 10
    excitement_warning = 3
    food_reduce = 2
    food_max = 10
    food_warning = 2
    level: 0
    sleep_reduce = 1
    sleep_max = 10
    vocab = [""]

    def __init__(self, name, pet_type):
        self.age = self.age
        self.excitement = randrange(self.excitement_max)
        self.food = randrange(self.food_max)
        self.level = self.level
        self.name = self.name
        self.pet_type = self.pet_type
        self.sleep = randrange(self.sleep_max)
        self.vocab = self.vocab[:]

    def __clock_tick(self):
        self.food -= 1
        self.sleep -= 1

I thought perhaps I could create another function of __clock_tick? Or maybe I import the python time module into my code.

Asked By: DevTuck

||

Answers:

You can use a Timer object to call your __clock_tick on a periodic basis.

import threading
...

PERIOD_SEC = 5 * 60

# in your constructor
def __init__(self):
    self.timer_task = None

def __clock_tick(self):
    self.food -= 1
    self.sleep -= 1

    # timers are one shot, so you need to start a new one as long as
    # you want to execute this callback on a periodic basis
    self.make_alive()

# to start your timer
def make_alive(self):
    self.timer_task = threading.Timer(PERIOD_SEC, self.__clock_tick, args=(self,))
    self.timer_task.start()

# to stop your timer
def kill(self):
    if (self.timer_task is not None):
        self.timer_task.cancel()
        self.timer_task = None

NOTE: By convention, a function name which starts with two underscore is private and cannot be seen to child class which inherits from your main class. You may rather want it to be protected instead (i.e.: one single underscore).

NOTE: the advantage of using a Timer over basic busy waiting loops is that you reduce the CPU usage, benefits from sync mechanisms provided by the threading API and keep your program running without blocking it.

Answered By: Jib

You can use the time module with a loop to call __clock_tick method every 5 minutes (300 seconds) as follows:


from random import randrange
import time

class pet(object):
    age: 0
    excitement_reduce = 3
    excitement_max = 10
    excitement_warning = 3
    food_reduce = 2
    food_max = 10
    food_warning = 2
    level: 0
    sleep_reduce = 1
    sleep_max = 10
    vocab = [""]

    def __init__(self, name, pet_type):
        # set self values
        self.age = 0
        self.excitement = randrange(self.excitement_max)
        self.food = randrange(self.food_max)
        self.level = 0
        self.name = name
        self.pet_type = pet_type
        self.sleep = randrange(self.sleep_max)
        self.vocab = self.vocab[:]
        


    def __clock_tick(self):
        self.food -= 1
        self.sleep -= 1
        print('Clock tick called')
        print(self.food , self.sleep)

    
    def callClockTick(self):
        while True:
            self.__clock_tick()
            time.sleep(300)



if __name__ == "__main__":
    p = pet('abc', 'cat')
    p.callClockTick()

Here I added the print method for visualization purposes.

Note: I have slightly modified the class pet‘s variable declarations in this example. But the idea will work regardless of it.

Answered By: S M Samnoon Abrar
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.