Can't run time delay text on Mac terminal (Python) - python

I'm having trouble with the Terminal on my Mac.
I'm trying to print out delay text (like it appears on a type writer) and the code (below) was correct when I tested on an online compiler.
import sys
import time
intro1= "Welcome player. What's your name?"
for x in intro1:
sys.stdout.write(x)
time.sleep(0.2)
But my Mac Terminal just freezes for a sec and print out the whole statement in one go. I got Python 2.7.10 on the Mac. I looked up online and I think my Terminal is cutting the buffer for convenience's sake but now I actually need the buffer (I'm going to be printing out delayed text a lot). Is there any statement to turn on the buffer (or fix it since it should be set by default) on my Terminal? Thanks a lot

You need to add sys.stdout.flush() after each sys.stdout.write() to force the character out instead of letting it get buffered:
import sys
import time
introduction = "Welcome player. What's your name? "
for character in introduction:
sys.stdout.write(character)
sys.stdout.flush()
time.sleep(0.2)
name = raw_input()

Related

Print on the same spot in IPython console

This has been asked before (for instance a, b, etc.), but I cannot make it work in IPython console.
I simply want to print some text over and over on the same line, not as continuous text, but replacing the previous one.
This is my code:
import time
try:
while True:
s = "I want this always on the same line. "
print(s, end="\r", flush=True)
time.sleep(0.5)
except KeyboardInterrupt:
pass
And here is what I get in IPython console:
I am using Anaconda distribution on PC and Spyder, with Python 3. The code works in Anaconda terminal, but I need to print out some image as well so I need IPython. I also tried using end="" or adding a comma after the print() statement (even if this is for Python 2), but to no avail.
I wrote this before the edit with IPython console, so I am not sure if this is a solution that works there or not, but here it its:
Instead of using the print() command, i would instead try to use sys.stdout.
This is a "progressreport" that I have in one of my scripts:
from sys import stdout
from time import sleep
jobLen = 100
progressReport = 0
while progressReport < jobLen:
progressReport += 1
stdout.write("\r[%s/%s]" % (progressReport, jobLen))
stdout.flush()
sleep(0.1)
stdout.write("\n")
stdout.flush()
The sleep function is just so that you can see the progresReport get larger. The "\r" part of the stdout is what makes the script "replace" the previus string. The flush() is added after the write() function, because it is sometimes needed to show the output on some enviroments.
Once you don't want to write to that row anymore, then you terminate it either by writing an empty string without "\r" or by writing a "\n".

My typing simulator runs in the python shell but not in real life?

I am writing a program to simulate typing and it runs in the python shell but not when double clicked any ideas?
My code is as follows:
import sys,time
def slow_text(str):
for letter in str:
sys.stdout.write(letter)
sys.stdout.flush
time.sleep(0.1)
print("")
slow_text('Hello')
I am using python 3.5.
You're not actually calling sys.stdout.flush. That line should be:
sys.stdout.flush()
Without flushing, what's actually happening is that the script delays for some seconds with a blank console window (while the characters go into the output buffer) and then they all appear at once and the script ends and the window immediately closes, before you have a chance to see them.
That it worked in the Python shell was just a coincidence.

Why sleep is running before print here? [duplicate]

I was writing a simple program on Python 3.1 and I stumbled upon this:
If I run this on the IDLE it works as intended - prints "Initializing." and then adds two dots, one after each second, and waits for input.
from time import sleep
def initialize():
print('Initializing.', end='')
sleep(1)
print(" .", end='')
sleep(1)
print(" .", end='')
input()
initialize()
The problem is that when I double-click the .py to execute the file, it runs on python.exe instead of pythonw.exe, and strange things happen: it joins all the sleep() times i.e. makes me wait for 2 seconds, and then prints the whole string Initializing. . . at once. Why does this happen? Is there a way to avoid that happening in the terminal? It works fine if I use the IDLE in both windows and linux.
This is because the output is being buffered.
You should add a sys.stdout.flush() after each write
It sounds like the difference is that stdout is automatically being flushed in IDLE. For efficiency, programming languages often save up a bunch of print calls before writing to the screen, which is a slow process.
Here's another question that has the answer you need:
How to flush output of Python print?

Python - Is there any way to make output text end on the top of idle?

Im just wondering if it is possible to have the last thing printed on the top line for example:
Print("hello")
Print("hello, again...")
And have the idle shell look like:
hello, again...
hello
Instead of the other way around. Does anyone know of any command in python that i can use to make the last printed item appear at the top of the shell?
If i had a timer that updates a variable each second, how would i make sure the old value is cleared:
import time
print("hello", end="\r")
time.sleep(1)
print("hello, again...",end="\r")
You will need to run the code from somewhere that is not idle as it is not a real tty, using clear or cls is also going to fail in idle. You could possibly use the curses lib as mentioned in a comment but it will certainly not be trivial to implement, if you wanted to reverse the output like the lines in your question you could redirect stdout to an io.StringIO object and reverse the lines:
from contextlib import redirect_stdout
from io import StringIO
f = StringIO()
with redirect_stdout(f):
print("hello")
print("hello, again...")
f.seek(0)
print("".join(f.readlines()[::-1]))
Which in idle will output:
hello, again...
hello
If I were you I would ditch idle, what you are seeing is one of many limitations you may encounter when using idle.
If you really do want to stay using idle, you should download idlex which has some extensions to make idle work more like a terminal
This worked for me on Windows using Python 3
pip install windows-curses
Example:
import curses
import time
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
try:
stdscr.addstr(0, 0, "Printing Numbers...")
for i in range(10):
stdscr.addstr(1, 0, "Number: {0}".format(i))
stdscr.insertln()
stdscr.refresh()
time.sleep(0.5)
finally:
curses.echo()
curses.nocbreak()
curses.endwin()
Using stdscr.insertln() allows you to insert a blank line under the cursor. All following lines are moved down by one line.
More information on curses found here:
https://docs.python.org/2/library/curses.html
The only thing I an think of is keeping track of everything printed and clearing the console every time.
import os
console_lines = []
def reverse_print(text):
console_lines.append(text)
os.system('cls')
print('\n'.join(reversed(console_lines)))
reverse_print('hi')
reverse_print('hello')
reverse_print('okay')

Python: How do I display a timer in a terminal

I'm new to python programming and using ubuntu to do so. In a program I have done I used a delay of 1 minute until it executes the code again. How can I program a timer to be displayed in the terminal based on the value of the delayed time? Thanks in advance...
The simplest way is as follows.
import time
import sys
for remaining in range(10, 0, -1):
sys.stdout.write("\r")
sys.stdout.write("{:2d} seconds remaining.".format(remaining))
sys.stdout.flush()
time.sleep(1)
sys.stdout.write("\rComplete! \n")
"\r" returns the text cursor to the beginning of the line, so that you can overwrite what you're previously written. Because typically output isn't written until a newline ("\n"), you need to manually .flush() the output stream.
Because the line isn't being cleared, we need to ensure that each new line of output is long enough to cover up the existing line.
The curses module has tools for more advanced terminal output, but is more complicated to use.

Categories