Q : Python time - python

I would like to use ·time()· to launch an event. An example would be to print("test") for 3 seconds. For that I did this:
from time import time, sleep
from random import random
t = time()
n = 3
print(n, time() - t)
for i in range(100):
sleep(0.04)
print(time() - t)
if time() - t > n:
print("test")
break
and it works! But in my game, in a while loop, it does not work... Why not?

If I've understood correctly, it seems you don't know how to run a simple gameloop and run some test code after 3 seconds, here's some naive approach:
from time import time, sleep
from random import random
start_time = time()
n = 3
while True:
elapsed_time = time() - start_time
sleep(0.04)
print(elapsed_time)
if elapsed_time > n:
print("test")
break

if you want to achieve something else during the 3 second delay period, rather than just going round a while loop, try using a time-delayed thread. For example, the following
import threading
import time
def afterThreeSec():
print("test")
return
t1 = threading.Timer(3, afterThreeSec)
t1.setName('t1')
t1.start()
print ("main")
time.sleep(1)
print ("main")
time.sleep(1)
print ("main")
time.sleep(1)
print ("main")
time.sleep(1)
print ("main")
gives the output:
main
main
main
test
main
main

Related

Break a while loop with the sleep function inside after a certain period of time

How can i stop a while loop after a certain time in which the sleep function is used. The condition inside a while loop does not work correctly because the sleep function pauses the execution of the code.
In this case i have delay for 40 seconds before a while loop stops:
# timeout for 10 minutes
timeout = time.time() + 60*10
while True:
if time.time() >= timeout:
break
# do something
sleep(20)
# do something
sleep(20)
you may use the code below.
import datetime
import time
timeout = datetime.datetime.now() + datetime.timedelta(seconds=20) # define here!
while True:
now = datetime.datetime.now()
if now >= timeout:
print('time is up !')
break
else:
print('do something')
time.sleep(5) # define here!
continue
Looks like you need a variable sleep duration.
Something like this:
from time import time, sleep
timeout = time() + 10 * 60
while time() < timeout:
# do some work
sleep_duration = min(20, timeout - time())
sleep(sleep_duration)
This means that the sleep will be at most 20s
Probably, the fastest solution will be to set the certain amount of sleep.
timeout = time.time() + 60*10
while time.time() < timeout:
# do something
# added clipping negative numbers too
time_left = max(0,min(20, timeout - time.time()))
sleep(time_left)
if time_left == 0:
break
time_left = max(0,min(20, timeout - time.time()))
# do something
sleep(time_left)
Not the most elegant solution. But should work

Using two different functions at the same time in python

import time
import random
def timer():
correct = 1
x = 0
while correct != 2:
time.sleep(0.1)
x = x + 0.1
def round1():
numb = random.randint(1, 100)
print(numb)
timer()
ans = input(">")
if ans == numb:
correct = 2
x = round(x)
print("you did that in", x ,"seconds!")
round1()
I was trying to get both functions to run together (have the game playing and the timer going in the background) but as soon as the timer started it would let me continue the game.
In the given program, I have created two different functions that will work at the same time. I have used threading to create thread of functions and sleep to limit the printing speed. In similar manner you can use game and timer function together.
from threading import Thread
from time import sleep
#sleep is used in functions to delay the print
#the below functions has infinite loop that will run together
#defining functions
def func1():
for x in range(20):
sleep(1)
print("This is function 1.")
def func2():
for x in range(10):
sleep(2)
print("This is function 2.")
#creating thread
thread1=Thread(target=func1)
thread2=Thread(target=func2)
#running thread
thread1.start()
thread2.start()

Threading in python - user input with timer

I am trying to run two functions in parallel:
Timer
Input field
Program should terminate either when Timer ends or when user provides an answer.
Everything is working fine, but when the time is up I still can input an answer, and I want process to terminate.
Can somebody help me with that issue ?
Thanks !
Here is my code:
import sys
import time
import threading
def countdown2(seconds):
global stop_timer
stop_timer = False
start = time.time()
while not stop_timer:
if time.time() - start >= seconds:
stop_timer = True
print(f'End of time {time.time() - start}')
print(f'End of time in {time.time() - start}')
countdown_thread = threading.Thread(target=countdown2, args=(5,))
countdown_thread.start()
while not stop_timer:
answer = input('Provide answer: ')
if answer:
stop_timer = True
break
print('End')
Here's an example of how you could do this:
from threading import Thread
import time
import signal
import os
got_input = False
def countdown(duration):
global got_input
for _ in range(duration):
time.sleep(1)
if got_input:
return
if not got_input:
os.kill(os.getpid(), signal.SIGINT)
def main():
global got_input
(t := Thread(target=countdown, args=[5])).start()
try:
answer = input('Please enter a value: ')
got_input = True
print(f'You entered: {answer}')
except KeyboardInterrupt:
print('\nToo slow')
finally:
t.join()
if __name__ == '__main__':
main()

How to stop 'enter spamming' in a python reaction timer

I have been trying to make a reaction timer for a project to test reaction times. It uses 'perf_counter' to record the times before and after an input to test how long it takes to press the enter key. The issue is that the enter key can be spammed which makes it seem if they have a reaction time of 0.000001 seconds. I have made a class which disables the keyboard and enables it when I want. Even in that case, people are able to sneak in extra enter presses between the disables and enables. I have attached the code below. Any ideas how to prevent enter spamming?
import time, random, msvcrt
from math import log10, floor
def round_sig(x, sig=5):
return round(x, sig-int(floor(log10(abs(x))))-1)
class keyboardDisable():
def start(self):
self.on = True
def stop(self):
self.on = False
def __call__(self):
while self.on:
msvcrt.getwch()
def __init__(self):
self.on = False
import msvcrt
disable = keyboardDisable()
disable.start()
print('When I say __GO__ you hit ENTER! This will happen 3 times. Got it?')
time.sleep(2)
print('Ready')
time.sleep(1)
print('Steady')
time.sleep(random.randint(2,5))
print('#####__GO__######')
disable.stop()
tic = time.perf_counter()
a = input()
toc = time.perf_counter()
if msvcrt.kbhit():
disable.start()
timeSpent = toc-tic
print('Your first time was '+str(timeSpent) + ' seconds')
time.sleep(1)
print('The next one is coming up.')
time.sleep(1)
print('Ready')
time.sleep(1)
print('Steady')
time.sleep(random.randint(2,5))
print('#####__GO__######')
disable.stop()
tic2 = time.perf_counter()
b = input()
toc2 = time.perf_counter()
if msvcrt.kbhit():
disable.start()
timeSpent2 = toc2-tic2
print('Your second time was '+str(timeSpent2) + ' seconds')
time.sleep(1)
print('The last one is coming up.')
time.sleep(1)
print('Ready')
time.sleep(1)
print('Steady')
time.sleep(random.randint(2,5))
print('#####__GO__######')
disable.stop()
tic3 = time.perf_counter()
c = input()
toc3 = time.perf_counter()
timeSpent3 = toc3-tic3
print('Your last time was '+str(timeSpent3) + ' seconds')
average = (timeSpent + timeSpent2 + timeSpent3)/3
numAverage = round_sig(average)
print('Your average time is '+str(numAverage) + ' seconds')
The keyboard-disabling code never really runs.
Here's a simplification of your program that uses a function to capture one reaction time and calls it thrice.
The clear_keyboard_buffer() function (that should consume all outstanding keystrokes) was borrowed from https://stackoverflow.com/a/2521054/51685 .
import time, random, msvcrt, math
def round_sig(x, sig=5):
return round(x, sig - int(math.floor(math.log10(abs(x)))) - 1)
def clear_keyboard_buffer():
while msvcrt.kbhit():
msvcrt.getwch()
def get_reaction_time():
print("Ready")
time.sleep(1)
print("Steady")
time.sleep(random.randint(2, 5))
print("#####__GO__######")
clear_keyboard_buffer()
tic = time.perf_counter()
a = input()
toc = time.perf_counter()
return toc - tic
print("When I say __GO__ you hit ENTER! This will happen 3 times. Got it?")
time1 = get_reaction_time()
print(f"Your first time was {time1} seconds")
time.sleep(1)
print("The next one is coming up.")
time2 = get_reaction_time()
print(f"Your first time was {time2} seconds")
time.sleep(1)
print("The last one is coming up.")
time3 = get_reaction_time()
print(f"Your first time was {time3} seconds")
average = (time1 + time2 + time3) / 3
print(f"Your average time is {round_sig(average)} seconds")
This solution uses a Thread to start the timer, while the main thread waits for input all the time. That way, it is possible to catch early key presses:
from threading import Thread
import random
import time
def start():
global started
started = None
time.sleep(random.randint(2,5))
print("#### GO ####")
started = time.time()
t = Thread(target=start)
print("ready...")
# start the thread and directly wait for input:
t.start()
input()
end = time.time()
if not started:
print("Fail")
else:
print(end-started)
t.join()

How we can stop a program at certain time in a day#15:30pm everyday…?(It's running every 1 minute)

Anyone help me to get code for below conditions...
I would like to run job1 and job2 for every 2 and 3 seconds,
job1 and job2 should start#9:30am in a day..and should stop#17:30pm...!
job3 #17:31pm daily once only..
import schedule
import time
def job1():
print("I'm working...")
def job2():
print("I'm not working...")
def job3():
print("I'll not work...")
schedule.every(2).seconds.do(job1) #For Every 2 seconds
schedule.every(5).seconds.do(job2) #For Every 3 Seconds
schedule.every().day.at("17:28").do(job3) #Once in a day
while True:
schedule.run_pending()
time.sleep(1)
You can wrap this into a function and start it in a given time with a scheduler
schedule.every(2).seconds.do(job1) #For Every 2 seconds
schedule.every(5).seconds.do(job2) #For Every 3 Seconds
And you could do the same with canceling the job when you want. So you will have 2 extra job which starts and stops the other jobs.
Probably not the nicest way of doing this, but something like this should work. (You obviously can extend the if statement to incorporate only weekdays/exclude holidays etc.)
import datetime
import time
def job_a():
print('a')
def job_b():
print('b')
def job_3():
print('3')
start_a = datetime.datetime.now()
wait_time_a = 2
start_b = datetime.datetime.now()
wait_time_b = 5
start_time = 9.30
end_time = 17.31
do_job_3 = False
while True:
while datetime.datetime.now().hour + datetime.datetime.now().minute/100. > start_time \
and datetime.datetime.now().hour + datetime.datetime.now().minute/100. < end_time:
do_job_3 = True
if (datetime.datetime.now() - start_a).seconds > wait_time_a:
job_a()
start_a += datetime.timedelta(seconds=wait_time_a)
if (datetime.datetime.now() - start_b).seconds > wait_time_b:
job_b()
start_b += datetime.timedelta(seconds=wait_time_b)
time.sleep(1)
if do_job_3:
do_job_3 = False
job_3()
time.sleep(1)

Categories

Resources