I'm trying to create a program that runs in a similar format to the game show Countdown.
I have found various ways to create a timer, most successfully with the time.sleep command and a while loop.
However, the user needs to be able to input a word whilst the timer is going on, otherwise the user could take as long as they want to think of their word after the timer has stopped. Once the timer has stopped, whatever the user has typed in should be taken as their word. I haven't found any kind of solution for this yet as python runs sequentially so it's difficult to have a timer and an input at the same time.
This worked for me previously... Uses time.time(). If this isn't what you are looking for maybe check out perf_counter()
import msvcrt
import time
def Countdown():
p = 3.00
alarm = time.time() + p
text = []
while True:
n = time.time()
if msvcrt.kbhit():
text.append(msvcrt.getche())
if n < alarm:
print(round(alarm - n))
else:
print("Time's up!")
break
Countdown()
Making a countdown timer with Python and Tkinter?
Related
Can the time library help with the task: the loop should stop when a certain time passes? I'm going to write a light game program in Python that should stop after for example 1 minute and output the result.
I can't find information about this function.
The straightforward solution is to run a while-loop with a time-checking boolean expression:
from datetime import datetime, timedelta
end_time = datetime.now() + timedelta(minutes=1)
while end_time >= datetime.now():
print("Your code should be here")
Another more sophisticated approach is to run the program in a separate thread. The thread checks for an event flag to be set in a while loop condition:
import threading
import time
def main_program(stop_event):
while not stop_event.is_set():
print("Your code should be here")
stop_event = threading.Event()
th_main_program = threading.Thread(target=main_program, args=(stop_event,))
th_main_program.start()
time.sleep(60)
stop_event.set()
In the approaches shown above the program execution finishes gracefully but an iteration within the while-loop has to be finished to check the boolean expression. This means the program doesn't exit immediately once the timeout is reached.
To make the main program exit right away once the timeout is reached, we can use daemon thread. Please note that daemon threads are abruptly stopped at shutdown. Their resources may not be released properly:
import threading
import time
def main_program():
while True:
print("Your code should be here")
th_main_program = threading.Thread(target=main_program, daemon=True)
th_main_program.start()
time.sleep(60)
You need to take time at the start and break your loop when the difference between current time and time at the start is more than you want.
import time
start_time = time.time()
while True:
current_time = time.time()
if current_time - start_time > 60: #time in seconds
break
#your code
You can also add time.sleep(0.01) to the loop to limit your fps.
My timer won't work properly, since it keeps printing forever, not what I want.
I've already tried re-organizing the script in many ways, but the result is always the same.
import time
CommandInput = input()
#execution [uptime]
def uptime(y):
while 1 == 1:
if (CommandInput == "uptime"):
print(y, " seconds")
y = y + 1
time.sleep(1)
uptime(9)
I wanted to make some sort of "background timer" that kept running from when the script was executed up to when it was closed, and if I typed a certain line in the input it would show the current number it is in. The problem is that it keeps printing the timer forever, for every single number it counts. I wanted to do a one-time thing, where you could wait as much as you want and type the input, which would show the number the timer is in.
Your current program has to wait for input() to finish. The compiler does not move past the second line until the user hits enter. Thus the functions starts once the input is finished.
This timer could be done several way, such as threading or timers. There are some examples of that here and here. For threading, you need one process for user inputs and one for timers. But the better and easier way is to to use a timer and store the current time. I believe the following code is somewhat similar to what you want:
import time
start_time = time.time()
def get_time():
current_time = time.time()
total = current_time - start_time
return total
while True:
CommandInput = input()
if CommandInput == "uptime":
y = get_time()
print(str(round(y)) + " seconds")
The variable start_time records the current time at the start. time.time() gets the current time in seconds on the computer. The get_time function is called after an input and sees how much time has pasted by subtracting the current time minus the start time. This way the you do not need multiple loops.
The while True loops just waits for the user input and then prints the time. This then repeats until the program is exited.
To write a script like that you would need to look into a module called asyncio (https://docs.python.org/3/library/asyncio.html), which would allow you to run multiple things at the same time.
Here is a asyncio hello world:
import asyncio
async def main():
print('Hello ...')
await asyncio.sleep(1)
print('... World!')
# Python 3.7+
asyncio.run(main())
I'm working on an irl minigame where you get materials every 5 minutes.
To monitor this i wanted to write a simple python script.
But now there is a little roadblok,
how do you make a loop that does something every x minutes, while still running other keyboard inputs without it disrupting the loop?
Here's a fairly simple example of using a threading.Timer. It displays the current time every 5 seconds while responding to user input.
This code will run in any terminal that supports ANSI / VT100 Terminal Control Escape Sequences.
#!/usr/bin/env python3
''' Scrolling Timer
Use a threading Timer loop to display the current time
while processing user input
See https://stackoverflow.com/q/45130837/4014959
Written by PM 2Ring 2017.07.18
'''
import readline
from time import ctime
from threading import Timer
# Some ANSI/VT100 Terminal Control Escape Sequences
CSI = '\x1b['
CLEAR = CSI + '2J'
CLEAR_LINE = CSI + '2K'
SAVE_CURSOR = CSI + 's'
UNSAVE_CURSOR = CSI + 'u'
GOTO_LINE = CSI + '%d;0H'
def emit(*args):
print(*args, sep='', end='', flush=True)
# Show the current time in the top line using a Timer thread loop
def show_time(interval):
global timer
emit(SAVE_CURSOR, GOTO_LINE % 1, CLEAR_LINE, ctime(), UNSAVE_CURSOR)
timer = Timer(interval, show_time, (interval,))
timer.start()
# Set up scrolling, leaving the top line fixed
emit(CLEAR, CSI + '2;r', GOTO_LINE % 2)
# Start the timer loop
show_time(interval=5)
try:
while True:
# Get user input and print it in upper case
print(input('> ').upper())
except KeyboardInterrupt:
timer.cancel()
# Cancel scrolling
emit('\n', SAVE_CURSOR, CSI + '0;0r', UNSAVE_CURSOR)
You need to send a KeyboardInterrupt, that is, hit CtrlC to stop this program,
Maybe a timer will be helpful for your task. I recommend you to check this link: https://docs.python.org/2.4/lib/timer-objects.html. While the timer is counting you are able to do other tasks and when the time is up, you can attach a function to the timer to do something. Timers from this library inherits from Threads
I have been searching and searching on how to figure out how to make an input or something go into a while loop. As in, the input() command won't stop my stopwatch. I have tried tkinter, pygame, and a couple other methods, but they just didn't work. If anyone can help me out, I would prefer something small and simple, if that's even possible. And to be specific on what I want to learn to do, is basically allowing, when any key is pressed, for it to instantly stop (preferably without hitting enter). Thanks, saddlepiggy!
Here is what I have so far, with nothing to activate the stopping:
#Setup (Variables and stuff)
hours = 0
minutes = 0
seconds = 0
import time
#Main Part of Code
print("Welcome to PyWatch, a stopwatch coded in Python!")
print("Press any key to start the stopwatch.")
print("Then, press any key to stop it!")
start = input("")
while hours < 48:
seconds = seconds + 1
time.sleep(1)
print(hours, "hours,", minutes, "minutes,", seconds, "seconds")
#If Statements for getting seconds/minutes/hours
if (seconds == 60):
minutes = minutes + 1
seconds = seconds - 60
if (minutes == 60):
hours =hours + 1
minutes = minutes - 60
Threading is what you want.
Create a second thread that waits for the input while your first thread handles your stopwatch code. Behold:
import threading, sys
def halt():
raw_input()
threading.Thread(target=halt).start()
while hours < 48 and threading.active_count() > 1:
seconds = seconds + 1
time.sleep(1)
# copy and past what you had before
Allow me to elaborate on what's happening: Thus far, all of the code you've written has been single threaded. This means only one line of code is executed at a time, there's only one thread of execution. Consequentially, your script can't multitask, it can't wait for input and print the time at the same time.
So when this line is evaluated
threading.Thread(target=halt).start()
The main thread creates a second thread of execution. Meanwhile, the main thread goes on and enters the while loop. The target parameter is the entry point of the thread, it's the starting point. It's analogous to if __name__ == "__main__:" for the main thread. Just as the main thread terminates when it reaches the end of if __name__ == "__main__:", our second thread will terminate once it reaches the end of halt().
The threading.active_count function tells you how many threads in are current in execution.
You can't do that in Python. You are asking for a keyboard event. Keyboard events are shipped with a GUI. This thread explains pretty much everything: QKeyPress event in PyQt
Or use an external application for your OS that can append output to a file that is read by your Python program in a loop. When a certain event is detected you can perform some actions. For Linux this tread explains: https://superuser.com/questions/248517/show-keys-pressed-in-linux
As stated in the question above, I wanted to create/implement a Timer to be used in a Maths Test program so that the user can view the timer whilst the system executes various commands.
I've tried many timers such as:
import time
s=0
m=0
while s<=60:
os.system('cls')
print (m, 'Minutes', s, 'Seconds')
time.sleep(1)
s+=1
if s==60:
m+=1
s=0
-
import sys
import os
import time
import datetime
current_time = datetime.datetime.now().time()
current_time = str(current_time)
current_time = current_time[:-7]
print(current_time)
if current_time = #set-the-time:
#Do something
However the top timer requires the system to sleep. Therefore if I were to implement this in a Maths Test Program, the user will not be able to input any data or perform any actions because the system continuously sleeps. Also when using the second method, again I would have to create some sort of while loop so that a signal/alert is passed when the time limit is reached, but again this will make the system freeze. Is there any way I could implement some sort of timer which allows the program to be run simultaneously???