Arnav
Arnav

Reputation: 115

How could I set a boolean value to True, and make it so if a condition is met, it becomes False, but only for a certain amount of time?

Seems like there should be a simple solution using the time module or something, but I've tried a few things and nothing seems to work. I need something like this to work:

hungry = True
if line.find ('feeds'):
    #hungry = False for 60 seconds, then hungry is true again

Anyone have a solution for this?

edit: As for what I've tried, I've tried this bit of code:

if hungry==True:
     print('yum! not hungry for 20 seconds')
     hungry = False
     i = 20
     while(i>0):
         i-=1
         time.sleep(1)
         if(i==0):
             hungry = True

But that doesn't work because the program just pauses until hungry is True again, and hungry being false while the program sleeps won't help; it should be false for a certain amount of time while the rest of the program works

edit: It looks like this won't be possible without threading. I'll have to either find a new solution, or learn to use threading. Thanks for all the help anyways, I seriously appreciate it!

Upvotes: 1

Views: 4310

Answers (5)

the wolf
the wolf

Reputation: 35532

You can do something along these lines:

from threading import Timer
import time

class Time_out(object):
    def __init__(self,secs):
        self.timer = Timer(secs,self.set_false)
        self.hungry=True
        self.timer.start()

    def set_false(self):
        self.hungry=False

if __name__ == '__main__':
    x=Time_out(1)
    y=0
    t1=time.time()
    while x.hungry:
        y+=1
        # this loop -- do whatever... I just increment y as a test...

    print 'looped for {:.5} seconds, y increased {:,} times in that time'.format(time.time()-t1, y)

Prints:

looped for 1.0012 seconds, y increased 5,239,754 times in that time

The value I used here for the timeout is 1 second but you can use your own value. Then do the work in the while loop. This is a very primitive but effective callback.

The advantage is you can have many Time_out objects and the loop will keep going until nobody is hungry!

Upvotes: 1

Niklas R
Niklas R

Reputation: 16870

You could also use something like the code below. This is an elegant OOP solution which is convenient to use and maintain.

from time import time

class TimedProperty(object):

    def __init__(self, value1, value2):
        self.value1 = value1
        self.value2 = value2
        self.start_time = -1
        self.time_value = 0

    @property
    def value(self):
        if self.valuenum == 0:
            return self.value1
        else:
            return self.value2

    @property
    def valuenum(self):
        if time() - self.start_time > self.time_value:
            return 0
        else:
            return 1

    def switch_for(self, seconds, value=None):
        self.start_time = time()
        self.time_value = seconds
        if value is not None:
            self.value2 = value

Usage:

def main():
    p = TimedProperty(True, False)
    print p.value
    print p.valuenum
    p.switch_for(0.2)
    print p.value
    print p.valuenum
    sleep(0.5)
    print p.value
    print p.valuenum

Output:

True
0
False
1
True
0

Example on codepad.org: http://codepad.org/glujHgey (sleep() is forbidden on codepad, its been replaced by a time consing for loop)

Upvotes: 1

Rushy Panchal
Rushy Panchal

Reputation: 17532

Easy solution:

from time import time # time() is the time in seconds since the epoch (January 1st, 1970)
hungry = True
if line.find('feeds'):
    start, hungry = time(), False # it will be a fraction of a second off 
    while 1:                      # because hungry is set to False right 
        if (time() - start) >= 60:  # after start is set to the current time
            hungry = True             
            break  

NOTE: This may not be exactly 60 seconds because time() (at least, I am told this) can be affected by the memory usage of the program; thus, it may be slightly off.

Also, unless you use threading, you can't really do anything else in the program. You could run the rest of the program in the while loop, though.

EDIT: You could create a function that does this. Thus, you can have part of the program run, then check if it is time to change the value of hungry again:

def isHungry(start):
     from time import time
     if (time() - start) >= 60: hungry = True # if 60 seconds has passed
     else: hungry = False
     return hungry

from time import time
# some code
if line.find('feeds'):
    start = time()
# a bit of code
hungry = isHungry(start)
# more code
hungry = isHungry(start)

Upvotes: 0

DSM
DSM

Reputation: 353079

You could encapsulate the behaviour you want in a TimedValue class, but that might be overkill here-- I'd probably just do something like

now = time.time()
hunger = lambda: time.time() > now + 60

and then use hunger() whenever I wanted the value instead of hungry. That way, the code doesn't block, and we can continue doing work, but hunger() will give us the right state. E.g.

import time
now = time.time()
hunger = lambda: time.time() > now + 60
for i in range(10):
    print 'doing stuff here on loop', i
    time.sleep(10)
    print 'hunger is', hunger()

produces

doing stuff here on loop 0
hunger is False
doing stuff here on loop 1
hunger is False
doing stuff here on loop 2
hunger is False
doing stuff here on loop 3
hunger is False
doing stuff here on loop 4
hunger is False
doing stuff here on loop 5
hunger is True
doing stuff here on loop 6
hunger is True
doing stuff here on loop 7
hunger is True
doing stuff here on loop 8
hunger is True
doing stuff here on loop 9
hunger is True

Upvotes: 3

Emily
Emily

Reputation: 6069

I'm not sure what kind of accuracy you're requiring, but maybe you can just sleep for 60 seconds and then set the variable to true?

from time import sleep
hungry = True
if line.find('feeds'):
  hungry = False
  sleep(60)
  hungry = True

Upvotes: 1

Related Questions