A simple way to print few line stuck to the same position

T

TheSaint

Hello
I studying some way to print few line in the console that won't scroll down.
If was for a single line I've some idea, but several line it may take some
vertical tab and find the original first position.
I don't know anything about course module, some example will be highly
apreciated.
 
S

Steven D'Aprano

Hello
I studying some way to print few line in the console that won't scroll
down. If was for a single line I've some idea, but several line it may
take some vertical tab and find the original first position. I don't
know anything about course module, some example will be highly
apreciated.

I think you want something like this:


import sys
import time

def spinner():
chars = '|/-\\'
for i in range(30):
for c in chars:
sys.stdout.write(' %3d :: %s\r' % (i, c))
sys.stdout.flush()
time.sleep(0.2)
 
T

TheSaint

Steven said:
def spinner():
chars = '|/-\\'

Not exactly.
I'd like to show 4~6 line of report and refreshing periodically all of them,
avoiding to scroll down.
example:

this count 50
Second time 90
following line 110
another line xxx

The lines should remain on their position and update their data.
I think, I should go for course module, but it's a bit of learning, which I
didn't embarked yet.
 
S

Steven D'Aprano

Not exactly.
I'd like to show 4~6 line of report and refreshing periodically all of
them, avoiding to scroll down.


You have to use the curses module for that.
 
H

Hans Mulder

I'd like to show 4~6 line of report and refreshing periodically all of them,
avoiding to scroll down.
example:

this count 50
Second time 90
following line 110
another line xxx

The lines should remain on their position and update their data.

The quick and dirty way would be to output VT100 sequences: they work
on most, if not all modern terminals and emulators.
For example, to move the cursor to the start of line 20 and clear the
rest of the screen:

sys.stdout.write("\033[20;0H\033[J")

Or to clear the first six lines and put the cursor in the top left:

for i in range(1, 7):
sys.stdout.write("\033[%d;0H\033[K" % i)
sys.stdout.write("\033[0;0H")

After doing that, you could print your report.

A minimalist solution would be to print the labels ("This count", etc.)
only once, and position the cursor after it to update the report.
I think, I should go for course module, but it's a bit of learning, which I
didn't embarked yet.

The module is called "curses" and, yes, it would be the best way to go.


-- HansM
 
T

TheSaint

Hans said:
A minimalist solution would be to print the labels ("This count", etc.)
only once, and position the cursor after it to update the report.

Generally a good point. Similar sequences are working for coloring and
formatting text. I don't know whether the program would behave to someone
else who using not konsole like I do.
The module is called "curses" and, yes, it would be the best way to go.

OK, I didn't understand if I must setup a window first in order to implement
cursor positioning.
 
H

Hans Mulder

Hans Mulder wrote:
Generally a good point. Similar sequences are working for coloring and
formatting text.

As I said, VT100 sequences work in pretty much any modern terminal or
emulator (but not in a DOS box under Windows).
I don't know whether the program would behave to someone
else who using not konsole like I do.

If you use the "\033[H" sequence to move the cursor to a predefined
postition, you'll find that other people's windows have a different
size from yours. The standard library provides thin wrappers around
the low-level calls need to figure out the window size:

import array
import fcntl
import sys
import termios

def getwindowsize():
buf = array.array('h', [0] * 4)
res = fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ, buf, True)
return buf[0:2]

rows, columns = getwindowsize()

print rows, columns

Alternatively, you could parse the output of `stty -a`.

Oh, and people will resize their window while your script is running,
and expect it to respond sensibly. You could install a handler for
SIGWINCH signals, but at this point curses will begin to look more
and more attractive, as it will handle these details for you.

But then, maybe you can avoid absolute coordinates altogether. If
your report is always exactly six lines, you could write the sequence
"\r\033[5A" after each report. This moves the cursor to the left
margin and five lines up, ready to overwrite the previous report,
independent of window size.
OK, I didn't understand if I must setup a window first in order to implement
cursor positioning.

If you use curses, you must initialize it by calling curses.initscr(),
which returns a "WindowObject" representing the konsole window. To
put things on the screen, you call methods on this object. Keep in
mind that a "window" in curses jargon is just a rectangle inside
your konsole window. You can't create real Windows using curses.

Whether or not you use curses, if the numbers in the current report can
be smaller than those in the previous report, you'll want to write some
spaces after each number to erase the previous number. For example, if
you try to overwrite "this count: 10" with "this count: 9", you'll end
up with "this count: 90" on the screen. You don't want that to happen.


Hope this helps,

-- HansM
 
S

Sarcar, Shourya C (GE Healthcare)

A way to do this on DOS/Windows console would be:

import sys
for r in range(0,2**16):
line = "Count : %d" % r
sys.stdout.write(line)
sys.stdout.flush()
# do something that consumes time
backup = "\b" * len(line) # The backspace character; this will
prevent characters from the prev "print" showing up
sys.stdout.write(backup)
sys.stdout.flush()

Regards,
Shourya
http://partlytrue.wordpress.com/


P.S: This is my first post to the list and I am new to python and I have
Outlook as my mail client. Can't get worse. I am sure I am flouting some
response/quoting etiquette here. If someone could guide, I would be most
grateful.

-----Original Message-----
From: [email protected]
[mailto:p[email protected]] On
Behalf Of Hans Mulder
Sent: Sunday, June 05, 2011 4:31 AM
To: (e-mail address removed)
Subject: Re: A simple way to print few line stuck to the same position

Hans Mulder wrote: report.

Generally a good point. Similar sequences are working for coloring and
formatting text.

As I said, VT100 sequences work in pretty much any modern terminal or
emulator (but not in a DOS box under Windows).
I don't know whether the program would behave to someone else who
using not konsole like I do.

If you use the "\033[H" sequence to move the cursor to a predefined
postition, you'll find that other people's windows have a different size
from yours. The standard library provides thin wrappers around the
low-level calls need to figure out the window size:

import array
import fcntl
import sys
import termios

def getwindowsize():
buf = array.array('h', [0] * 4)
res = fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ, buf, True)
return buf[0:2]

rows, columns = getwindowsize()

print rows, columns

Alternatively, you could parse the output of `stty -a`.

Oh, and people will resize their window while your script is running,
and expect it to respond sensibly. You could install a handler for
SIGWINCH signals, but at this point curses will begin to look more and
more attractive, as it will handle these details for you.

But then, maybe you can avoid absolute coordinates altogether. If your
report is always exactly six lines, you could write the sequence
"\r\033[5A" after each report. This moves the cursor to the left margin
and five lines up, ready to overwrite the previous report, independent
of window size.
go.

OK, I didn't understand if I must setup a window first in order to
implement cursor positioning.

If you use curses, you must initialize it by calling curses.initscr(),
which returns a "WindowObject" representing the konsole window. To put
things on the screen, you call methods on this object. Keep in mind
that a "window" in curses jargon is just a rectangle inside your konsole
window. You can't create real Windows using curses.

Whether or not you use curses, if the numbers in the current report can
be smaller than those in the previous report, you'll want to write some
spaces after each number to erase the previous number. For example, if
you try to overwrite "this count: 10" with "this count: 9", you'll end
up with "this count: 90" on the screen. You don't want that to happen.


Hope this helps,

-- HansM
 
H

Hans Mulder

A way to do this on DOS/Windows console would be:

import sys
for r in range(0,2**16):
line = "Count : %d" % r
sys.stdout.write(line)
sys.stdout.flush()
# do something that consumes time
backup = "\b" * len(line) # The backspace character; this will
prevent characters from the prev "print" showing up
sys.stdout.write(backup)
sys.stdout.flush()

You can achieve that effect on Posix systems by writing a "\r".

However, the OP wanted to print a report of perhaps six lines, so
the question is: how would you then move the cursor five lines up?
P.S: This is my first post to the list and I am new to python and I have
Outlook as my mail client. Can't get worse. I am sure I am flouting some
response/quoting etiquette here. If someone could guide, I would be most
grateful.

One of the problems with Outlook is that it seduces you to put your
reply above the text you're replying to; the jargon phrase for this
is "top posting". This practice is frowned upon in this forum.

We prefer responses below the original, so that a person who hasn't
read earlier posts in a thread can understand yours when reading it
from top to bottom.

If you're responding to several points made in the previous post,
you would put your response below the paragraph in which it is made,
and delete the paragraphs you're not responding to.

Kind regards,

-- HansM
 
T

TheSaint

Hans said:
If you use curses, you must initialize it by calling curses.initscr(),
which returns a "WindowObject" representing the konsole window. To
put things on the screen, you call methods on this object. Keep in
mind that a "window" in curses jargon is just a rectangle inside
your konsole window

I've learned great things from you. Thank you very much.
The curse window I could realize it immediately that it's a part of console
screen, in curses module. Usually it's represented as blue box with some
shadow effect :)
Deleting old writing it's another good point.
Actually, I reduced in a simplier solution with one line report :p. I'll
look into curses for some better visual effects.
Playing with tabs (vertical and horizontal) I think it won't be a reliable
method, unless when the position it would stick to the upper left corner of
the console.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top