Why doesn't my piece of code execute in order? [duplicate] - python

This question already has answers here:
Printing on the same line with time.sleep()
(2 answers)
Closed 3 years ago.
While trying to solve a bigger issue, I reduced my code to two simple commands and I found out that they are not executed in order.
My idea is to give a kind of feedback to the user after clicking on a button(3D Slicer) while running a function. So, what I would expect is to freeze the button immediately after clicking it until the action is finished. So I tried the following to check if the very first command is executed on first position:
def onStartSegmentation(self):
self.segmentButton.setEnabled(False)
sleep(3)
print("2nd step: Starting segmentation")
However, the result is sleeping for 3 seconds and then executing both commands immediately one after the other.
I know this might sound silly, but I can't guess why it's acting like that.

print() function is buffered. That means the output will be buffered before displaying to the screen until the buffer is full or new line character is encountered. If you want to have your output to be displayed on the screen immediately, you need to flush the buffer by using sys.stdout.flush() or you need to explicitly specify it in the argument to print function.
def onStartSegmentation(self):
print("1st step: Starting segmentation", flush = True)
sleep(3)
print("2nd step: Starting segmentation", flush = True)
OR
def onStartSegmentation(self):
print("1st step: Starting segmentation")
sys.stdout.flush()
sleep(3)
print("2nd step: Starting segmentation")
sys.stdout.flush()

Related

How to make python NOT wait for user input while in a loop? [duplicate]

This question already has answers here:
Python async: Waiting for stdin input while doing other stuff
(3 answers)
Closed 4 months ago.
I want it so that my code continuously replaces itself continuously, and while that executes, I want the input to just take what it is without needing to press enter. I'm an android user and I've already tried downloading non-built-in-modules, so I can't use the keyboard module or anything like that.
My code is basically:
while game == "on":
print("string")
inpu = input
time.sleep(1)
clear screen
Apologies for false text editing or bad "code grammar."
I'm new to coding and stack overflow.
NOT wait for user input while in a loop?
Solution
That is easy, using multi-thread or multi-process. i.e create another thread that handles the input separately.
Demo of full code
Here is a very simple demo of multi-thread to begin.
import _thread
args = None
# Define a function for the thread
def mythread(threadname):
global args
args = input("input anything: ")
# Create one threads as follows
try:
_thread.start_new_thread( mythread, ("UI",) )
while args==None: # mimic your work loop
pass;
print("main loops end demo end")
except:
print ("Error: unable to start thread")
To run
$ python3 demo.py
Output
input anything: hello
main loops end demo end

How do you write multiple lines of replaceable console output in python?

I am trying to have three different lines of text in the terminal display the different count progresses. The problem is they overwrite each other and honestly I don't know what to do anymore. Any tips or fixes?
def first():
for i in range(50,0,-1):
sys.stdout.write("\rThe current chicken is: {:<3d}".format(i))
time.sleep(1)
def second():
for i in range(100,0,-1):
sys.stdout.write("\rThe current number is: {:<3d}".format(i))
time.sleep(1)
def third():
for i in range(1000,0,-1):
sys.stdout.write("\rThe current cow is: {:<3d}".format(i))
time.sleep(1)
awidj = [first, second, third]
for thread in awidj:
threading.Thread(target=thread).start()
\r will just overwrite the last line that was written. Since you have multiple threads here, there is no way to control which one that is.
For more precise control over console output, check out the curses module.

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()

Is there a way to prevent automatic newline on python command line? [duplicate]

This question already has answers here:
How to print without a newline or space
(26 answers)
Closed 3 years ago.
I am making a command line game engine in python. However, when I attempt to print a command, it newlines and creates a jittery frame.
Adding the end attribute bogs down my computer and nearly crashes the shell. The dupe uses sys.stdout.write('') newline sys.stdout.flush or print'', or print('',end=''). all bog down shell and crash it. print('') doesn't bog down though which is weird.
#this is enough code to demonstrate the problem
while true:
print(' = === ===== ======= ========= =========== ============= YYYYYYYYYYY ================================================================================')
#crash issue
import sys
while True:
sys.stdout.write('mooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo')
sys.stdout.flush()
I expect the screen to fill, instead it wobbles up and down.
I am not sure if I understood your question correctly, but I’m thinking you do not want to print a new line with each call to the print() function.
If so, the print function has an optional argument end, that is set by default as \n (this, creating a new line if not specified otherwise). If you don’t want this to happen, you can simply use the print function as:
print(your_argument, end=“”)
Replacing your_argument with whatever you want to print out.

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.

Categories

Resources