A timer that restarts on a trigger Python - how to restart? - python

Bit of a newbie so bear with:
I am trying to make a crude 60s timer that is reset and starts again on the rising edge of a trigger (ie when a gate goes high). The problem I have is that it won't reset and restart unless the timer has completed (ie reached zero). How do I interrupt the while loop and get it to start again?
Here is my code:
import keyboard
import time
t=60
last = False
current = False
while True:
current = keyboard.is_pressed('space') # triggered when space bar is pressed
if last == 0 and current == 1:
while t>=0:
print(t)
t-=1
time.sleep(1)
last = current # reset

Try this:
import time
import keyboard
x=60
while True:
try:
if keyboard.is_pressed('space'):
x=60
print(f"Timer reset to {x}")
elif keyboard.is_pressed('space'):
break
else:
print(f"{x} seconds left")
time.sleep(1)
x-=1
except Exception:
pass

This is my suggestion. The problem is, that time.sleep is blocking, so when it's sleeping you cannot break it by pressing escape. You will have to spam the escape button, but it works.
import keyboard
import time
t=60
last = False
current = False
while True:
current = keyboard.is_pressed('space') # triggered when space bar is pressed
if last == 0 and current == 1:
while t>=0:
if keyboard.is_pressed('escape'):
t = 60
last = False
current = False
print("Timer stopped.")
break
print(t)
t-=1
time.sleep(1)
last = current # reset
Sample output/test:
60
59
58
57
56
60
59
58
57
56
60
59
60
59
58

To suggest a solution without break:
import keyboard
import time
last = 0
current = 0
while True:
t=60
current = keyboard.is_pressed('space') # triggered when space bar is pressed
if last == 0 and current == 1:
current = 0
while t>=0 and current == 0:
print(t)
t-=1
time.sleep(1)
current = keyboard.is_pressed('space')
last = current # reset
Not sure how you want to manage long presses here. If the spacebar stays pressed for more than one second, the timer will reset several times in (technically) one keypress.

Related

How to get out of a while loop with a specific key

I am trying to make an auto clicker but when i try to make my code exit it doesnt
here is my code
import mouse
import keyboard
import time
import os
os.system('cls')
def Config():
print("Click every")
hour = int(input("Hour: "))
minute = int(input("Minute: "))
second = int(input("Second: "))
total_time = hour*3600 + minute*60 + second
print("f6 to start and f10 to stop")
keyboard.wait('f6')
while True:
time.sleep(total_time)
mouse.click()
#def Fastest():
print(" Auto clicker!!!")
print(" By ze")
print("-------------------------")
print("Auto click on desired time or Fastest?")
choose = int(input("""
1. Config (No milliseconds)
2. Fastest
"""))
if choose == 1:
Config()
# elif choose == 2:
# Fastest()
#TODO:
# use mouse.click
# make it click with time
# make function fastest start with f1 and stops with f2
# create back up file
i tried an if statement with keyboard.is_pressed('key') thinking it would work but it doesnt my results are that the code exits (if key is pressed then exit)
You need to check if the key is pressed in your infinite loop. If it is pressed, you need to exit
while True:
time.sleep(total_time)
mouse.click()
if keyboard.is_pressed("f10"):
break
But this waits for the sleep function , so you'll need to hold f10 for total_time seconds.
You should use a loop to check for the key, rather than sleeping
import datetime
...
clicking = True
while clicking:
mouse.click()
s = datetime.datetime.now()
while ((datetime.datetime.now()-s).total_seconds() < total_time):
# This runs while the difference in time since you started the loop is less than the time you want to wait
if keyboard.is_pressed("f10"):
clicking = False
break
Use one thread to handle user input and another thread to do the clicking:
from threading import Thread
from msvcrt import getwch
import mouse
done = False
def auto_click():
print("Press \"q\" to quit")
global done
while True:
if getwch() == "q":
done = True
break
Thread( target = auto_click, daemon = True ).start()
while not done: # you can add whatever logic you want including a time gate here
mouse.click()

Making a timer reset on a light

I'm very new to code and want the led.off portion to be extendable. Basically, if I hit the button again before the 10 seconds run out. So if the button is hit before lighting up, there is another 10 second wait, starting at press 2.
from time import time, sleep
from signal import pause
led = LED(18) # or whatever pin you've got it on
button = Button(23) # again, adjust as necessary
def light_off_for_10_sec():
led.off()
sleep(10)
led.on()
button.when_pressed = light_off_for_10_sec
The 10 second pause before lighting up works great, but here is what I have tried to use to stretch the led.off period.
def stretched(values):
when_pressed = 10
for value in values:
if value:
sleep(5)
pressed = time()
yield time() - pressed <= 20
led.source = stretched(button.pressed)
pause()```

counting code giving me 0 instead of a value

this is my code:
from threading import Timer
timeout = 5
t = Timer(timeout, print, ['Sorry, times up'])
t.start()
count_push1 = + 1
print("Please push the button to count up.You have 5 seconds.")
while True:
if bool(push_button1.read()):
press_count = + 1
print(press_count)
sleep(0.2)
break
else:
print('You pressed', press_count, 'times.')
break
break
I want the user to have 5 seconds.In that 5 seconds, the user will click a button, and timer will reset to 5 seconds.If button is not clicked in 5 seconds,it shows the total number of times user pressed the button.I tried but when I run the code,the code automatically ends.Someone help please
You have the order of the operators wrong. In your while loop, you need to change the counter to count_push1 += 1
At the top where you define the variable as being 1, I would remove the the + for readability.
Edit: count_push1 += 1 is short for count_push1 = count_push1 + 1

Pause and Continue a Loop When Press Key in Python

Who can help me on this?
Pause Countdown when press "P" Key and continue the Countdown when press "S" key. Until now i have this code, but i cant find the way to solve this.
Thanks
from multiprocessing import Process
import keyboard
import time
def countdown_1():
i=6
j=40
k=0
while True:
a = keyboard.read_key()
if(str(a) != "p"):
if(j==-1):
j=59
i -=1
if(j > 9):
print(str(k)+str(i)+":"+str(j))
else:
print(str(k)+str(i)+":"+str(k)+str(j))
time.sleep(1)
j -= 1
if(i==0 and j==-1):
break
if(i==0 and j==-1):
print("END")
time.sleep(1)
countdown_1()
I get a solution to your problem, that is because when you use keyboard.readkey() python wait for a key to be pressed. instead, you should use keyboard.is_pressed('X')
I have modified your code to make a working version, I slightly change it to match my taste.
from multiprocessing import Process
import keyboard
import time
def countdown_1():
pause_keyboard = False # I use a bolean as a state is clearer for me
i = 6 # minutes
j = 40
k = 0 # represent 0 we will instead use code format
while True:
starting_time = time.time()
while True: # this loop wait one second or slightly more
if time.time() - starting_time >= 1: # a second or more
break
if keyboard.is_pressed('p'):
pause_keyboard = True
elif keyboard.is_pressed('s'):
pause_keyboard = False
if pause_keyboard:
continue
if (j == -1): ## here we adjust the count when we changes minutes
j = 59 # 59 secondes
i -= 1 # one minutes less
if(j > 9): ## in order to pretty print
print("{}{}:{}".format(0, i, j)) # you can direclty use 0 instead of k.
else:
print("{}{}:{}{}".format(0, i, 0, j))
j -= 1
if(i==0 and j==-1): # we finish the counter
break
if(i==0 and j==-1):
print("END")
time.sleep(1) # wait a last second
countdown_1()
EDIT: Use time.time() instead of sleep to be able to catch signals.

PYTHON: How to make a program to stop if some seconds have passed?

So I'm making a little speed game. A random letter is going to be generated by a function, right after that, I want the program to wait some seconds. If nothing is pressed, you will lose and your record will be displayed If you press the right key, another random letter is going to be displayed. I used the time function and simulated a cronometer that lasts in a range (0,2). This is what I have so far. It works, the thing is, it displays the first letter, if you press it wrong you lose (good) but even if you press it right, the cronometer obviously keeps running, so it gets to 2 and you lose. I want it to stop and reset after I hit the key, but I have no idea of how to do it. Im new in programming so I'm sorry if you don't get something.
import string
import random
import msvcrt
import time
def generarletra():
string.ascii_lowercase
letra = random.choice(string.ascii_lowercase)
return letra
def getchar():
s = ''
return msvcrt.getch().decode('utf-8')
print("\nWelcome to Key Pop It!")
opcion = int(input("\n Press 1 to play OR\n Press 2 for instructions"))
if(opcion == 1):
acum=0
while True:
letra2 = generarletra()
print(letra2)
key = getchar()
for s in range (0,2):
print("Segundos ", s)
time.sleep(2)
acum = acum + 1
if((key is not letra2) or (s == 2)):
print("su record fue de, ", acum)
break
elif(opcion == 2):
print("\n\nWelcome to key pop it!\nThe game is simple, the machine is going to generate a
random\nletter and you have to press it on your keyboard, if you take too\nlong or press the wrong
letter, you will lose.")
else:
print("Invalid option!")
PD: You need to run it with a console simulation in your IDE or directly from the console. msvcrt library won't work inside an IDE for some reason.
msvcrt.getch() is blocking, so you don't actually measure the time it took the user to press the key. The for loop starts after the user already pressed it.
also, time.sleep() is blocking, so the user will have to wait the sleep time even if he already pressed the key.
To solve the first problem you can use msvcrt.kbhit() to check if the user pressed on some key, and call msvcrt.getch() only if he did. This way msvcrt.getch() will return immediately after you call it.
To solve the second problem you can just use time.time() to get the start time of the round, and compare it to current time inside a loop. You can print how much time passed inside the loop also.
Here is the final code (with some extra naming and formatting changes):
import string
import random
import msvcrt
import time
MAX_TIME = 2
def get_random_char():
return random.choice(string.ascii_lowercase)
def get_user_char():
return msvcrt.getch().decode('utf-8')
print("\nWelcome to Key Pop It!")
option = input("\n Press 1 to play OR\n Press 2 for instructions\n")
if option == "1":
score=0
while True:
char = get_random_char()
print("\n" + char)
start_time = time.time()
while not msvcrt.kbhit():
seconds_passed = time.time() - start_time
print("seconds passed: {0:.1f}".format(seconds_passed), end="\r")
if seconds_passed >= MAX_TIME:
key = None
break
else:
key = get_user_char()
if key != char:
break
score = score + 1
print("\nsu record fue de, ", score)
elif option == "2":
print("""
Welcome to key pop it!
The game is simple, the machine is going to generate a random
letter and you have to press it on your keyboard, if you take too
long or press the wrong letter, you will lose.""")
else:
print("Invalid option!")
Timestamp-solution:
from time import time, sleep
start = time() # start time measuring by creating timestamp
def time_passed(start, duration):
"""tests if an amount of time has passed
Args:
start(float): timestamp of time()
duration(int): seconds that need to pass
Returns:
bool: are 'duration' seconds over since 'start'
"""
return start + duration <= time()
# Use as condition for while
while not time_passed(start, 5):
sleep(1)
# ... or if statements or <younameit>
if time_passed(start, 5):
print("Do something if 5 seconds are over")

Categories