Replace while true loops [closed] - python

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
I was the other day trying to create on python a little program who would detect if the key x is pressed, if yes the program continue and do it's task. i found the way to do it with the package keyboard :
while True :
if keyboard.is_pressed("x"):
...
But it appears that the while true loop after a long time, start bugging, and that brought to ask you, if it is possible to do a loop or something to detect a key press without causing lags like the window system events when you click on a shortcut then a program appears.
Thank you.

The keyboard documentation specifically says NOT to use the method you are using:
import keyboard
# Don't do this!
#
#while True:
# if keyboard.is_pressed('x'):
# print('x was pressed!')
#
# This will use 100% of your CPU and print the message many times.
# Do this instead
while True:
keyboard.wait('x')
print('x was pressed! Waiting on it again...')
# or this
keyboard.add_hotkey('x', lambda: print('x was pressed!'))
keyboard.wait()
I would recommend reading the documentation for your specific needs.
Note:
If you are looking to bind the specific key to a function, you could do something like this:
import keyboard
def on_x_key_press():
print("'x' key pressed")
keyboard.on_press_key("x", on_x_key_press)

Now your computer runs through that loop as fast as it can. I think you could add a limit on how many times the keyboard press is checked.
import time
while True:
if keyboard.is_pressed("x"):
...
time.sleep(0.001) # the program just sleeps for 0.001 seconds
If the program still lags, try to increment the value of seconds to wait (for example: from 0.001 to 0.005).

Related

How to implement an asynchronous function in python 3

I'm very new to programming as a whole. Had some basic experience with C++ and HTML, like simple calculators and other really basic stuff(I started learning on my own a few months ago) and because of this I'm not even sure if I am posting this question correctly. Maybe it goes without saying but I am new to stackoverflow as well(My first post!), so I may do some things wrong here and I kindly ask for your comprehension. Any constructive criticism is more than welcome!
So here's my problem: I am trying to make a simple chatting program in Python 3, but here's the catch: I want to use python's asychronous capabilities to allow the user to terminate the program at any given time the esc key is pressed. I've looked into a few libraries already, such as pynput, asyncio, tornado and getch(). But no matter how I change my code I just can't seem to reach my goal here.
I made an async function called runalways() that's supposed to run during the entire duration of the program, parallel to the other functions. But it doesn't and I couldn't figure out why...
I'm sorry if I couldn't explain my issue properly. Some terms and concepts are still rather blurry to me, but hopefully it won't be so for long. I'll leave the code I have so far which does a good job implementing the chat function, but that's about it. The async bit is basically inexistent at this moment.
It would be really appreciated if someone could explain what I'm missing:
import time, asyncio
from msvcrt import getch
# Creates a chat-like effect
def typing(text):
for i in text:
print(i, end=" ")
time.sleep(0.1)
time.sleep(1.0)
# Terminates the program
def termination():
print("Program terminated")
time.sleep(0.5)
SystemExit
# Defines async function to read pressed keys and terminate if Esc is pressed
# (Not working)
async def runalways():
while True:
print(ord(getch()))
key = ord(getch())
if key == 27: # Esc
termination()
# Initialize chatting
def startChat():
typing("\nHello!\n")
typing("How are you?\n\n")
typing("Answer:\t")
x = input()
typing("\nAnyways, that isn't relevant right now.\n")
time.sleep(0.5)
typing("Can we get started?\n\n")
typing("Answer(Y/N):\t")
x = input()
# validates input
while (x != "Y") & (x != "N"):
typing("\nHey, don't go fooling around now. Keep it real! Try again.\n\n")
typing("Answer(Y/N):\t")
x = input()
if (x == "Y") | (x == "y"):
typing("\nThere you go! Now, let's go through the basics...\n\n")
termination()
elif (x == "N") | (x == "n"):
typing("\nSorry to hear that... See you next time, then!")
termination()
# Defines starter point for the program
def main():
runalways()
startChat()
main()
I will try my best to clarify any questions that may help the understanding of my issue. Thanks in advance!
You have two functions competing to grab the input. runalways wants to grab them with getch, while your main chat loop is trying with input. The two processes conflict; only one can consume each character. Whenever one thread grabs input, the other gets to claim the buffer for the next input.
Instead, you need to set up a single input channel that terminates immediately on ESC; otherwise, it echoes to the terminal and passes the character to the main loop (or buffers it until EOL appears).

Function doesn't work in another function with sleep [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I have a function that scrapes websites and returns a statement that is depending if it found certain keywords. This function is called checksite. When I run the function on its own it works great but I can't get it to work inside another function together with time.sleep.
This works great
checksite()
This does not work
while True:
checksite()
time.sleep(10)
I want the checksite-function run every 10 second. All help is appreciated!
Your code should work. To check what is wrong, you could use this:
def checksite():
#blahblah
while True:
print('starting')
checksite()
print('site checked')
time.sleep(10)
print('sleep function complete')
Then maybe you will get an idea of what is wrong.
It is important to know what the checktime() execution does.
If you dont see anything happening after 10 seconds and the script still executing more than expected, my first suggestion would be to know how much time the execution takes.
You can run this and get the amount of time:
import time
import datetime
def checktime():
#Doing some execution
print('execution...')
#Use:
while True:
started = datetime.datetime.now()
checktime()
time.sleep(10)
executed = datetime.datetime.now()
print('The script runtime is: {0}'.format(executed - started))

Adding reading some character in while loop

I am reading serial data in while loop, I want to add something in code that if I press t than something should be print otherwise while loop should work. I tried to use readchar, but it wait for me to press some key, I dont want it to wait. I want while loop to work till I press some key
Raspberry pi 2.7
while True:
data = s.recv(xxx)
print(data)
if (x == t)
print(Hello)
else:
continue
it is waiting if i use read char.
There are lots of questions already asked on similar topics which would solve your problem. Some of them include the following:
Loubo's "detect key press in python" here on SO, as well as Spae's "Python key press, detect (in terminal, no enter or pause)".
You could use:
import keyboard as kb
num = 0
while True:
if kb.is_pressed('t'):
num += 1
print (num)
Besides that, you have grammar and indentation errors.
Please consult this post on the SO Meta so further problems like this do not occur.

How to have an updating prompt while waiting for input in python?

So the question is how to have an input function or stdin.readline function waiting for an input, while having an updating prompt i.e. The prompt contains the time in format HH:MM:SS and is refreshing every second like:
while 1:
sys.stdout.write('\r' + time.strftime(TIME_FORMAT) + ' :>')
time.sleep(1.0)
But as soon as you add an input there, of course the program waits until you write some input. The version of python I am using is 3.5.
I know I should use curses, but I am planing to write a cross-platform program and the only module I have found is clint, but it didn't have anything in the documentation on the updating prompt.
I have found something that got pretty close but has different problems:
def input_thread(L):
x = input()
L.append(x)
L = []
thread = threading.Thread(target=input_thread, args=(L,))
thread.start()
while 1:
sys.stdout.write('\r' + time.strftime(TIME_FORMAT) + '>:')
time.sleep(1.0)
sys.stdout.flush()
Now the problem remains is that when you type the input but do not press ENTER, the input on the next iteration remains but when you write something, the previous input gets replaced by the current one. Of course the previous inputs are still there in the argument L, so there is no lost input. I hope I didn't describe this to confusing.
If there is no easy way of doing this as it could be done with curses, I'm open to similar cross open tools. Thanks for your time and answers!
So, I figured out what I wanted, a few months ago but didn't answered my own quesiton.
To have a prompt with updating time, you need a separate threads that:
Updates the prompt with additional input
Catches your key strokes
The second thread handles every key-stroke and you can program it how to handle the pressed keys.
When pressing a key, the thread that updates the prompt adds the pressed keys. Also you have to configure some shortcuts for Return, Backspace, etc... to work as expected
I've got it to work and unfortunately... I don't like it. If anyone would like to see the code I will happily provide.

Input with time limit/countdown [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I'm pretty new to Python and would like to write a (not computer) language trainer for my students. Just something like where a timer runs in the background and the student has to input words quickly to slow down/revert the countdown - otherwise the countdown reaches zero and displays some "game over" message. (Just like when a special agent has to defuse a bomb while the timer races towards zero.)
There are tons of explanations of threading which sounds like the right way to do it, sure, but so far I haven't found anything where a timer is combined with a (time-limited) raw_input. Could any of you pros give me a pointer to the tutorial/discussion I have overlooked?
import threading
import time
import os
def ask():
"""
Simple function where you ask him his name, if he answers
you print message and exit
"""
name = raw_input("Tell me your name, you have 5 seconds: ")
exit_message = "Wohoho you did it..Your name is %s" % name
exit(exit_message)
def exit(msg):
"""
Exit function, prints something and then exits using OS
Please note you cannot use sys.exit when threading..
You need to use os._exit instead
"""
print(msg)
os._exit(1)
def close_if_time_pass(seconds):
"""
Threading function, after N seconds print something and exit program
"""
time.sleep(seconds)
exit("Time passed, I still don't know your name..")
def main():
# define close_if_time_pass as a threading function, 5 as an argument
t = threading.Thread(target=close_if_time_pass,args=(5,))
# start threading
t.start()
# ask him his name
ask()
if __name__ == "__main__":
main()
You don't have to do it via threading, you could in a single thread run through your 'logic' at a specific frequency and each iteration recalculate the countdown via a time-delta method. This is how many video games are produced.
Lets say you run this pseudo-code method at 60hz:
delta = timenow-timelast;
countdown -= delta;
if(input)
processInputHere;
You should be able to convert the pseudo-code to python code to make it work

Categories

Resources