Short Question
Is it possible/practical to write and update a multi-line (contains \n) string on a Windows terminal?
Background
I have looked into curses, but it is Unix only. I saw a few other Window ports, but it was a bit troubling that Windows XP was an experimental OS for one them. I am hoping to use this as part of a diagnostic feature to display link status, message rates, etc on a mainly terminal application (note that some variants do have a wxPython GUI input). That being said, using Cygwin is non-ideal and would love to find a workaround using only the sys module.
I have tried the following: (note that I expected them to fail, but hoped I would be wrong)
Attempt 1: Updates the string but it is all on 1 line
sys.stdout.write("\r")
sys.stdout.write("This is a multi-line screen print test")
sys.stdout.write("Line 1")
sys.stdout.write("Line 2")
sys.stdout.flush()
Attempt 2: Does not update but prints all the lines
sys.stdout.write("\r")
sys.stdout.write("This is a multi-line screen print test\n")
sys.stdout.write("Line 1 \n")
sys.stdout.write("Line 2\n")
sys.stdout.flush()
The closest thing I could find to curses (that has been updated in the last 10 years) was Windows Console Driver. Rather than use this approach I went at it was a less elegant method.
import os
import time
while(1):
time.sleep(.05)
os.system('cls')
print "This is a multi-line screen print test"
print "Line 1"
print "Line 2"
You might have to use the Windows Console API. For example, SetConsoleCursorPosition. Other people appear to have implemented Python modules to support this API: 1, 2
Related
I know you can clear the shell by executing clear using os.system, but this way seems quite messy to me since the commands are logged in the history and are litterally interpreted as commands run as the user to the OS.
I'd like to know if there is a better way to clear the output in a commandline script?
print "\033c"
works on my system.
You could also cache the clear-screen escape sequence produced by clear command:
import subprocess
clear_screen_seq = subprocess.check_output('clear')
then
print clear_screen_seq
any time you want to clear the screen.
tput clear command that produces the same sequence is defined in POSIX.
You could use curses, to get the sequence:
import curses
import sys
clear_screen_seq = b''
if sys.stdout.isatty():
curses.setupterm()
clear_screen_seq = curses.tigetstr('clear')
The advantage is that you don't need to call curses.initscr() that is required to get a window object which has .erase(), .clear() methods.
To use the same source on both Python 2 and 3, you could use os.write() function:
import os
os.write(sys.stdout.fileno(), clear_screen_seq)
clear command on my system also tries to clear the scrollback buffer using tigetstr("E3").
Here's a complete Python port of the clear.c command:
#!/usr/bin/env python
"""Clear screen in the terminal."""
import curses
import os
import sys
curses.setupterm()
e3 = curses.tigetstr('E3') or b''
clear_screen_seq = curses.tigetstr('clear') or b''
os.write(sys.stdout.fileno(), e3 + clear_screen_seq)
You can use the Python interface to ncurses, specifically window.erase and window.clear.
https://docs.python.org/3.5/library/curses.html
I use 2 print statements to clear the screen.
Clears the screen:
print(chr(27) + "[2J")
Moves cursor to begining row 1 column 1:
print(chr(27) + "[1;1f")
I like this method because you can move the cursor anywhere you want by [<row>;<col>f
The chr(27) is the escape character and the stuff in quotes tells the terminal what to do.
This question already has answers here:
How to clear the interpreter console?
(31 answers)
Closed 7 years ago.
Python 3.5.0
I'm working with 150-200 lines of code so it isn't the worst. But this game involves a lot of repetitive lines of code, so I was wondering if there was a command that clears the whole console (for instance if I was to write code that prints "hello world" then it clears itself and prints "hello usa" where "hello world" used to be) before outputting the next line of code. I'm hoping to do this in the code editor in IDLE instead of the shell.
I guess I didn't make it clear enough D: sorry, my bad. I tried the import os way, and it just opened up a cmd console every once and a while for about a fraction of a second. I want a command that I can write in the python code editor that comes with idle, so that whenever I run the program and the program pops up, the text will pop up on the running program, disappear, then print the next text (or next step of the program).
You could try this, You will have to import os of course, and i am hoping you are using windows
>>> import os
>>> clear = lambda: os.system('cls')
>>> clear()
in linux you can try
os.system('clear')
On *nix you could say,
os.system("clear")
Assuming windows, try:
import os
os.system('cls')
I am very new to Python and I would like to know how I would clear a text that has been printed and add another piece of text. For example, I would like to display "Hello" then program with a delay of 10 seconds to replace text with another text "Goodbye". I am using Python 3.3 on Windows 7.
import time
import os
print ('hello there')
time.sleep(10) # this will BLOCK your program for 10 seconds
os.system('cls') # clear the screen, since cls is the clear screen command for windows
print ('bye')
input() # this is to wait to user to enter something to exist
version 2, using some 'visual' effects :D
import time
import os
print ('hello there')
for i in range(1, 10):
time.sleep(1)
print ('.')
os.system('cls')
print ('bye')
input()
Once text is sent to stdout, there really isn't a good way to change it. What you probably want to do would require a UI library such as tkinter (which comes with Python) or wxPython. Then you can create a Window with a label widget that can change every few seconds. You might be able to use Python's curses library too, but I have yet to see a coherent tutorial on how you would use that for this sort of thing.
Python's output is based on an abstraction of "output is just a file that you can write to", so there's no way to do this cross-platform.
However, if you want it to work in a Windows cmd.exe console (aka "DOS prompt"), and don't care about working inside IDLE, on Unix, over a network, etc., you can use the MSVCRT console I/O APIs.
Unfortunately, the limited set of console I/O APIs built into the standard library doesn't include the clear function. But you can look for third-party extended console I/O libraries on PyPI, or use PyWin32 to call the MSVCRT functions directly.
Or you can use a cheap hack:
import subprocess
subprocess.check_call(['cls'])
This just calls the cls function, which does everything for you.
Edit: the linked post does not solve this problem, this is still an outstanding issue.
I execute the following program in Spyder with iPython:
import time
print "Please enter your name."
userName=raw_input();
print "Now let's wait a few seconds, {}.".format(userName)
time.sleep(1)
print "Did you lose your patience?"
It prompts the user for their name, then (instead of printing the first line, waiting, and then printing the second line), it pauses and then prints the outputs of the last two print statements at the same time.
When I run from the command line, it works as expected. So does anyone know what I can do so that the script shows the desired behavior from within Spyder/iPython (I am working in Windows 7, Spyder 2.2.5 running iPython with Python 2.7).
Note because I get the expected behavior when I run from the command line, the suggestion at Why is time.sleep pausing early? is not transparently applicable, but perhaps it is easy to port that solution to this case? Also, running 'sys.stdout.flush()' before the sleep command doesn't seem to do anything.
I tested this in Spyder and vanza's solution works for me. Are you sure you put sys.stdout.flush() in the right line? It should look like this:
vanza's solution:
import time
import sys
print "Please enter your name."
userName=raw_input();
print "Now let's wait a few seconds, {}.".format(userName)
sys.stdout.flush() # <- *** it goes here ***
time.sleep(3)
print "Did you lose your patience?"
You might want to scroll down the iPython console a bit before entering your input, to see the text clearly (otherwise it stays a bit low to be noticed).
I recently switched OS and am using a newer Python (2.7). On my old system, I used to be able to print instantaneously. For instance, suppose I had a computationally intense for loop:
for i in range(10):
huge calculation
print i
then as the code completed each iteration, it would print i
However, on my current system, python seems to cache the stdout so that the terminal is blank for several minutes, after which it prints:
1
2
3
in short succession. Then, after a few more minutes, it prints:
4
5
6
and so on. How can I make python print as soon as it reaches the print statement?
Try to call flush of stdout after the print
import sys
...
sys.stdout.flush()
Or use a command line option -u which:
Force stdin, stdout and stderr to be totally unbuffered.
Since Python 3.3, you can simply pass flush=True to the print function.
Import the new print-as-function as in Python 3.x:
from __future__ import print_function
(put the statement at the top of your script/module)
This allows you to replace the new print function with your own:
def print(s, end='\n', file=sys.stdout):
file.write(s + end)
file.flush()
The advantage is that this way your script will work just the same when you upgrade one day to Python 3.x.
Ps1: I did not try it out, but the print-as-function might just flush by default.
PS2: you might also be interested in my progressbar example.