How to make python script more efficient while loop - python

I have a simple python script that listens to my keypress and executes a command upon keypress. In my code, I have an infinite while loop which is pretty harsh on the performance of my computer. I'm wondering what's a better way to achieve the same behavior with less impact on the performance. The objective is to print a text which says
You Pressed A Key!
Every time I press a certain key, in this case, 'h', I want to be able to press h multiple times not just once hence the while loop.
import keyboard
while True:
if keyboard.is_pressed('h'):
print('You Pressed A Key!')

You may want to make the process sleep for a while using:
import time
time.sleep(number_of_seconds)

Related

Logging with pynput only every x seconds

I want to use pynput in 2.7 to check for interactions with either the keyboard or the mouse. Since it's not about the actual data (like the keys) I want to keep it simple and check only every x seconds if there is a new input. If there has been one, then the timecode should be logged, if not the script needs to wait for the next input (whenever this may be).
I want to run this script all day long in order to check how much time is spend in which application.
So far I got it together, but the script logs up to 50-60 events per second. Faaaaaar to much data. So, I need to make it wait somehow.
I guess the decisive part of the script is the listener.
With MouseListener(on_move=on_move) as listener:
With KeyboardListener(on_press=on_press) as listener:
listener.join()
How can I alter this part to make it wait after joining?
Adding a time.sleep(5) didn't make a difference. Putting the 5 in the join() brackets (join(5)) as an outtime didn't work either.
Or would I need to make it wait in the
def on_press(key):
# log the timecode
part for instance?
Hope there's an easy solution.
Cheers
Tom

Ignore keyboard event on waitKey() in OpenCV

I'm learning OpenCV and I decided to make a snake game using it. It's almost done but there is a slight problem that seems simple but I couldn't find a solution.
while True:
move()
cv2.imshow('Snake Game', frame)
cv2.waitKey(250)
It's supposed to wait 250 miliseconds before the next frame but key presses break the waiting so game speeds up when I hold down a key. How can I make it ignore the keyboard events and only use time?
I would be very surprised if waitKey didn't stop the waiting after key presses. In fact the name itself suggest that. So basically it's like calling a function called max and then expect the minimum.
From your code and what you've described, you're using waitKey for two reasons:
waiting for some fixed time. That means you're using it to synchronize your game loop.
using it (maybe) to handle key presses for user interaction with the game.
In my opinion, first thing to do is to stop waiting and just keep showing frames continuously as soon as it is ready. And for synchronization you just need to save time for each frame printing. And using that time you update after user interaction or deciding how to process frame or ... One place to help you in that is to look at how game loops are implemented.Take a look here : https://gamedev.stackexchange.com/questions/651/how-should-i-write-a-main-game-loop

Stuck in a loop - Threaded continues while loop prevents code from moving forward (Python)

EDIT:
I apparantly wasn't aware of daemon threads.. This solved the main issue..
Now just puzzling to keep the loop checking for button press, whether it has been pressed or not =)
I'm trying to stop a raspberry pi running code when I press a button (emergency stop button connected to the pins).
So far it's not working out. (In my example code I use code to switch the light of the button to make testing easier).
The threading seems to be working well, however the shell program installed in the pi running the code, first 'test runs' the code to check for errors before actually executing. In my while not read_button() code, the 'checking' of the code gets stuck on the 'while not' until I press the button; not ideal..
Reversing the code and having while read_button() or only if read_button() doesn't actually respond to my button press, since likely the code finishes after checking instead of continuously check.
So.. How to solve this? A continues loop stops my code from proceeding until the while loop is broken (I did join the thread in the end..). A non-continues loop doesn't function, since it won't continuously check for the button press..
To make things worse; after the emergency stop was performed I want the thread to still continue checking for button press after (the user might decide to resume the program and have to hit emergency stop again later on the way within the same code).
I feel like I'm in an endless loop myself trying to fix this =P
(Sorry for the lengthy post and sorry for any noob-terms used, I'm very new to this; only picked programming up 3 weeks ago)
Thank you very much in advance!!
def button_check():
while not read_button(): #developer API
if read_button():
set_button_light(blue=True) #developer API
t = Thread(target=button_check)
t.start()
time.sleep(20) #just to give me time to test
t.join()

What is the best way to pause/stop/command a Python script anytime anywhere?

I have a Python script running selenium framework in a command line and running continuously to control Chrome do background data processing and monitoring. My simplified code structure is as following
while True:
Do_task1() # a blocking function
Do_task2() # another blocking fucntion
... # calling many blocking functions below, including wait(), time.sleep()
I need a way to interrupt the script anytime and anywhere to pause, terminate safely and give commands. What are the best ways to do this?
I've thought and tried of several ways but I am not exactly sure how to approach it:
I tried this:
if msvcrt.kbhit():
key = msvcrt.getch().decode("utf-8").lower()
if key == "j":
self.setting1 = True
elif key == "k":
self.setting2 = True
in the while loop, but it has to pass through bunch of blocking calls before reacting to my keypresses. And the command isn't exactly accepting my keyboard input in real time, that is I'll enter a character input, and I think it will be in the background buffer, then once the code execution reaches the code above, it starts to do stuff.
For terminating the script, I just do Ctrl-C in the CMD window, which I don't think it's the best way, and I should properly end the program ending background processes like Chromedriver.
I thought of having a GUI which runs somehow asynchronously and I can have buttons for pausing, and terminating the script. But I am not exactly sure how to approach it, or if this is a good idea to even try. Any suggestion is welcomed.
Use a script monitoring/workflow monitoring framework like AirBnB's Airflow or Luigi. I had only done brief research on this.
A related question but I don't need to return exactly where it's left off
I usually use try and except to do this
while True:
try:
Do_Task1()
Do_Task2()
except KeyBoardInterrrupt:
break

AutoKey repeating loop

I have been searching forums and the web for hours looking into a way of making a repeating python loop for Autokey. The goal is to allow timed intervals of key presses, such as pressing "1" every 16 seconds, "2" every 30, so on and so forth for as many keys as I may need (likely less than 8). I would also want to be able to end this process at the click of any combination. I have been testing looping only 1 keyboard input every 5 seconds, and I can easily make that work. I am fairly new to python and coding in general, and what has worked for me in the past does not here. I've tried:
import time
import sys
try:
while True:
time.sleep(5)
keyboard.send_key("4")
except KeyboardInterrupt:
exit(0)
sys.exit(0)
and variations there of, such as switching the while loop and try/except. It feels as though my keyboardinterrupt is not working properly, I've used ctrl -c and ctrl break, to no avail. Any help is appreciated. Thank you in advance.
I have a similar requirement, and from my searching, I found a comment from AutoKey developer.
These codes could be what you need:
while True:
retCode = keyboard.wait_for_keypress(
'c', modifiers=['<ctrl>'], timeOut=5)
if retCode:
break
keyboard.send_key("4")
KeyboardInterrupt only catches Ctrl+C if it was send to the controlling terminal. This means that if you're pressing Ctrl+C from a different window, it will not catch.
To work around this, you need to register a keyboard shortcut on Ctrl+C, and have it send a signal to your main script.

Categories