I want to make a system in python what was listen to keypresses and when I hit enter something happens depends on the value of the command I write.
How can I do this?
I try to write this:
import keyboard
def run_buffer(cmd):
print("\nThe buffer value is: {}, The buffer size is: {}".format(cmd, len(cmd)), end="")
buffer = ""
def on_press(e):
global buffer
if e.name == "enter": # When I hit enter I need to run the 'command' and emtpy the buffer.
run_buffer(buffer)
buffer = ""
elif e.name == "backspace":
buffer = buffer[0:-1]
elif e.name == "f4":
print("Asd")
elif len(e.name) == 1:
buffer += e.name
keyboard.on_press(on_press)
while True: # This was just for the script has runtime and won't stop immediately.
a = 0
When I run the script sometimes works perfectly, but sometimes it's just too late and the cursor not follow my expectations.
I get this in the console
I hope someone can help me :D
Thanks for help, and sorry for my bad English.
Related
I am trying to make a simple AFK script for if I need to leave my pc for short period and the code works on it's own but when I try to use one script to run another, It runs but then stops a few seconds later with exit code 0. I'm not sure what's wrong and I've tried multiple things such as:
import test1
test1.run()
And that doesn't seem to work. Every site I find tells me to use the above example or stuff such as exec which I've been told is dangerous. Note: a text file named 'bridge' will have to be created so the file can be stopped
main.py
import os
from output import run
import keyboard
from time import sleep
print('Start afk program? (Y/N)')
cmd = str.lower(input('> '))
if cmd == 'y':
print('Use X to Stop')
print('Starting in 10 seconds...')
run()
while True:
if keyboard.is_pressed('x'):
print('exit key pressed')
x = '1'
else:
x = '0'
if os.path.exists('bridge.txt'):
with open('bridge.txt', 'w') as file:
file.write(x)
file.write('\n')
file.close()
else:
exit('file not found')
if x == '1':
exit(0)
sleep(0.1)
output.py
import os
from time import sleep
from pynput.keyboard import Controller
keyboard = Controller()
def run():
global keyboard
sleep(10)
keyboard = Controller()
count = 0
while True:
if os.path.exists('bridge.txt'):
with open('bridge.txt', 'r') as file:
content = file.readlines()
for line in content:
if line[0] == '1':
exit(0)
if count == 1:
press_key('w')
elif count == 2:
press_key('a')
elif count == 3:
press_key('s')
elif count == 4:
press_key('d')
elif count == 10:
count = 0
press_key('q')
count += 1
sleep(0.1)
def press_key(key):
keyboard.press(key)
sleep(0.5)
keyboard.release(key)
run()
I get that having the two systems apart can be easily avoided and will be fixed later, but the answer to this question will help me with other projects
For me (Python 3.8), your code works fine if you simply type on the terminal
python main.py
provided that you comment out or delete the last line in output.py:
# run()
which would execute function run upon importing output in main. The program also works if I import from a local module
import output
output.run()
If for some reason you're trying to import output from a different directory, you may have to deal with relative imports -- a subject nothing to do with the specific implementation of your scripts.
This code seems to have couple of problems from initial check.
Since you are calling run() before the if keyboard.is_pressed('x'):, it will always run in infinite loop.
Also, if line[0] == '1':, this needs to be changed to if line[-1] == '1': to check the last character entered, but since the code never reached the line to take x as input, entering a value x will not work either.
There are logical errors here.
I tried making a while loop, however, I can't break it. I am new to programming and maybe I am bitting more than I can chew, but I would be grateful if someone could help me. I am using pywhatkit and I have a problem defining the searching variable.
import pywhatkit as pwt
def searching_mode():
searching = (input(''))
while True:
print(f"Searching ...")
if searching == pwt.search(input('')):
continue
else:
searching == (input('exit'))
break
searching_mode()
Your input should be in while loop so it can continue execute the input when there's no input or break when the input is 'exit'. Try this:
import pywhatkit as pwt
def searching_mode():
while True:
searching = input('Search for? (type "exit" to exit) : ')
if 'exit' in searching:
break
elif not searching:
continue
else:
print(f'Searching for "{searching}"...')
pwt.search(searching)
searching_mode()
Output:
Search for? (type "exit" to exit) : python course
Searching for "python course"...
Search for? (type "exit" to exit) :
Search for? (type "exit" to exit) : stackoverflow python while loop
Searching for "stackoverflow python while loop"...
Search for? (type "exit" to exit) : exit
Process finished with exit code 0
Hi if you can give more information about what you want to achiev and give full script can help better. But you can try setting up a switch to break a loop for example;
def searching_mode():
switch = True:
searching = (input(''))
while switch:
print(f"Searching ...")
if searching == pwt.search(input('')):
continue
else:
searching == (input('exit'))
switch = False
searching_mode()
While loop will continue to run if you construct like "while True", so you can setup a condition to break from it. by using
while switch:
if condition1:
#do something:
else:
#do this
switch = False
# so next time it
I'm writing code for an alarm system that runs for a predefined amount of time and allows a user to input code up to three times. If the code isn't entered correctly within 3 times I have a print statement (will eventually append this with more code) that works as defined, the problem is I need the timeout to execute some code similarly. As in, if timeout then do this as well, (essentially go to the same line of code the input failure goes to)
TIMEOUT = 7 # number of seconds your want for timeout
keycode ="0000";
count = 3
def interrupted(signum, frame):
"called when read times out"
print ('Input timeout!! Contacting Owner!')
signal.signal(signal.SIGALRM, interrupted)
def input():
try:
count = 3
for i in range(3,0,-1):
userIn= raw_input("Enter the security code to disable the alarm
system\n");
if userIn != keycode :
count = count-1;
print ("Incorrect Password...Tries Remaining", count);
else:
print("Password accepted, security system offline");
#BRANCHING CODE GOES HERE
break
if count == 0:
print("Contacting Owner!");
#BRANCHING CODE GOES HERE
except:
return
# set alarm
signal.alarm(TIMEOUT)
s = input()
# disable the alarm after success
signal.alarm(0)
After timeout, message prints Input timeout!! Contacting Owner!, but the user can still enter a password. This is obviously not a very good alarm system! Ideally I could create an or statement at the "if count == 0 or TIMEOUT: True" kind of thing.
For some reason adding this little bit of code to the definition section solved the problem
I don't know why, and I don't know how, but getting rid of the 0 on return0 or moving it a space away breaks the codes functionality. If anyone can explain why that would be amazing.
a = 1 ;
def interrupted(signum, frame):
a = 0;
"called when read times out"
print ('Input timeout!! Contacting Owner!');
if a == 0:
return0
signal.signal(signal.SIGALRM, interrupted)
Sorry I'm new to programming, and don't really understand how this Thread thing works. My goal was for this input to be timed, and I found some code that does that. However, I'm confused about the structure of this Thread because if you are "too slow", the program never continues on to print "checkpoint" as desired. It just sort of... freezes... Why is it getting stuck?
import time
from threading import Thread
answer = None
def check():
# waits for user input for 3 seconds
for i in range(3):
time.sleep(1)
if answer != None:
return
print('too slow')
Thread(target = check).start()
answer = input("Input something: ")
print('checkpoint')
One thing I tried is:
t = Thread(target = check)
t.start()
answer = input("Input something: ")
# also tried t.join()
if t.is_alive:
print('hi')
I tried to solve this program by trying to raise and catch an exception. However, I couldn't catch the exception. How do I catch it? (Or is there another solution to the problem I am having?)
import time
from threading import Thread
answer = None
def check():
# waits for user input for 3 seconds
for i in range(3):
time.sleep(1)
if answer != None:
return
print('too slow')
# was hoping to catch this as an exception
raise TimeoutError
# starts new thread
Thread(target = check).start()
# prompts user for an input
answer = input("Input something: ")
print('checkpoint')
What's good:
When you type something into the input prompt within 3 seconds, it prints "checkpoint" and continues on with code.
What's bad:
If you take "too long", the program prints "too slow!" as expected, BUT then it stops executing code and just sort of... freezes. So to try to fix this, I was hoping to raise a Timeout Error and then catch it, but I don't know how to catch it. This didn't catch the error:
try:
Thread(target = check).start()
except:
pass
This didn't either:
try:
answer = input("Input something: ")
except:
pass
Could I get some help? Thank you!
Edit: Forgot to mention that I am using linux so a lot of the solutions for my application did not work for me like msvcrt or keyboard. And modules that do work for Linux seem not to be "non-blocking."
You should think of the two threads as two separate programs, but sharing the same variables.
Thread 1 consists of everything that isn't indented in your code. It launches a thread, then it waits for user input, then it prints "checkpoint". Then it's done.
Thread 2 consists of the function check. It checks to see if the variable isn't None. If that happens it's done. If that doesn't happen in three seconds, it prints "too slow" and now it's done.
Neither thread "knows" what the other one is doing, except they share one variable, answer.
The program as a whole will exit when all its threads are finished.
That's it. That's what you've written. So if you type something, the program exits because Thread 1 will always exit after you type something. Thread 2 exits once it sees the variable isn't None.
If you don't type anything, Thread 1 will just sit there and wait for you, forever. That's how the input function works. Thread 2 will exit after 3 seconds or less, but that doesn't affect Thread 1.
You can't throw an Exception from one Thread to another. So you can't throw an exception from Thread 2 and have Thread 1 handle it.
Have you tried typing something AFTER the message "too slow" appears? When you do, Thread 1 (and therefore your program) will exit.
The bottom line is that you can't use the input function in cases like this, because that function blocks the flow of its thread until the user types something. There is nothing any other thread can do to make it continue.
DISCLAIMER: THIS DOESN'T ANSWER THE QUESTION BUT IN CASE YOU WANT TO KNOW HOW I GOT AROUND THE "INPUT" THING, HERE IS MY SOLUTION TO THE PROBLEM.
Actually I found something that works! It's a little strange but it works for what I am trying to do, thanks to #rayryeng 's answer here: detect key press in python?.
Problem Statement: Continue the program when 'enter' is pressed, and timeout if input takes too long. This does exactly that, although it displays strangely to the console... PS. I had to run this in my terminal as 'sudo' or it wouldn't work in my scratch file for whatever reason.
import curses
import os
from time import time, sleep
def main(win):
win.nodelay(True) # True turns on "non-blocking"
key=""
win.clear()
win.addstr("Please press 'Enter' to continue:")
start_time = time()
while 1:
end_time = time()
try:
if end_time-start_time > 5: # 5 seconds
return 'You are too slow!'
else:
key = win.getkey()
if key == os.linesep:
return 'OK. Continuing on...'
except Exception as e:
# No input
pass
p = curses.wrapper(main)
print(p) #-> either 'You are too slow!' or 'OK. Continuing on...'
I guess if you actually wanted to store the input you can modify it to be something like this:
def main(win):
win.nodelay(True) # True turns on "non-blocking"
key=""
win.clear()
win.addstr("Please press 'Enter' to continue:")
start_time = time()
while 1:
end_time = time()
try:
if end_time-start_time > 5: # 5 seconds
return 'You are too slow!'
else:
key = win.getkey() # gets a single char
if key: # == os.linesep:
return str(key) # returns that single char
except Exception as e:
# No input
pass
p = curses.wrapper(main)
print(p) #-> either 'You are too slow!' or character entered
And if you want to store more characters you could do something like this (just be aware that it also stores the "enter" key in the resulting string):
import curses
import os
from time import time, sleep
def main(win):
win.nodelay(True) # True turns on "non-blocking"
key=""
win.clear()
win.addstr("Please press 'Enter' to continue:")
start_time = time()
result = key # empty string
while 1:
end_time = time()
try:
if end_time-start_time > 5: # 5 seconds
return 'You are too slow!'
else:
key = win.getkey() # gets single char
result = result + str(key) # adds characters to the empty string
if key == os.linesep: # "new line"
return result
except Exception as e:
# No input
pass
p = curses.wrapper(main)
print(p) #-> either 'You are too slow!' or characters entered
I'm working on a Python script using Blessed and can't get the 'hidden_cursor()' function to work properly.
It will successfully hide the cursor but it won't set the visibility back on exit.
This is what I tried so far:
with term.hidden_cursor():
while True:
command = raw_input (term.move(27, 2) + "")
if command == "X":
os.system('clear')
sys.exit()
else:
os.system('clear')
main('self')
And here's the full script: https://gist.github.com/lovemac15/c5e71e0b8aa428693e5b
Thanks! :D
Try changing the control flow to be sure to exit the with block:
with term.hidden_cursor():
while True:
command = raw_input (term.move(27, 2) + "")
if command == "X":
os.system('clear')
sys.exit()
else:
os.system('clear')
break
main('self')