HomePage | Optical Illusions | War Stories | QBasic | Dads Navy Days | Bristol | Bristol, USA | Bristol, Canada | Terre Haute | Miscellany | Web Stuff | About Ray | Site Map | Site Search | Messages | Credits | Links | Web Rings
QBasic | Errors | 40lb Weight | Bits | Chance | Colours | Dates | Delays | File Dialog | Files | Input | Matching | Menus | Mouse | Numbers | SeqNo | SIRDS | Sorts | Text | Timer | DLoads
Visual Basic has a percent flood fill feature which is useful for displaying the percentage complete of a process. I thought it would be nice to do my own in QBasic. It's not so pretty but does the job.
This is a slightly more complicated program, here's the code for it
:
DIM Count AS INTEGER 'Used for loops, general numeric variable DIM Hrs AS INTEGER 'Hold hours DIM Mins AS INTEGER ' Holds minutes DIM PerCent AS INTEGER 'Calculates percentage done DIM Counter AS LONG 'Used for loops, general numeric variable DIM Elapsed AS LONG 'Used to calculate times DIM Num AS LONG 'General numeric variable DIM EndTimer AS LONG 'Holds the end time DIM EstTime AS LONG 'Used to claculate times DIM secs AS LONG 'Holds seconds DIM StrtTimer AS LONG 'Holds the start time DIM PerCntdone AS STRING 'Used to calculate % done and position on screen CLS PRINT "Busy.Bas Ray Thomas, September 1998" PRINT PRINT "This small program can work out and display a percent done bar" PRINT "a la Visual Basic (but not so pretty)." PRINT PRINT PRINT "Press any key to continue ..." DO LOOP UNTIL INKEY$ <> "" Num = 307 'A made up number, could be the number of records to process CLS PRINT "Working, please wait ..." PRINT PRINT PRINT CHR$(201); STRING$(50, CHR$(205)); CHR$(187) PRINT CHR$(186); SPACE$(50); CHR$(186) PRINT CHR$(200); STRING$(50, CHR$(205)); CHR$(188) StrtTime = TIMER PRINT PRINT "Routine started on :", " "; MID$(DATE$, 4, 2); "/"; LEFT$(DATE$, 2); "/"; PRINT RIGHT$(DATE$,2); " at "; TIME$ FOR Count = 1 TO Num Hrs = 0 Mins = 0 secs = 0 FOR Counter = 1 TO 100000 'This loop merely to act as a delay NEXT Counter 'but could be processing records etc EndTime = TIMER Elapsed = EndTime - StrtTime 'gives the elapsed time in seconds secs = Elapsed IF Elapsed >= 60 THEN Mins = FIX(Elapsed / 60) secs = Elapsed - (60 * Mins) END IF IF Mins >= 60 THEN Hrs = FIX(Mins / 60) Mins = Mins - (60 * Hrs) END IF LOCATE 9, 1 PRINT "Elapsed time :", Hrs; "Hours"; Mins;"Minutes"; FIX(secs); "Seconds " Hrs = 0 Mins = 0 secs = 0 EstTimes = (Elapsed / Count) * (Num - Count) secs = EstTimes IF EstTimes >= 60 THEN Mins = FIX(EstTimes / 60) secs = EstTimes - (60 * Mins) END IF IF Mins >= 60 THEN Hrs = FIX(Mins / 60) Mins = Mins - (60 * Hrs) END IF LOCATE 10, 1 PRINT "Estimated time to go :", Hrs; "Hours";Mins; "Minutes"; FIX(secs); "Seconds " PerCent = (Count / Num) * 100 PerCntdone$ = STR$(PerCent) + "% complete " LOCATE 5, 2 PRINT STRING$(Count / (Num / 50), CHR$(177)); LOCATE 4, 20 PRINT PerCntdone$; NEXT Count LOCATE 1, 1 PRINT "Finished " LOCATE 11, 1 PRINT "Routine finished on :", " "; MID$(DATE$,4, 2); "/"; LEFT$(DATE$, 2); "/"; PRINT RIGHT$(DATE$,2); " at "; TIME$ PRINT "Number of iterations :", Num END
During May 2000, I had a very interesting email saying that if used near midnight then the above code will not work correctly. On investigation, I realised why, the time elapsed is worked out by using the TIMER function which returns the number of seconds elapsed since midnight.
Suppose the program was started at 11pm and ran till 2am. The line StrtTime = TIMER would make StrtTime equal to 82800 (the number of seconds in 23 hours). The line EndTime = TIMER would make EndTime equal to 7200 (the number of seconds in 2 hours). When working out the number of seconds elapsed, Elapsed = EndTime - StrtTime, would make Elapsed equal to -75600, which isn't quite what we want.
A solution would be to replace Elapsed = EndTime - StrtTime with :-
IF EndTime < StrtTime THEN Elapsed
= 86400 - StrtTime + EndTime
ELSE Elapsed = EndTime - StrtTime
86400 is the number of seconds in 24 hours.
Of course this only works if the program is running for less than one day, for longer processes additional problems are introduced. The programmer must check to see how many days have passed since the process was started. The DATE$ command can be used and then a routine written to do the maths of taking one date away from another, but because you have to take into account the differing number of days in a month a simpler solution would be to check the TIMER periodically, if the reading is less than the reading before then another variable, which would count the days needs to be incremented.
Just before the process to be timed starts insert :-
LastTime = TIMER
During the process to be timed (remember that this must be done before 24 hours have elapsed) insert:-
ThisTime = TIMER IF ThisTime < LastTime THEN DayCount = DayCount + 1 LastTime = ThisTime END IF
The total time elapsed can now be calculated as :-
EndTime = TIMER
Elapsed = (DayCount * 86400) + EndTime - StrtTime
The program snippets above may need editing, if the EndTime is very close to midnight then the DayCount counter may not be incremented properly. An extra line
IF EndTime < StrtTime THEN DayCount = DayCount + 1
may be needed to be added between the last two program lines.
During the email correspondence I wrote a program to investigate what happens to the system clock, TIMER and ON TIMER functions. The program changes the system time so it is best not to stop it from finishing itself, it will reset the system clock to the correct time when it finishes. As the clock passes midnight the system date will also change. The date is also reset near the end of the program.
Using the ON TIMER(x) GOSUB function and a simple counter loop. As in the program above there is a problem with the TIMER function as it changes from 86400 to 0 at midnight. The ON TIMER function however still works as it should. As in the above program the time elapsed calculation is corrected by the addition of 86400 to the calculation.
In November 2003, I received an email from Jonathan Simpson saying that in QBasic 7.1 the following code can be used
DIM a AS LONG, b AS LONG, days AS INTEGER a = INT(NOW) DO UNTIL something b = INT(NOW) IF b > a THEN days = days + 1: a = INT(NOW) LOCATE 1, 1: PRINT days, NOW LOOP
Unfortunately QBasic v1.1 hasn't this facility.
'Midnight Ray Thomas May 2000 'A program to investigate what happens to the system clock and 'TIMER functions at midnight CLS StartTime$ = TIME$ 'Get the time the program was started StartDate$ = DATE$ 'Get the present system date TIME$ = "23:59:55" 'Set the system time to just before midnight ProgStart = TIMER 'Get the number of seconds past midnight Start = TIMER ON TIMER(1) GOSUB TimeUp 'Set up the timer interupt TIMER ON 'Start the timer interupt FOR Count = 1 TO 1000000 'A do nothing loop NEXT Count TIMER OFF 'Stop the timer interupt PRINT "Count ended"; Count PRINT PRINT "Press any key to reset the system clock ..." DO LOOP UNTIL INKEY$ <> "" GOSUB ResetTime END TimeUp: '*** Do whatever you want to do after the timer interupts Finish = TIMER PRINT PRINT "The time is now: "; TIME$ '*** Stop the program to read what happens to the counters at midnight IF TIME$ = "00:00:02" THEN TIMER OFF PRINT "press any key to continue ..." DO LOOP UNTIL INKEY$ <> "" TIMER ON END IF PRINT "The Count is now at:"; Count PRINT Finish - Start; "seconds elapsed" '*** This is the part that checks for what happens at midnight '*** it is here that the start time is greater than the finish time IF Start > Finish THEN PRINT "Amended time elapsed"; 86400 - Start + Finish PRINT CINT(86400 - Start + Finish); "rounded amended second(s) elapsed" ELSE PRINT CINT(Finish - Start); "rounded second(s) elapsed" END IF PRINT "The end time is"; Finish PRINT "The start time is"; Start Start = TIMER RETURN ResetTime: '*** Work out the total time elapsed '*** and reset the system date and time PRINT PRINT "The date when the program was started was "; StartDate$ PRINT PRINT "The time when the program was started was "; StartTime$ PRINT PRINT "The date has changed to "; DATE$ PRINT PRINT "Resetting the date to "; StartDate$ PRINT DATE$ = StartDate$ Finish = TIMER PRINT "The program was running for"; CINT(86400 - ProgStart + Finish); "seconds" Hours = VAL(LEFT$(StartTime$, 2)) Mins = VAL(MID$(StartTime$, 4, 2)) Secs = VAL(RIGHT$(StartTime$, 2)) Finish = TIMER Secs = Secs + CINT(86400 - ProgStart + Finish) IF Secs > 60 THEN Mins = Mins + INT(Secs / 60) Secs = Secs MOD 60 END IF IF Mins > 60 THEN Hours = Hours + INT(Mins / 60) Mins = Mins MOD 60 END IF NewTime$ = LTRIM$(STR$(Hours)) + ":" + LTRIM$(STR$(Mins)) + ":" + LTRIM$(STR$(Secs)) TIME$ = NewTime$ PRINT PRINT "The time has been restored to "; TIME$ RETURN
QBasic | Errors | 40lb Weight | Bits | Chance | Colours | Dates | Delays | File Dialog | Files | Input | Matching | Menus | Mouse | Numbers | SeqNo | SIRDS | Sorts | Text | Timer | DLoads
HomePage | Optical Illusions | War Stories | QBasic | Dads Navy Days | Bristol | Bristol, USA | Bristol, Canada | Terre Haute | Miscellany | Web Stuff | About Ray | Site Map | Site Search | Messages | Credits | Links | Web Rings
This page last updated 23rd November 2003