Forum: Ruby Console output

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Hello T. (Guest)
on 2009-05-16 22:15
Hi

I am trying to find a way to output text in a console on the same spot
many times. I have a table with data (multiline) and need the numbers in
it to change every second, but the numbers should be at the same spot.

I have asked several people and I got the answer about using
ncurses/curses, however I haven't found any that works both on win32 and
linux, which I need.

Best regards
Shot (Piotr S.) (Guest)
on 2009-05-16 22:57
(Received via mailing list)
Hello There:

> I am trying to find a way to output text in a console on the same spot
> many times. I have a table with data (multiline) and need the numbers in
> it to change every second, but the numbers should be at the same spot.

I had this problem previously, with the additional spin that the
status must be updated by parallel processes. The discussion is here:
http://groups.google.com/group/ruby-talk-google/br...

> I have asked several people and I got the answer about using
> ncurses/curses, however I haven't found any that works both on
> win32 and linux, which I need.

Unfortunately, I don’t use Win32, so I can’t
say whether the above examples work there.

— Shot
Mk 2. (Guest)
on 2009-05-16 23:31
> I have asked several people and I got the answer about using
> ncurses/curses, however I haven't found any that works both on win32 and
> linux, which I need.

Totally new to ruby but from experience with C and perl I would say the
answer to this question is tough luck.  You have to use an API (such as
ncurses); if you cannot get that to work satisfactorily you will have to
write seperate front-ends for each OS.

If ruby/Tk is cross platform enough and it's possible you might as well
go the GUI route; dealing with Tk is not much more complex than curses.
A simple task like this one will be -- simple.
Colin B. (Guest)
on 2009-05-17 01:53
(Received via mailing list)
Assuming I understand correctly what you want to do,
on a Windows system to show progress in a "console" box
I just repeatedly use (every second):
  print 13.chr + "text to show progress"

The short bit of code below demonstrates this. (I hope!)
So you may not need to use ncurses/curses.
(Although using those might make it easier to do more complicated
things.
 I haven't used ncurses/curses.)

I haven't tried this on Linux, but as the basic idea
is to use "print" (to avoid a new-line)
and "13.chr" (to return to the start of the line
before displaying the new progress text)
I hope it would also work in Linux.


puts
puts 'simple (Windows) example to show putting text on same console
line'
k = 13
k.times do | n |
  txt = 'count= ' + n.to_s
  print 13.chr + txt  ## CR = CarriageReturn
  sleep 0.5
end
puts '  *** final new line'
puts

If you - or anyone else - is interested in some more complicated code
then I'd be happy to post it.
(Basically I wrapped the "print 13.chr + txt" in an object
 which tested when the next display should be made,
 and which displayed the (formatted) time so far,
 and some other relevant information.)
Shot (Piotr S.) (Guest)
on 2009-05-17 02:11
(Received via mailing list)
Colin B.:

> Assuming I understand correctly what you want to do,
> on a Windows system to show progress in a "console" box
> I just repeatedly use (every second):
>   print 13.chr + "text to show progress"

Now that I think about the Original Poster’s prolem, I think
the solution needs to walk up and down the screen as well. :|

> I hope it would also work in Linux.

FWIW, your below code does run under Linux. :)

> puts
> puts 'simple (Windows) example to show putting text on same console line'
> k = 13
> k.times do | n |
>   txt = 'count= ' + n.to_s
>   print 13.chr + txt  ## CR = CarriageReturn
>   sleep 0.5
> end
> puts '  *** final new line'
> puts

— Shot
Hello T. (Guest)
on 2009-05-17 02:22
Shot (Piotr S.) wrote:
> Colin B.:
>
>> Assuming I understand correctly what you want to do,
>> on a Windows system to show progress in a "console" box
>> I just repeatedly use (every second):
>>   print 13.chr + "text to show progress"
>
> Now that I think about the Original Poster’s prolem, I think
> the solution needs to walk up and down the screen as well. :|
>
>> I hope it would also work in Linux.
>
> FWIW, your below code does run under Linux. :)
>
>> puts
>> puts 'simple (Windows) example to show putting text on same console line'
>> k = 13
>> k.times do | n |
>>   txt = 'count= ' + n.to_s
>>   print 13.chr + txt  ## CR = CarriageReturn
>>   sleep 0.5
>> end
>> puts '  *** final new line'
>> puts
>
> — Shot

Yes, it seems like the code above only is for one line, or?
I need to update a whole table, many lines, is it tough luck =/

Thank you for answers
Shot (Piotr S.) (Guest)
on 2009-05-17 03:00
(Received via mailing list)
Hello There:

> I need to update a whole table, many lines, is it tough luck =/

In this case, you can either use ncurses (hopefully, through some
platform-agnostic gem) or – if that’s feasible – clear the screen
every iteration and print the whole table; something to the tune of

case RUBY_PLATFORM
when /linux/          then `clear`
when /win32/, /mswin/ then `clrscr`
end

Note: The above code is untested and extremly naïve,
you should probably use something like the platform gem:
http://files.rubyforge.vm.bytemark.co.uk/platform/...
(except it’s old and there is a much newer gem that does
this; unfortunately, its name escapes me right now).

— Shot
Hello T. (Guest)
on 2009-05-17 03:13
Shot (Piotr S.) wrote:
> Hello There:
>
>> I need to update a whole table, many lines, is it tough luck =/
>
> In this case, you can either use ncurses (hopefully, through some
> platform-agnostic gem) or – if that’s feasible – clear the screen
> every iteration and print the whole table; something to the tune of
>
> case RUBY_PLATFORM
> when /linux/          then `clear`
> when /win32/, /mswin/ then `clrscr`
> end
>
> Note: The above code is untested and extremly naïve,
> you should probably use something like the platform gem:
> http://files.rubyforge.vm.bytemark.co.uk/platform/...
> (except it’s old and there is a much newer gem that does
> this; unfortunately, its name escapes me right now).
>
> — Shot

Yeah I tried with this clear method, with the unsafe system('cls')
however, but if i clear and redraw every second, it flickers very much.

Im gonna test this 'clear' but i guess it will be the same?

Thank you
Colin B. (Guest)
on 2009-05-17 06:06
(Received via mailing list)
> Yeah I tried with this clear method, with the unsafe system('cls')
> however, but if i clear and redraw every second, it flickers very much.

Using "cls" had also occurred to me, but I (literally) see
what you mean about the flickering:

50.times do | k | k = k.to_s
  system( "cls" )
  30.times do | n | n = ' *' + k + '=' + n.to_s
    puts n * 10
  end
end

Not very pleasant visually, and it looks as though it would be
very difficult to actually see any information properly.

> I have asked several people and I got the answer about using
> ncurses/curses, however I haven't found any that works
> both on win32 and linux, which I need.

That suggests to me that you've tried using "curses"
on Win32 and Linux and that it didn't do what you wanted.
Is that right?

I'm gettting the distinct impression that you and Shot
know a lot more about this than I do, which makes me
a bit reluctant to post the code below, because I suspect
you may have already tried something like it,
and it didn't do what you want.

But since it's something which I might use in the future,
I'll post it, because that will fix it more firmly in my mind.
(And now I *really* know why GNU wget uses a single line
 progress bar: it's simpler just to use print 13.chr + "text".)

(Assuming this doesn't do what you want on Linux (or Win32),
 I'd be interested in a few details of what problems you've
 found trying to get something to work on both Win32 and Linux.)

This is based on the "hello.rb" example in the following place
on my Win32 Ruby installation:
  C:/ruby/src/ruby-1.8.6-p111/ext/curses

require "curses"
include Curses

init_screen

puts '##### screen size(?): lines, cols:', lines, cols
puts 'about to display text'
sleep 2

begin
  crmode
  setpos( 8, 13 )
  addstr("display text which we will partly over-write later")
  refresh
sleep 2
  setpos( 3, 40 ) ; addstr("display some text") ; refresh
  setpos( 8, 40 ) ; addstr("PARTLY") ; refresh
  setpos( 8, 32 ) ; addstr("W") ; refresh
  20000.times do | k |
    setpos( 8, 13 ) ; addstr( k.to_s + " ") ; refresh
  end
ensure
  close_screen
end


This seems to work reasonably fast on Win32.
(And it reminds me that I did once know something about
 moving stuff about on screens using DOS: in the 1980s
 I got so fed up with reinventing wheels every time
 I wanted input in BASIC programs that I wrote
 a parameter file driven program to generate input screens.
 Somewhat to my surprise, it worked quite well!)
Hello T. (Guest)
on 2009-05-17 15:40
> require "curses"
> include Curses
>
> init_screen
>
> puts '##### screen size(?): lines, cols:', lines, cols
> puts 'about to display text'
> sleep 2
>
> begin
>   crmode
>   setpos( 8, 13 )
>   addstr("display text which we will partly over-write later")
>   refresh
> sleep 2
>   setpos( 3, 40 ) ; addstr("display some text") ; refresh
>   setpos( 8, 40 ) ; addstr("PARTLY") ; refresh
>   setpos( 8, 32 ) ; addstr("W") ; refresh
>   20000.times do | k |
>     setpos( 8, 13 ) ; addstr( k.to_s + " ") ; refresh
>   end
> ensure
>   close_screen
> end

Hello Colin

Wow, this code was really awesome, worked like a charm both on win32 and
linux.
Switching only the setpos makes me able to change and print text in many
rows. Thank you very very much.

Best Regards.
This topic is locked and can not be replied to.