Getting user input while letting other code run - python

I'm making a Discord client (in old discord.py). Discord requires regular communications or else it will close the connection and subsequently make my program crash. My client requires user input (via input command) for the message which prevents the request from being made and making it crash.
Is there a way to ask for user input and let other code run in the background?

Use threading:
from _thread import start_new_thread as thread
def othercode(): # Code which will execute during input
print("bloop")
def inputcode(): # Code which will recieve input
global thing
thing = input("input: ")
thread(othercode) # Start a thread
inputcode() # STart the input script on the main thread

Related

How do I use Tkinter and Telebot together?

I've been working on a Python project where I'm stuck at one point. Basically, I have a GUI that updates automatically once 5 seconds. I have done it using the method .after(5000, main) where main function looks like the following.
def main():
global lastthreshold
global run
global lastaction
global bakiye
global lif
global gsecenek
paributl, binancedolar, paribudolar, dolar = getData()
farklow, farkhigh = diff(paributl, binancedolar, paribudolar)
data = guiDataMaker(paributl, binancedolar, paribudolar, farklow, farkhigh)
gui = Gui(data, dolar, lastthreshold, alsatmiktar, bakiye)
#print(*data, sep="\n")
#print(*cooldown.items(), sep="\n")
if run:
lif = gui.gui()
for i in paributl.keys():
cooldown[i] = "NONE"
run = False
gui.secenek.set(gsecenek)
runbot = runBot(lastthreshold, bakiye, data, cooldown, alsatmiktar)
if runbot[0] != None:
currency, guncelfark, fiyat, newbakiye, buydate, islem = runbot
bakiye = newbakiye
guncelislem = (currency, guncelfark, fiyat, newbakiye, buydate, islem)
lastaction = (currency, guncelfark, fiyat, newbakiye, buydate, islem)
gui.updateGuiData(lif, cooldown, guncelislem)
else:
gui.updateGuiData(lif, cooldown, lastaction)
src.after(5000, main)
src.mainloop()
main()
#src.mainloop()
#bot.polling()
My actual code is something around 450 lines, so I think pasting it here would be a waste of space. Though, I can do that if it helps you help me more easily. Anyway, the above code works perfectly with a single thread which is created by src.mainloop().
In the project, what I'm trying to do is basically a trading bot. To help the user see what is going on, I created a gui using Tkinter library. I create the gui only once and I only update the data every 5 seconds.
What I want to achieve is to create a Telegram Bot which the user can interact with. For example use should be able to type /BTC-USD to get information about bitcoin-dolar. So far, I achieved to send the user every buy/sell operation of the bot in telegram. However, what I'm stuck right now is to get commands of the user since it requires me to use bot.polling() which is another thread. Wherever I put this line of code in my code, it causes GUI to "not responding".
So in simpler words, my question is how can I have a Telegram Bot interacting with a user by sending messages and getting commands, also a GUI that is updated automatically every 5 seconds?

Want to add a "Do You want to close the program" warning message in python

I am making a python program which takes a lot's of user input. And If user by mistake close the program all the data stored in variables are gone. So, I want to make something like warning message like "Do you want to close the program" appear when ever user click on close button or do shortcut like alt+F4 to close program. I just want it for making my program much better. Cuz, If some one had input many data and he by mistake close
the program and all the progress for him and my program as lost. So to overcome this I want to to know to make something like warning message appear whenever user try to close the program.
This can be done with the signal library. This is a built in library that can asynchronously handle user events in Python. You can read more in the Python Documentation.
Here is a simple example that I typically use to remind myself. (As a note, this was inspired by this SO post from eight years ago):
import signal
import sys
def yay():
x = 0
while True:
x += 1
print(x)
def terminate_catcher(signum, frame):
#Restoring sigint in case user hits Ctrl+C for real to avoid loop
signal.signal(signal.SIGINT, actual_sigint)
#Some conditional
if input("Are you sure? (Y/N)") == "Y":
sys.exit(1)
#Restore the signal catcher if the user decides not to cancel
signal.signal(signal.SIGINT, terminate_catcher)
if __name__ == '__main__':
# store the original SIGINT handler
actual_sigint = signal.getsignal(signal.SIGINT)
signal.signal(signal.SIGINT, terminate_catcher)
yay()
Essentially, the main function registers an event handler that is called whenever the SIGINT interrupt is called. Whenever the function runs, it restores the handler back to the original SIGINT handler in case the user hits ^C one more time while the exception is being handled so we can avoid an infinite loop. Whenever the function is triggered, it just asks the user if they want to leave and uses system.exit(1) if they say yes. If the user decides to stay, it restores the handler for future events.

How to interrupt in python

my subscribe function will call on_message function everytime that have message from websocket
and unsubscribe when message is STOP
is_sub = True
def on_message(msg):
print(msg)
if msg == "STOP":
unsubscribe(key)
is_sub = False
#continue to code
print("Start")
key = subscribe(on_message)
while is_sub:
print("on sub")
time.sleep(1)
#cotinue here
print("End")
without while loop the code will end and not recive any more message.
I want to find the better way (without time.sleep) to interrupt and continue the code
ps. I can't edit subscribe and unsubscribe function
You could run the instance of your websocket server in a separate thread. This will allow you to still continue to run your main thread while your webserver is listening to incoming messages.
I think you can't do it without a while loop. If you want to free your main thread you can do your message subscription on separate thread but that's not what you want I guess. Most WebSocket client would provide a method to keep the connection alive. for example this provides a run_forever() methods which does the 'while loop' part for you. If you are using a client there is a chance that they provide methods for keeping the connection alive. I suggest you go through the documentation once more.
If you want to continue the code, you could use the continue() command and if you want to stop, you could use the break() command.

How to send and receive data from python to arduino at the same time

I currently have an arduino code, which is connected to three sensors: temperature, pressure and humidity. I would like to make a code in python that of an order (by int or strg), this sends the type of sensor that I want to read, example: if I enter by keyboard 1, it constantly sends me temperature data; if income 2, send me pressure data; and thus be able to enter any digit at any time.
Pd: Sorry my bad english,I don't know if i could explain my problem
I have a similar code in arduino with switch case, and it works perfectly. but I can not make it work in python since when I put raw_input (), the program stops waiting for input and stops reading the sensor data.
Python
import serial
import time
ser=serial.Serial('/dev/ttyUSB0',baudrate=115200)
while 1:
ser.setDRT(False)
#c=raw_input()
#ser.write(c)
med=a.readline()
print med
this just works fine to read data from one sensor type assigned by default
If you have tasks, that needs to run in parallel, you can use threads. One thread gets the sensor data and the other waits for input.
Python has a very easy to use builtin module for threading.
Official python docs: https://docs.python.org/3.7/library/threading.html
Tutoialspoint: https://www.tutorialspoint.com/python/python_multithreading.htm
A very simple implementation example might look like this:
import threading
def wait_input():
while True:
user_input = input()
# do something with user_input
def get_sonsordata()
while True:
med=a.readline()
print(med)
input_thread = threading.Thread(target=wait_input)
input_thread.start()
sensor_thread = threading.Thread(target=get_sonsordata)
sensor_thread.start()

Python MP3Play with Threading

I am trying to create an MP3Player with python (not using any fancy GUIs, just basic command-line). You are able to input commands like "playlist" which prints all songs or "play [num]" which plays the specified song in your playlist. I can do this all in the one thread, but what I want is to create another thread so you can do more commands like "add song" or "delete song" while the actual music is playing (instead of the command line waiting for the music to finish). Here is what I have with one thread:
import mp3play, time
clip = mp3play.load(song)
clip.play()
time.sleep(clip.seconds()) #Waits the duration of the song
clip.stop()
#Command line asks for input after this
This works all fine and dandy, but when I try to implement threading into this, like this:
import mp3play, time
def play(songname):
clip = mp3play.load(song)
clip.play()
time.sleep(clip.seconds()) #Waits the duration of the song
clip.stop()
#Get user input here
#Check if user inputted command
#User inputed "play"
thread.start_new_thread(play,("some_random_song.mp3",))
It glitches out. It all seems fine until you close the application half way through the song and the music still keeps running. To stop the music, I have to open Task Manager and end the task. So I thought about having a "stop" command as well, which wouldn't close the thread, but it would use
clip.stop()
I don't know what happens if you try to stop() a clip that isn't running, so I implemented a prevention system (boolean running that checks if it is or not). But now nothing works, so far here is my code:
def play(filename):
global clip
clip.play()
time.sleep(clip.seconds())
clip.stop()
playing = False
clip = ""
#Get user input
#blah blah blah command stuff
#User inputted "play"
thread.start_new_thread(play,("some_random_song.mp3",))
playing = True
#Goes back to command line
#User inputted 'stop' this time
if playing:
clip.stop()
playing = False
But when I try to run this, it gets to clip.play() in the thread but doesnt start it. Im not sure how I can get around this, and if it's possible to do this without threading. Thanks in advance.
It would be better to play MP3's using a different process, using multiprocessing.Process.
Write a function that takes the path to an MP3 file, and start that as a Process.
For technical reasons, the dominant python implementation (from python.org) restricts threading so that only one thread at a time can be executing python bytecode. This will probably never be glitch free.

Categories