How to detect user inactivity time in python application (Linux)? - python

I am wondering if there is any way that when I ask for user input, if there is a way to detect how many seconds have passed since asking for user input?
I would like to be able to have some kind of timer, that if the user hasn't entered an answer and pressed enter for 15 minutes, to jump to another function, or set the user input to some default value and continue on.
Here is the input for the user:
res = input('Test result? "(P)ass,(F)ail,(R)etry,(S)ave and Quit,(Q)uit": ')
after 15 minutes(900 secs), set res = "S" and continue on.
Or something similar.
My investigation into something similar has lead me to believe the solution is likely not cross-platform. And I am running this script in Red Hat Linux. Also, I am accessing and executing the script via PuTTY.
Any help would be greatly appreciated.
Thank you.

It is actually easy to do this in a cross platform way.
You should be able to do this by launching a thread to handle the user input, and monitoring both the thread and the time from the main loop.
Some relevant points:
The threading module's doc can be found here.
Your code
res = input('Test result? "(P)ass,(F)ail,(R)etry,(S)ave and Quit,(Q)uit": ')
should run from the child thread.
For the resolution you need, you can monitor the time via the time module.

Related

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.

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

Python help - Need the ability to restart the script when it hangs or automatically set a timer

I currently have a python script that does exactly what I need it to do, however every now and then the script will hang and the only way to restart it is by killing the script and relaunching it.
I was wondering if there was a way to put in a few commands that will restart it lets say everytime it hangs or when a specific message appears or even just restart it on a timer eg:every 50 seconds.
I cannot provide the code through here, but I can provide it if we talk in private.
I am willing to pay you a bit of money if your fix does work.
please email me at stackoverflow1#shaw.ca
Thanks!
Edit: I see, ok - then is it possible to provide me with some codes which it will restart on a specific timer?
Edit2: Ok thanks everyone for their comments - I will get in touch with the person who built it to see if they can rewrite it from scratch to include a timer.
Cheers.
Feel free to pay me if you want, although it is by no means necessary.
Here:
import time
import threading
import os
def restart():
time.sleep(50)
os.execv('/full/path/to/this/script', ['second argument', 'third argument'])
def main():
t = threading.Thread(target=restart, args=(), name='reset')
t.start()
# ... The rest of your code.
If you have any buffers open that you care about (such as stdout) you'll want to flush them right before the call to execv up there.
I haven't tested this code, because I don't have a python interpreter handy at the moment, but I'd be surprised if it didn't work. That call to execv replaces the current context, so you don't get an increasingly deep hierarchy of child processes. All I'm doing, in case you're curious and want to know what magic phrase to google, is setting a "timer interrupt handler". For the pedants, no, I recognize this thing isn't directly handling any interrupts.
The numeric argument to sleep is in seconds. I would simply request that you not use my code in malware, unless it is for research purposes. I'm particular that way.
edit: Additionally, a lot of it was taken from here.

In Python, how could I get a user input while simultaneously running the script?

In my program I am trying to take the chat from a website and printing it on my console. While that's going on I'm using raw_input to get chat from whoever is using it. My problem is that raw_input pauses the rest of the script until i say something or press enter. Is there a simple way to fix this?
You have to multithread. One thread for user input and another for the background tasks.
The documentation is a bit complex (I'm pretty confused by it), but it's a start: http://docs.python.org/library/threading.html
You may also want to look into the curses module: http://docs.python.org/library/curses.html

Categories