Do I need to pass variables to threads through Thread? - python

Is there any real difference between these two?
Variables are accessed in the threaded function, but not passed to it through Thread(args)
Variables are passed to the threaded function through Thread(args)
# 1
def do_something():
event = Event()
tracker = MyObject.instance()
start_time = datetime.timestamp(datetime.now())
def threaded_function():
current_time = datetime.timestamp(datetime.now())
while True:
if current_time - start_time > 30:
tracker.put("too long")
break
elif event.is_set():
break
else:
time.sleep(1)
thread = Thread(target=threaded_function)
thread.start()
# Do something that may take more than 30 seconds
event.set()
# 2
def do_something():
event = Event()
def threaded_function(tracker, start_time):
current_time = datetime.timestamp(datetime.now())
while True:
if current_time - start_time > 30:
tracker.put("too long")
break
elif event.is_set():
break
else:
time.sleep(1)
tracker = MyTracker.instance()
start_time = datetime.timestamp(datetime.now())
thread = Thread(target=threaded_function, args=(tracker, start_time))
thread.start()
# Do something that may take more than 30 seconds
event.set()

Practically speaking, there is little difference between the two, since you only start one thread.
In #1, threaded_function is a closure over two local variables in do_something. There would be no way to reliably vary those values between two or more threads, as any change to tracker or start_time would be visible inside any call to do_something.
In #2, tracker and start_time are local to threaded_function. They can be initialized to different values in each thread that runs threaded_function, and the values in one function are independent of values in another.

Related

should i use for loop or while loop to make a break timer in python?

I have this code to stop a function at a specific time. I would loop through the function and then break the function, if it takes too long, is there a better way to do it?
import time
def function_one()
rec = (time.time())
print("im starting")
ans = str(time.time() - rec)
ans = (round(float(ans), 15))
print("this is where im doing something code")
while ans < 10:
return function_one()
break
You can make it simpler like this:
import time
def function_one():
start_time = time.time()
while True:
print('Function doing something ...')
if time.time() - start_time > 10:
break
function_one()
Here, I'm using a while loop just to keep the function running, but that depends on the details of your function.
In general, what you need is:
set the start time
do whatever the function is supposed to be doing;
check if it's been running for too long and, in case it has, you can simply return.
So, something like:
import time
def function_one():
start_time = time.time()
# do your job
if time.time() - start_time > 10:
return something
function_one()
If you want to stop a function after a set amount of time has passed I would use a while loop and do something like this.
import time
def function_one():
start = (time.time()) #start time
limit = 1 #time limit
print("im starting")
while (time.time() - start) < limit:
#input code to do here
pass
print(f"finished after {time.time() - start} seconds")
function_one()

How do i do some stuff and count time in parallel in python?

I want my code to take some integers for some time (e.g. 10 seconds) and to count and print time every second. So it prints time permanently and i enter some numbers whenever i want. Maybe i should use async functions?
def accepting_bets():
global list_of_bets
list_of_bets = []
list_of_bets.append(int(input()))
def main():
i = 10
while True:
print(f"{i} seconds remaining...")
time.sleep(1)
i -= 1
accepting_bets()
if i == 0:
break
print(list_of_bets)
You can move the timing code to a different thread.
I would recommend researching about multi-threading in Python if you aren't aware about it.
import threading
import time
def countTime():
i = 10
while True:
print(f"{i} seconds remaining...")
time.sleep(1)
i -= 1
if i == 0:
break
print(list_of_bets)
thread1 = threading.Thread(target=countTime)
thread1.start()
# while you want to get the input
global list_of_bets
list_of_bets = []
list_of_bets.append(int(input()))
The countTime function will keep on running on another thread, and will not be paused by the input statement

Timer update inside while loop & if statement?

I'm building my first timer in Python and looking into time module. This is what I want:
Inside while loop, when the if condition "A" is true for the first time, start timer
When 10 seconds has passed, trigger an event
When 30 seconds has passed, clear timer so that it's ready to start again when if condition "A" is true
I feel like I have all the building blocks but still cannot get my head around for starting the 10 second timer. In pseudocode, I want this:
if current_time - the_time_from_first_if_statement_match > 10:
do something
This is what I have now. Any help appreciated!
def main():
start_time = time.time()
time_limit = 10
while True:
current_time = time.time() #keeps updating
matchresult = video_process.match
if matchresult == True:
elapsed_time = current_time - start_time #can be anything like 14 or 100 at this point, I'd just want a 10 sec timer
if elapsed_time > time_limit:
print("do something")
Something along these lines:
while True:
while not condition:
...
start_time = ...
while elapsed_time < 10:
...
do_something
while elapsed_time < 30:
...

How to create a timer that resets for quiz games?

I trying to create a timer for my quiz game. It should reset after every right question. But problem with my code is that it keeps increasing speed after every time it resets.
timeCount = 30
def countdown():
global timeCount
while timeCount > 0:
print(timeCount)
sleep(1)
timeCount -= 1
else:
print("Time Out!")
I think this is what you are trying to do:
import time
timeCount = 30
start = time.time()
seconds = 0
def countdown():
global timeCount
global seconds
while seconds < timeCount:
now = time.time()
seconds = now - start
print(timeCount - seconds)
else:
print("Time Out!")
countdown()
This teaches you how to use time.time. You can take away seconds from timeCount to make a timer that goes down from 30 to 0. When the seconds hits 30, you can end the loop and print "Time out". You can truncate the unnecessary floating point values, since i am assuming floating point numbers doesn't look good on a quiz timer and is unnecessary as well.
seconds = int(seconds)
You can use the function time.perf_counter() :
import time
start=time.perf_counter()
time.sleep(1) #you can replace the sleep function with the action you want to monitor
end=time.perf_counter()
print('elapsed time : ',end-start)
In the example above, time.perf_counter() evaluated the time when it is called so it gives you the elapsed time between the two call.
if you want to use your current logic :
Your 'global' statement means that your are going to modify the 'timeCount' variable during the execution of your code. To fix it, you can use a new local variable in your function (called 'local_count' in the below solution), like this you reset the countdown each time you call your function :
import time
timeCount = 30
def countdown():
local_count = timeCount
while local_count > 0:
print(local_count)
time.sleep(1)
local_count -= 1
print("Time Out!")

Python realtime timer

Could anybody advise me on converting the Java Timer class to Python? Currently I am converting a Java program to a Python script. However, Python does not have the Timer/TimerTask library (if it does have this, please enlighten me. Thanks!). I need to be able to reset the Timer. Java has Timer.cancel, but Python doesn't have this. Is there any replacement for it?
timer.cancel();
timer = new Timer("Printer");
MyTask t = new MyTask();
timer.schedule(t, 0, 1000);
Java script timer
class Timerclass extends TimerTask {
//times member represent calling times.
private int times = 0;
public void run() {
times++;
if (times <= 5) {
System.out.println(""+times);
} else {
this.cancel();
//Stop Timer.
System.out.println("Timer Finish");
}
}
}
Currently my code
import time
import threading
class Variable:
count = 0
people = 0
times = 0
def enter():
if int(Variable.count == 1):
print("Entered")
t = threading.Timer(5.0, countdown)
t.start()
else:
print("Entered +1")
t.clear() // Stuck Help
t = threading.Timer(5.0, countdown)
t.start()
def out():
if int(Variable.count > 0):
print("Exited")
elif int(Variable.count < 0):
print("Error")
def countdown():
print("TIMEUP")
while True:
sensor1 = input("Sensor 1: ")
sensor2 = input("Sensor 2: ")
Variable.count+=1
if int(sensor1) == int(sensor2):
Variable.count -= 1
print(Variable.count)
print("error")
elif int(sensor1) == 1:
Variable.people += 1
print(Variable.people)
enter()
elif int(sensor2) == 1:
Variable.people -= 1
print(Variable.people)
out()
else:
print("Error")
i have one problems that i'm stuck in i need to stop the current counting and start a new one whenever the method call
Basically what i want or im looking out for is when i recall this method it will reset or cancel any existing and recount again
Update latest
import time
import threading
class Variable:
count = 0
people = 0
times = 0
def countdown():
print("TIMEUP")
t = threading.Timer(5.0, countdown)
def enter():
if int(Variable.count == 1):
print("Entered")
t.start()
else:
print("Entered +1")
t.cancel()
t.join() # here you block the main thread until the timer is completely stopped
t.start()
def out():
if int(Variable.count > 0):
print("Exited")
elif int(Variable.count < 0):
print("Error")
while True:
sensor1 = input("Sensor 1: ")
sensor2 = input("Sensor 2: ")
Variable.count+=1
if int(sensor1) == int(sensor2):
Variable.count -= 1
print(Variable.count)
print("error")
elif int(sensor1) == 1:
Variable.people += 1
print(Variable.people)
enter()
elif int(sensor2) == 1:
Variable.people -= 1
print(Variable.people)
out()
else:
print("Error")
Anybody can spot my ,istake im getting this error but i t.clear() the process
in start raise RuntimeError("threads can only be started once")
RuntimeError: threads can only be started once
I would suggest using the time module for something like this:
from time import time, sleep
from datetime import datetime, timedelta
nowtime = time()
#Put your script here
x = 1
for k in range(1000):
x+=1
sleep(0.01)
sec = timedelta(seconds=int(time()-nowtime))
d = datetime(1,1,1)+sec
print("DAYS:HOURS:MIN:SEC")
print("%d:%d:%d:%d" % (d.day-1, d.hour, d.minute, d.second))
This assigns the time in seconds at the beginning to a variable, and after the main script has finished, it subtracts the previous time from the current time and formats it in days, hours, minutes, and seconds.
Here is it running:
bash-3.2$ python timing.py
DAYS:HOURS:MIN:SEC
0:0:0:10
bash-3.2$
You could also use the Threading module, which has a built-in cancel method:
>>> import threading
>>> def hello():
... print "This will print after a desired period of time"
...
>>> timer = threading.Timer(3.0, hello)
>>> timer.start() #After 3.0 seconds, "This will print after a desired period of time" will be printed
>>> This will print after a desired period of time
>>> timer.start()
>>> timer = threading.Timer(3.0, hello)
>>> timer.start()
>>> timer.cancel()
>>>
Python actually has a class for this, which includes a cancel method: threading.Timer. It seems to be close enough to the Java Timer class for your needs (The Java Timer also runs in background thread). Here's the example usage from the docs:
def hello():
print "hello, world"
t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed
Edit:
The problem with your updated code is that you're trying to use the same Timer object more than once. That may be possible in the Java implementation, but in Python you can't reuse a Thread object (Timer is a Thread subclass). You'll need to create a new Timer object after you join() it. Like this:
t = threading.Timer(5.0, countdown)
def enter():
global t # You need this to tell Python that you're going to change the global t variable. If you don't do this, using 't = ..' will just create a local t variable.
if int(Variable.count == 1):
print("Entered")
t.start()
else:
print("Entered +1")
t.cancel()
t.join() # here you block the main thread until the timer is completely stopped
t = threading.Timer(5.0, countdown)
t.start()

Categories