Code Comments
Programming Forum and web based access to our favorite programming groups.Hello Everybody, I need help in Visual Fortran subject. I have an application in VF and I want to ad a progress bar to monitor the running progress. Any one can help me by providing a fully functional program that producess a progress bar (in its simplist form). Thanks in advance for the help.
Post Follow-up to this messageHussein wrote: > I need help in Visual Fortran subject. I have an application in VF and > I want to ad a progress bar to monitor the running progress. Any one > can help me by providing a fully functional program that producess a > progress bar (in its simplist form). The simplest form of a progress bar that I can think of is this old standby: program progress integer :: i write(*,'(A)',advance='NO') 'Starting work.' do i=1,256 write(*,'(A)',advance='NO') '.' ! ! Do various things here. ! end do write(*,'(A)') 'Done.' end - Brooks -- The "bmoses-nospam" address is valid; no unmunging needed.
Post Follow-up to this messageBrooks Moses wrote: > Hussein wrote: > > > > The simplest form of a progress bar that I can think of is this old > standby: > > program progress > integer :: i > write(*,'(A)',advance='NO') 'Starting work.' > do i=1,256 > write(*,'(A)',advance='NO') '.' > ! > ! Do various things here. > ! > end do > write(*,'(A)') 'Done.' > end Unfortunately, stuff like this doesn't work on systems where the output is buffered -- in my case, Intel Fortran 8.1 on Linux. Does one have to resort to vendor-specific stuff to turn off the buffering -- and, if so, is this a compiler switch or a code modification? cheers, Rich
Post Follow-up to this messageRich Townsend wrote: > Brooks Moses wrote: > > Unfortunately, stuff like this doesn't work on systems where the output > is buffered -- in my case, Intel Fortran 8.1 on Linux. Does one have to > resort to vendor-specific stuff to turn off the buffering -- and, if so, > is this a compiler switch or a code modification? Hmm; clearly I didn't test that sufficiently -- I didn't think about the buffering problem, and thus didn't include any delay in my "do various things" that would make it clear. There seems to be a message on the Intel boards speaking about this same problem (and why FLUSH doesn't solve it) here: [url]http://softwareforums.intel.com/ids/board/message?board.id=11&message.id=2108[/url ] Steve Lionel replies there: > The behavior you are looking for is implementation-dependent, and > non-advancing I/O was not intended for this purpose. I recommend > instead using the $ edit descriptor in an explicit formatted write. > This will do what you want. Using that suggestion, the following program works properly on Intel Fortran 7.1 on Windows: program progress integer :: i, j write(*,'(A$)') 'Starting work.' do i=1,256 write(*,'(A$)') '.' do j=1,1200000 end do ! Do various things here. end do write(*,'(A)') 'Done.' end Note, though, that the '$' edit descriptor is an Intel extension, and may not work in other compilers. - Brooks -- The "bmoses-nospam" address is valid; no unmunging needed.
Post Follow-up to this messageHussein wrote: > fully functional program that producess a > progress bar (in its simplist form). > Thanks in advance for the help. program progbar implicit none integer :: i_ integer :: iarg real(8) :: rarg do i_=1,120 rarg=real(i_,8) iarg=int(21-20*cos(0.1*rarg)) call progress_bar(iarg) print*,'iarg:',iarg call sleepqq(140) end do contains subroutine progress_bar(ipercent) implicit none integer, intent(in) :: ipercent character, allocatable :: symbar(:) integer :: n_columns integer :: n_elements integer :: n_per_el integer :: element n_columns=100 n_elements=n_columns/2 ! half of the screen n_per_el=100/n_elements allocate(symbar(n_elements)) do element=1,n_elements if( element*n_per_el .le. ipercent )then symbar(element)='|' else symbar(element)=' ' end if end do WRITE(*,*) CHAR(27), '[2J' WRITE(*,*) CHAR(27), '[1;1H' write(*,fmt=*)symbar deallocate(symbar) return end subroutine progress_bar end program progbar -- igor.
Post Follow-up to this messageMany thanks Brooks, If I may bother you a little more, would you have a program that would produce a Progress Bar or Task Bar filling box while running the application. I am using VF 6.6. Or if not, how can I make the above program write a certain number of points (say 20 ) on the same line and repeating it without advancing to the next line? Regards
Post Follow-up to this messageThank you Igor, I think I am getting closer. How do you modify the program to make the symbols print on the same line without advancing to the next one?, i.e., all the action on one line. Regards, Hussein
Post Follow-up to this messageHussein wrote:
> Thank you Igor, I think I am getting closer. How do you modify the
> program to make the symbols print on the same line without advancing to
> the next one?, i.e., all the action on one line.
>
> Regards,
> Hussein
I do not quite understand your question
The program below does what you want.
It draws the red progress bar.
I also use Intel Fortran 8.1 on Linux
for me it works fine.
The principle is the following: every
time you call subroutine "progress_bar"
it cleans the screen and redraws the
progress bar with different colors.
It uses console codes to do this
(you can read about console codes in
man console_codes).
If you want to output something else
on the screen besides progress bar
you just need to modify this subroutine
or you just can use print*,'...' or
write(*,*)... after this subroutine.
******************* NEW BETTER CODE ********************
rogram progbar
implicit none
integer :: i_
integer :: iarg
real(8) :: rarg
do i_=1,125
rarg=real(i_,8)
iarg=int(51-50*cos(0.1*rarg))
call progress_bar(iarg)
call sleepqq(140)
end do
contains
subroutine progress_bar(ipercent)
implicit none
integer, intent(in) :: ipercent
character, allocatable :: symbar(:)
integer :: n_columns
integer :: n_elements
integer :: n_per_el
integer :: element
character,parameter :: esc = char(27)
character,parameter :: nl = char(10)
character,parameter :: bs = char(08)
character(len=3) :: numchar3
character(len=20) :: barform
n_columns=100
n_elements=n_columns/2 ! half of the screen
n_per_el=100/n_elements
allocate(symbar(n_elements))
symbar='*'
element=ipercent/n_per_el
WRITE(*,*) CHAR(27), '[2J' ! clean screen
WRITE(*,*) CHAR(27), '[1;1H' ! start from position (1,1)
write(numchar3,fmt='(i3)')element
barform='('//trim(adjustl(numchar3))//'a)'
write (*,fmt='(3a)',advance='no') ' ', ESC, '[1m' ! set bold
write (*,fmt='(3a)',advance='no') ' ', ESC, '[37m' ! white foreground
write (*,fmt='(3a)',advance='no') ' ', ESC, '[42m' ! green background
write(*,fmt='(i3)',advance='no')iarg
write (*, '(3a)',advance='no') ' ', ESC, '[41m' ! red background
write(*,fmt=barform,advance='no')symbar(
1:element)
write (*, '(3a)') ' ', ESC, '[0m' ! restores display defaults.
deallocate(symbar)
return
end subroutine progress_bar
end program progbar
--
igor.
Post Follow-up to this messageThe program runs on my compiler (Compaq Visual Fortran 6.6) with no errors. However, it porduces single color lines advancing to new line each time. So I think the problem here is the different compilers we are using. In other words, the output is many lines.
Post Follow-up to this messageIn article <cue7dl$d61$1@news-int2.gatech.edu>, gtg531e <gtg531e@prism.gatech.edu> wrote: .... > WRITE(*,*) CHAR(27), '[2J' ! clean screen > WRITE(*,*) CHAR(27), '[1;1H' ! start from position (1,1) .... I note that in all the other writes you are careful to use explicit formats, but in this one, you use list-directed formatting. I recommend sticking with the explicit formatting for things like this. List-directed formatting is for when you aren't picky about the details. In this case, you are (or should be) very picky. Let's see... checking the exact conditions, I think you are probably ok here, but very sensitive to details of things elsewhere. In any case, I still recommend using explicit formats where the details matter, as they do here. Specific details that matter very much here include whether the output strings are quoted and whether they have value separators (spaces or commas) between them. If either of those things happens, this won't work. The default is for those things not to happen, but that default can be overridden elsewhere, making this code "fragile". Oh, and I don't think I noticed anyone yet mentioning one of the "usual" caveats for this approach. It assumes an environment where ANSI escape sequences are recognized. That is true of many environments, but not all. In particular, it is true of some Windows environments, but not others. I forget the details of when it is and isn't true on Windows, but it is not something that can just be assumed to be installed in all Windows environments. (I think it is possible to make it work in any version of Windows, but that isn't the same thing as assuming that it just will work without taking some action on it). It is possible that this is the why the OP is not observing the desired behavior. To the OP... if this is the case, it has nothing to do with the compiler. But I don't know enough of the details of your system or exactly when this does and doesn't work in Windows. -- Richard Maine | Good judgment comes from experience; email: my first.last at org.domain | experience comes from bad judgment. org: nasa, domain: gov | -- Mark Twain
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.