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

Discussion in 'Python' started by TheSaint, Jun 2, 2011.

  1. TheSaint

    TheSaint Guest

    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.

    --
    goto /dev/null
     
    TheSaint, Jun 2, 2011
    #1
    1. Advertising

  2. On Thu, 02 Jun 2011 21:22:40 +0800, TheSaint wrote:

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


    --
    Steven
     
    Steven D'Aprano, Jun 2, 2011
    #2
    1. Advertising

  3. TheSaint

    TheSaint Guest

    Steven D'Aprano wrote:

    > 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.

    --
    goto /dev/null
     
    TheSaint, Jun 3, 2011
    #3
  4. On Fri, 03 Jun 2011 19:00:22 +0800, TheSaint wrote:

    > Steven D'Aprano wrote:
    >
    >> 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.



    You have to use the curses module for that.


    --
    Steven
     
    Steven D'Aprano, Jun 3, 2011
    #4
  5. TheSaint

    Hans Mulder Guest

    On 3/06/11 13:00:22, TheSaint wrote:

    > 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
     
    Hans Mulder, Jun 3, 2011
    #5
  6. TheSaint

    TheSaint Guest

    Hans Mulder wrote:

    > 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.
    --
    goto /dev/null
     
    TheSaint, Jun 4, 2011
    #6
  7. TheSaint

    Hans Mulder Guest

    On 4/06/11 13:14:05, TheSaint wrote:
    > Hans Mulder wrote:


    >> 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.


    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.

    >> 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.


    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
     
    Hans Mulder, Jun 5, 2011
    #7
  8. 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: python-list-bounces+shourya.sarcar=
    [mailto:python-list-bounces+shourya.sarcar=] On
    Behalf Of Hans Mulder
    Sent: Sunday, June 05, 2011 4:31 AM
    To:
    Subject: Re: A simple way to print few line stuck to the same position

    On 4/06/11 13:14:05, TheSaint wrote:
    > Hans Mulder wrote:


    >> 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.


    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.

    >> 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.


    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



    --
    http://mail.python.org/mailman/listinfo/python-list
     
    Sarcar, Shourya C (GE Healthcare), Jun 5, 2011
    #8
  9. TheSaint

    Hans Mulder Guest

    On 5/06/11 05:40:17, Sarcar, Shourya C (GE Healthcare) wrote:
    > 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
     
    Hans Mulder, Jun 5, 2011
    #9
  10. TheSaint

    TheSaint Guest

    Hans Mulder wrote:

    > 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.

    --
    goto /dev/null
     
    TheSaint, Jun 7, 2011
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Camel
    Replies:
    3
    Views:
    6,395
    Camel
    Jul 12, 2005
  2. Replies:
    7
    Views:
    653
    Stig Brautaset
    Jul 23, 2003
  3. Murali
    Replies:
    2
    Views:
    593
    Jerry Coffin
    Mar 9, 2006
  4. Cliff
    Replies:
    10
    Views:
    495
    Jim Langston
    Jun 23, 2007
  5. Replies:
    1
    Views:
    117
    Ian Wilson
    Mar 22, 2007
Loading...

Share This Page