Chapter Ten
Output Formatting, Part One
Keywords: CLS, LOCATE



Before we learn about screen formatting, here are the answers to the problems at the end of chapter 9. Here is the program to find the median of a list of numbers:
Download the Median Program Now!


TOP:

PRINT "Enter Number Of Items to Generate";

INPUT ITEMS

IF ITEMS > 200 THEN GOTO TOP

IF ITEMS < 2 THEN GOTO TOP

DIM A(ITEMS)

RANDOMIZE TIMER / 3

FOR NUM = 1 TO ITEMS

    LET A(NUM) = INT(100 * RND) + 1

NEXT NUM

FOR OUTER = 1 TO ITEMS - 1

    FOR INNER = OUTER + 1 TO ITEMS

        IF A(OUTER) <= A(INNER) THEN GOTO NOSWAP

        SWAP A(OUTER), A(INNER)

NOSWAP:

    NEXT INNER

    PRINT ".";

NEXT OUTER

PRINT

IF ITEMS / 2 = INT(ITEMS / 2) THEN GOTO EVEN

PRINT A(ITEMS / 2); "Is the Median."

GOTO DONE

EVEN:

LET MID1 = INT(ITEMS / 2)

LET MID2 = MID1 + 1

MEDIAN = (A(MID1) + A(MID2)) / 2

PRINT MEDIAN; "Is the Median."

DONE:

END

You may have noticed that we added a line (in green) which will print out a single period for every pass. This is to let the operator know that the program is working, and the computer hasn't gone out to lunch. This also required adding the PRINT command after the sort (also in green) to give us a carriage return. Also notice that we handled the cases for an odd number of items and an even number of items separately.

Let's look at our sorting program again. Here it is:


LET ITEMS = 50

DIM A(ITEMS)

RANDOMIZE TIMER / 3

PRINT "Unsorted List:"

FOR NUM = 1 TO ITEMS

    LET A(NUM) = INT(100 * RND) + 1

    PRINT A(NUM),

NEXT NUM

PRINT "Sorting Pass:"

FOR OUTER = 1 TO ITEMS - 1

    PRINT OUTER;

    FOR INNER = OUTER + 1 TO ITEMS

        IF A(OUTER) <= A(INNER) THEN GOTO NOCHANGE

        SWAP A(OUTER), A(INNER)

NOCHANGE:

    NEXT INNER

NEXT OUTER

PRINT

PRINT "Sorted List:"

FOR NUM = 1 TO ITEMS

    PRINT A(NUM),

NEXT NUM

END

To change our original sorting program to generate values between 1 and 1000, simply change the green line:


FOR NUM = 1 TO ITEMS

    LET A(NUM) = INT(1000 * RND) + 1

    PRINT A(NUM),

NEXT NUM

To change the original program to generate 150 items, change the first line to read:


LET ITEMS = 150

As you may remember, we wrote the original program in such a way as to easily change the number of items. Why? It is because we used a variable for the final value in defining the FOR...NEXT loops. We don't have to rewrite the program every time we need to change the number of items.

To change the original program to sort in descending order, change the IF...THEN line to:


IF A(OUTER) => A(INNER) THEN GOTO NOCHANGE

You may have noticed that when you run a program, anything that is sent to the screen with a PRINT command goes right below the line that was just printed, assuming no commas or semicolons. When the output line gets to the bottom, you notice that the rest of the screen scrolls up a line to make room for the new stuff. That is all well and good, but it just seems like things get a little messy after a while. Take the sorting program from chapter 9, for example. Let's say you typed in the whole program. When you run the program, the unsorted list starts printing out below whatever was there before, with everything else scrolling off the top. Wouldn't it be neat if we could start off with a "clean slate"? It would be a little nicer to have the screen erased when the program starts. Well, QBASIC has a command to do just that. It is the clear screen command, and it looks like this: CLS. Let's get ready to try it. First, fill up the screen with something. If you have a program in memory, run it a couple of times. If you don't have any program in memory, type in FILES (a QBASIC command to display the files in the current directory) a couple of times in the immediate window to fill up the screen. Once your output screen is full, type in CLS in immediate window, and watch what happens. Bingo! Your output screen is cleared! Now suppose you have cleared your screen, and used a bunch of PRINT commands to print out some kind of screen display, such as a series of boxes or something. Now, how do you get your cursor to a certain position to print out a number or letter? We use QBASIC's command that positions the cursor to any part of the screen. It is the LOCATE command. How do we use it? Take a look at this program segment:


...

CLS

LOCATE 20

...

After the CLS command, your screen would be cleared, and your cursor would be at the top of the screen. After the LOCATE command, they would go to the twentieth line down. That's nice, but what if we wanted to type something way over in column 75? Then we would use LOCATE 20,75. Let's try using these in a simple program.

Here is a variation of our sort program that we have designed strictly for learning purposes. It is stuck with sorting only 20 items. Go ahead and type these lines in:
Download the Sorting Example Now!



CLS

DIM A(20)

FOR LOOOP = 1 TO 20

    PRINT "Item number"; LOOOP; "is"

NEXT LOOOP

FOR LOOOP = 1 TO 20

    LET A(LOOOP) = INT(50 * RND) + 1

NEXT LOOOP

FOR LOOOP = 1 TO 20

    LOCATE LOOOP, 18

    PRINT A(LOOOP)

NEXT LOOOP

PRINT

PRINT "Sorting the List"

FOR OUTER = 1 TO 19

    FOR INNER = OUTER + 1 TO 20

        IF A(INNER) >= A(OUTER) THEN GOTO NOSWAP

        SWAP A(INNER), A(OUTER)

NOSWAP:

    NEXT INNER

NEXT OUTER

FOR EMPTY = 1 TO 50000

NEXT EMPTY

FOR LOOOP = 1 TO 20

    LOCATE LOOOP, 18

    PRINT A(LOOOP)

NEXT LOOOP

PRINT

PRINT "This Is the Sorted List"

END

Make sure that your variable LOOOP has 3 "O"'s in it, or you will get a bunch of error messages! The word LOOP is a reserved word in QBasic. Let's explain the green lines. What do they do? Nothing! All that they do it make the computer count from one to 50000. Why? Because it takes the computer a little bit of time to do that. This "holds up" the computer for about half of a second, so that you have a little time to look at the list while it gets sorted. The faster your computer runs, the less time it takes for it to count that high, and the shorter it waits. If you want the computer to wait longer, have it count up to a larger number, say 80000 or more. If you still need more time, have it count from -80000 to 80000. If you feel ambitious, you can use the TIMER command and an IF...THEN loop to have the computer wait a specific amount of time (in seconds). We'll show you that in the advanced series. The rest of the program is pretty straightforward. Go ahead and run it to see if it does what you expected.

The advantage of using the LOCATE statement is shown above, although it may not be too clear what with the screens popping up so fast. Let's take a closer look. Notice that we first cleared the screen, then dimensioned our array, and then printed our output screen? We haven't even generated the random numbers, yet! After we print the output screen, we then generate and assign our random numbers. Then using the LOCATE command followed by the PRINT command, we place the cursor where we want the number to print out. Then we print the number. See how we used our loop variable to position the cursor on the appropriate row? After that, we then sorted the list of numbers, and then had our empty FOR...NEXT loop to pause the computer for a bit. Then we printed out our sorted array, using the same technique for printing out the unsorted array. Did you notice that we didn't have to reprint out our "labels" again? Due to some technical reasons, this also makes the program run a bit faster. It takes a little bit of time to print out the labels, because the computer actually displays only one letter at a time. To print out each label takes up a lot of internal instructions in the computer. We won't go into it, but it is quite complicated!

For your information, most screens are 80 column wide and 24 lines high. That means your LOCATE command ranges from 1,1 for the top left, and 24,80 for the bottom right. There are a couple of exceptions to this, however, and they will be covered in the advanced series. Meanwhile, here are a couple of programs for you to try:

On the screen, have two headings, HEADS and TAILS. Flip a coin 2,500 times, and keep a tally of how many heads there were, and how many tails. Update the count on the screen after every coin flip, but only update the needed column. When you initially create the screen, go ahead and put a zero under each heading.

Using a FOR...NEXT loop and a LOCATE statement, draw a diagonal line of *'s on the screen from 1,1 to 22,22

Modify the above program to draw the "line" from 1,1 to 22,44. HINT: You can do calculations within the LOCATE command.

Next chapter, we will learn a very powerful option for the PRINT command that can do some really amazing formatting, especially when coupled with the LOCATE command we learned here. See you next time!!




Introduced In This Chapter:
KeyWords: CLS, LOCATE

Concepts: Clearing the screen, Placing the cursor at a particular print position on the screen without erasing the screen.


Previous Chapter Next Chapter