Ahsan Naseem
Ahsan Naseem

Reputation: 1106

threading.timer printing only last value of for loop

Hey I am stuck in a situation where I have if condition inside for loop. I wanted to get output with 10 seconds delay if condition satisfies. Instead of desired output I get all values at same time and then last value repeats with 10 second delay. Below is code

import threading
import time
a=[2, 3, 4, 10, 12]
b=2
for x in a:
    if x >2:
        def delayfunction():
            print(x,"is not ok")
        threading.Timer(10, delayfunction).start()
        delayfunction()
    else:
        print(x," is less than equal to 2")

output is:

2  is less than equal to 2
3 is not ok
4 is not ok
10 is not ok
12 is not ok
12 is not ok
12 is not ok
12 is not ok
12 is not ok

I will be very much grateful if could get some assist here. Thanks

Upvotes: 3

Views: 164

Answers (1)

Maxime de Pachtere
Maxime de Pachtere

Reputation: 283

The problem is your scope. After the timer, the delayfunction will print the current x value, not the value of x at the start of the timer.

You need to pass the x as argument like this:

import threading
import time
a=[2, 3, 4, 10, 12]
b=2
for x in a:
    if x >2:
        def delayfunction(current_x):
            print(current_x,"is not ok")
        threading.Timer(10, delayfunction, [x]).start()
        delayfunction(x)
    else:
        print(x," is less than equal to 2")

The output will be:

2  is less than equal to 2
3 is not ok
4 is not ok
10 is not ok
12 is not ok
3 is not ok
4 is not ok
10 is not ok
12 is not ok

If you don't want the output before the timer, just don't call your delayfunction in your if statement.

In fact, threading.Timer will call your function (given as second parameter) after the 10 seconde (given as first parameter)

import threading
import time
a=[2, 3, 4, 10, 12]
b=2
for x in a:
    if x >2:
        def delayfunction(current_x):
            print(current_x,"is not ok")
        threading.Timer(10, delayfunction, [x]).start()
    else:
        print(x," is less than equal to 2")

will output:

2  is less than equal to 2 # immediatly
3 is not ok                # before 10 second
4 is not ok                # before 10 second
10 is not ok               # before 10 second
12 is not ok               # before 10 second

Upvotes: 3

Related Questions