pythonmultithreading

Timer without threading in python?


I am new to programming and would like to add a counter that deducts 1 from your score every two seconds. (so that I have to answer quickly to make my score increase)

chr
import random
import time
radians2 = None
ans = None
score = 0

radians1 = ['0', 'π/6', 'π/3', 'π/4', 'π/2', '2π/3', '3π/4', '5π/6', 'π', '7π/6', '4π/3', '5π/4', '3π/2', '5π/3', '7π/4', '11π/6', '2π']
while radians2 == ans or ans == None:

radians3 = (random.choice(radians1))
ans = input(radians3)
if radians3 == '0':
    radians2 = 0

elif radians3 == 'π/6':
    radians2 = 30

elif radians3 == 'π/3':
    radians2 = 60

elif radians3 == 'π/4':
    radians2 = 45

elif radians3 == 'π/2':
    radians2 = 90

elif radians3 == '2π/3':
    radians2 = 120

elif radians3 == '3π/4':
    radians2 = 135

elif radians3 == '5π/6':
    radians2 = 150

elif radians3 == 'π':
    radians2 = 180

elif radians3 == '7π/6':
    radians2 = 210

elif radians3 == '4π/3':
    radians2 = 240

elif radians3 == '5π/4':
    radians2 = 225

elif radians3 == '3π/2':
    radians2 = 270

elif radians3 == '5π/3':
    radians2 = 300

elif radians3 == '7π/4':
    radians2 = 315

elif radians3 == '11π/6':
    radians2 = 330

elif radians3 == '2π':
    radians2 = 360
score = score + 1

if radians2 == ans:
    print('Correct!')
    print "You've got %d in a row" % score
print "You lose, the correct answer was %d" % radians2

Sorry if the code is messy/long I figured out that I want to basically run something like:

while 1:
     time.sleep(2)
     score = score - 1

The only problem is that won't run simultaneously with the rest of the program, and threading (which is what seems to be the alternative) is very confusing to me.


Solution

  • You can start new thread , by using following code and write whatever your functional logic in it's run() method.

    import threading
    import time
    
    class RepeatEvery(threading.Thread):
        def __init__(self, interval):
    
            threading.Thread.__init__(self)     
            self.interval = interval  # seconds between calls
            self.runable = True
    
        def run(self):
            global score # make score global for this thread context
            while self.runable:
                time.sleep(self.interval)
                if self.runable:     
                    score = score - 1
                    self.runable = False
    
        def stop(self):
            self.runable = False
    

    The above code will iterate until thread is runnable(self.runable = True), so after 2 seconds score will decremented by 1. and loop inside the run method will break, and will be terminated.

    So, in order to call above thread do this.

    score_thread = RepeatEvery(2)
    score_thread.start()    
    

    this will call the thread constructor init and will initialize the interval variable with 2 seconds or whatever value passed from here.

    In order to stop the thread meanwhile, just call the stop() method.

    score_thread.stop() 
    

    You can also call join() method , to wait until thread completes it's execution.

    score_thread.join() 
    

    Doesn't looks so confusing :)