Python does't run some lines of code as it should - python

can someone help me with this code? It's use is to make timed input for 2 seconds and it needs to print the last line even if the user did or didn't type something in the console (for that time). When I don't type in anything, after printing "Too Slow" it asks me for the same input, so I added IF, but it doesn't really notice it. I hope that someone can help me. Thanks!
import time
from threading import Thread
i = 0
answer = None
def check():
time.sleep(2)
if answer != None:
return
print("Too Slow") #prints this if nothing is typed in (for 2 seconds)
if i == 0:
i = 1
Thread(target = check).start()
answer = input("Input something: ") #program doesn't even notice IF and asks me the second time for input
print("This should be printed instantly after printing Too Slow (when user doesn't input anything)")

The return in the check function only causes the thread to be completed, but the call to input is independent of that thread and thus not interrupted when the check function completes. See this answer for an alternative solution using the signal module.

Related

Is there a way to cancel an input() in Python 3.8 after a certain period of time? [duplicate]

This question already has answers here:
Keyboard input with timeout?
(28 answers)
Closed 2 years ago.
I'm writing a program in Python 3.8. I'd like to make an input, let's say variable v. If v is input as "n," then some code is run. Any other input does nothing. Additionally, if the time runs out and nothing is inputted for v, then the "n" code is run.
I've tried a couple of different timers which work alright, but I'm struggling on how to cancel the input, since it stops my whole program and won't proceed onto the code I want to run.
Here's what I have:
def timerMethod():
timeout = 10
t = Timer(timeout, print, ['Sorry, times up'])
t.start()
prompt = "You have %d seconds to choose: are you feeling ok? y/n: \n" % timeout
answer = input(prompt)
if (answer == "n"):
feelingBad = True
t.cancel()
The two problems that I've encountered are 1. feelingBad (global variable) will never be made true. I feel like this is a basic Py principle that I've forgotten here, and I can change the way the code is written here, but if you'd like to point out my error please do. The main problem 2. is that if there is no input for the answer variable, the timer will end but the program will not proceed. If someone could please help me on the right track as on how to cancel the input prompt when the timer runs out, I'd greatly appreciate it.
Check the multithreading
here. I wish there was a better explanation on how it works. In my own words, one thread starts and sets the start time which is taken up by the second. Instead of a timer that counts down, it runs an if statement which compares the time taken with the time limit, which gives a space for any code to be run before the program exits.
You can try this:
import time
from threading import Thread
user = None
def timeout():
cpt = 0
while user == None:
time.sleep(1); cpt += 1
if user != None:
return
if cpt == 10:
break
print("Pass")
Thread(target = timeout).start()
user = input()

Python - Checking if there is an input from user without stopping the loop

I have a small script where I have a continuous loop. The loop runs and I expect that the user will give an input whenever he wants. I want to check if the user wrote something in the console, if yes, I will do something extra, if not, the loop continues.
The problem is that when I call the input() function, the program waits for user input.
The code that I will use here will be just a simple version of my code to show better what is my problem.
i=0
while True:
i+=1
if 'user wrote a number':
i+= 'user's input'
The objective is to not stop the loop if the user do not input anything. I believe this is a simple thing but I didn't find an answer for this problem.
Thank you for your time!
You can execute the background task (the while True) on a separate thread, and let the main thread handle the input.
import time
import threading
import sys
def background():
while True:
time.sleep(3)
print('background task')
def handling_input(inp):
print('Got {}'.format(inp))
t = threading.Thread(target=background)
t.daemon = True
t.start()
while True:
inp = input()
handling_input(inp)
if inp == 'q':
print('quitting')
sys.exit()
Sample execution (lines starting with >> are my inputs):
background task
>> a
Got a
>> b
Got b
background task
>> cc
Got cc
background task
background task
>> q
Got q
quitting
Process finished with exit code 0
The only caveat is if the user takes longer than 3 seconds to type (or whatever the value of time.sleep in background is) the input value will be truncated.
I'm don't think you can do that in one single process input(), because Python is a synchronous programming languaje,the execution will be stoped until input() receives a value.
As a final solution I'd recommend you to try implement your functions with parallel processing so that both 'functions' (input and loop) can get executed at the same time, then when the input function gets it's results, it sends the result to the other process (the loop) and finish the execution.

Python: display dynamic information on user input

I would like to be able to receive command line input from user in a python script, and at the same time display to the user some dynamic information.
The user should be able to enter text, but this should not block the displaying of information.
My goal is to create a game, where I show users a countdown while they still have time to enter an answer.
Is this achievable?
Yeah. To create a countdown in the console, you could do something like this:
from time import sleep
for num in reversed(range(0,11)):
print(num)
sleep(1.0)
or
from time import sleep
time = 10
while time != 0:
print(time)
time = time - 1
sleep(1.0)
Either will countdown from 10 to 0 with a second in between each number. Since you might want the user to be able to enter answers as quickly or slowly as like before reaching 0... you might want to look into running two loops concurrently. this thread might be helpful for that. You'll want to figure out how to break out of both loops if the user gets the right answer (and have something come up that says they got the right answer) or if the user runs out of time.
Well sounded like an interesting thing to look into so I did, ran into a few problems pretty soon.
First, I was able to make a running counter but the problem is, since it is a loop, the next layer the counter loop will reset everything you've answered on the previous layer unless you've pressed enter to input answer(answer + enter , during that 1 second period).
if you are making reflex based thing that you only need to press single keys you might be able to succeed with my code by using module getch.
There were few modules that I could use for making the timer and program run at the same time, threading and multiprocessing(better results with threading).
It's basically a working thing if you just remove the counter function which adds the loop, but you won't see the timer.
Pygame might be a good thing to do this with, haven't used it myself but I'd presume so.
here is my code
import time
import threading
import os
timel = 5
def question():
q = input("",)
print(q)
if q == "2":
print("\nCorrect")
else:
exit("\nFalse, You lose!!")
def counter():
timel = 5
for i in range(0, timel):
print("How much is 1+1?", timel)
timel -= 1
time.sleep(1)
os.system("cls")
def timer(seconds):
time.sleep(seconds)
exit("\nTIMES UP, You lose!!")
def exit(msg):
print(msg)
os._exit(1)
def main():
thread = threading.Thread(target=timer, args=(int("{}".format(timel)),))
thread2 = threading.Thread(target=counter)
thread.start()
thread2.start()
question()
if __name__ == "__main__":
main()

Get user input while printing to the screen

I would like to get user input while printing to the screen. I researched this a lot. but didn't find anything. I'm not very advanced with class programming in Python, so I didn't understand the other examples on stackoverflow.
Example:
import time
def user_input():
while True:
raw_input("say smth: ")
def output():
while True:
time.sleep(3)
print "hi"
input()
output()
I want the prompt to stay, even if the output is printing "hi". I already tried an example, but the input prompt disappears even if it is in a while loop.
First, let's go over your code
import time
def user_input():
while True:
raw_input("say smth: ")
def output():
while True:
time.sleep(3)
print "hi"
input()
output()
You are calling input() which is not actually your function name. It's user_input(). Also, once user_input() is called, output() will never be called because the while True condition in user_input() is always True, meaning it never exits outside the function.
Also, if you want to do something with multithreading, but you don't understand classes in Python, you should probably do a tutorial related to classes.
Take a look at this other StackOverflow Post on a multithreaded program.

Piping in Python 2.6 to a file with while loop

I'm completely new to Python piping but I think it's the answer to my problem. I've got a file cleverbot.py that takes endless input from raw_input and prints out the results to the command line. This is done while staying in a while loop the whole time, and when you say "bye" the script exits.
Now, can someone give me an example where I can pipe inputs to this script and then receive the output, without it ending the loop? The loop acts as a session and it's important that the script continues to run constantly inside this while loop while being able to have inputs piped to it.
Here is a snippet of the code. For anyone that wants to get the full thing its the pycleverbot library.
def main():
import sys
cb = Session()
q = ''
while q != 'bye':
try:
q = raw_input("> ")
except KeyboardInterrupt:
print
sys.exit()
print cb.Ask(q)
The cb = Session() can't be recreated at all after it's first made. That's why the while loop is in place. I lack the necessary logic to see a way of not using a while loop.
Hope this makes sense, thanks.
The trick is to not use a while loop in the first place.
for line in sys.stdin:
if line.lower().strip() == 'bye':
break
sys.stdout.write(do_something(line))
sys.stdout.flush()

Categories

Resources