Logging with pynput only every x seconds - python

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

Related

How to correctly stop pyqt5 QThread?

There is a program for pyqt5. It has a thread (qthread) in which you need to perform some action with a certain front end. I used QThread.msleep to define this period, and the flag that came out of the while cycle.
But if the period is long, then it will take a long time to wait for the exit from the loop, and I want to finish it as soon as I click on the button in the GUI (but not kill, start again soon).
The source code is pretty standard here, I need ideas.
An example of an exaggerated class for a separate thread.
class intrhead(QObject):
...
def run(self):
while(flag):
...
QThread.msleep(period)
The correct solution is to split the period.

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

How to make python script more efficient while loop

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)

How to run tasks periodically without interrupting the whole program

I have a program that constantly runs if it receives an input, it'll do a task then go right back to awaiting input. I'm attempting to add a feature that will ping a gaming server every 5 minutes, and if the results every change, it will notify me. Problem is, if I attempt to implement this, the program halts at this function and won't go on to the part where I can then input. I believe I need multithreading/multiprocessing, but I have no experience with that, and after almost 2 hours of researching and wrestling with it, I haven't been able to figure it out.
I have tried to use the recursive program I found here but haven't been able to adapt it properly, but I feel this is where I was closest. I believe I can run this as two separate scripts, but then I have to pipe the data around and it would become messier. It would be best for the rest of the program to keep everything on one script.
'''python
def regular_ping(IP):
last_status = None
while True:
present_status = ping_status(IP) #ping_status(IP) being another
#program that will return info I
#need
if present_status != last_status:
notify_output(present_status) #notify_output(msg) being a
#program that will notify me of
# a change
last_status = present_status
time.sleep(300)
'''
I would like this bit of code to run on its own, notifying me of a change (if there is one) every 5 minutes, while the rest of my program also runs and accepts inputs. Instead, the program stops at this function and won't run past it. Any help would be much appreciated, thanks!
You can use a thread or a process for this. But since this is not a CPU bound operation, overhead of dedicating a process is not worth it. So a thread would be enough. You can implement it as follows:
import threading
thread = threading.Thread(target=regular_ping, args=(ip,))
thread.start()
# Rest of the program
thread.join()

Executing code after waiting for time in background (Python)

I'm making a personal assistant like Google Assistant or Siri, and I want the user to be able to set reminders. For example, if they type "Remind me to wash the dishes at 5pm" I would like it to pop up later and remind them. However I also want code to be able to run while waiting, so you could set multiple reminders or check the weather.
time.sleep simply stops the program. I'm pretty sure there's a way to do it with threads but I'm not sure how. Please help!
Python threading has a Timer which does exactly what you ask for:
from datetime import datetime
from threading import Timer
def create_notification(time, name):
delay = (time - datetime.now()).total_seconds()
Timer(delay, show_notification, args=[name]).start()
def show_notification(name):
print(f'notification: {name}!')
create_notification(datetime(2034, 1, 1), 'Hello future!')
One thing to watch out for is this approach creates a single thread for each event (which doesn't scale well for lots of events). This also suffers from the problem that if the user closes your program, your program crashes, computer shuts down, power loss, etc. you lose all of your notifications. If you need to handle this, then save them to a file. If you need the notifications to show up even when your program isn't running look into solutions provided by the OS like cronjobs.

Categories