Programming in Tiny Basic

4 -- If an Elf Could Decide...

<Prev  Next>

In Chapter 3 you learned about changing the numbers stored in the computer's memory while the program is running. In this chapter you will learn about changlng the sequence of program commands, while the program is running.

In the last episode, you will recall, we left the hero of the story hanging on the edge of a cliff, ready to go crashing down to his doom with the wrong answer. Did you discover the problem? If not, try telling the program that you want to buy a $235 printer with $20 shipping and no tax. You see, one of the zeros is missing from the cents part. We do not know which zero yet so let's run it again, but assume the shipping is $20.07. Does that help you to discover the problem? What if the price were $236.03 (try both shipping charges)? The problem is not so much that you are getting the wrong answer, but that if the cents part is less than 10 the leading zero is not printed. We got a little too tricky! We would like to say to TINY something like, "print the cents part with two digits, even if the first digit is zero." Or maybe, "If the cents part is less than 10, then print an extra zero first."

Gee, that last one looks promising. Suppose TINY understood you when you said

IF C<10 THEN PRINT "0"
Well, did it? What is in C? Type in the following sequence of commands (notice which ones print out responses):
LET C=99
IF C<10 THEN PRINT "IT BETTER NOT BE"
LET C=10
IF C<10 THEN PRINT "IT IS STILL NOT <"
LET C=9
IF C<10 THEN PRINT "AHA!"
LET C=-99
IF C<10 THEN PRINT "WELL, WHAT DID YOU EXPECT?"
So it looks like this will solve the problem. We need to insert our correction between lines 160 and 170.
165 IF C<10 THEN PRINT 0;
Notice that we still end with a semicolon, because the cents in C is still coming. Try the program again with that $235 printer. Can you find any more problems (we call them bugs; getting rid of them is called debugging)? Note: just because you cannot find any bugs in your program does not mean that there are none.

Let's play with the IF command some more. CLEAR out your program from memory, so you can put a new one in.

I used to have trouble with Roman numerals when I was younger. Maybe you did too. We
will write a program to convert decimal numbers to Roman Numerals. What it will do is INPUT a nomber, then slowly convert it to Roman on one printed line. The number we will work with will be in variable N:

10 PRINT "NUMBER";
20 INPUT N
As I write this, I am not sure how much memory the program will take. If you have only 4K the program probably cannot process very large numbers. I will write the program backwards, then quit when I run out of space. This is OK, because TINY will put the lines in order as we type them in. I will suppose that line number 500 is a good line to end on (the line numbers are quite arbitrary; I am just guessing that I will not need more lines than will fit in less than 500). We assume that all that is left of the number in N is less than 4 (I will explain how N got that way as we go along):
500 END
490 PRINT
480 IF N>O THEN PRINT "I";
470 IF N>1 THEN PRINT "I";
460 IF N>2 THEN PRINT "I";
You can try this much out, if you want to RUN it. When it asks for a number, be sure to type in a number less than 4.

We assumed the number would be less than 4 when the program reached this point, so let's make it so:

450 LET N=N-N/4*4
This, as you will recall, sets N to the value of the remainder of N divided by (in this case) 4. Four is a special case:
440 IF N=4 THEN PRINT "IV";
If the number is greater than or equal to five (but less than nine) we print a "V":
420 IF N>=5 THEN PRINT "V";
430 LET N=N-N/5*5
Notice I could have just as easily written,
430 IF N>=5 THEN LET N=N-5
but you see. this takes more typing and thus more space in memory. Each character (letter, digit, etc.) of each line takes one byte of memory. Later I will show you some ways to save memory space. Try the program again. It should take numbers up to 8 now.

I don't think you will have any difficulty seeing that Roman Numeral 9 works like 4 and that the tens work like the ones:

400 IF N=9 THEN PRINT "IX";
410 LET N=N-N/9*9
390 LET N=N-N/10*10
380 IF N>=10 THEN PRINT "X";
370 IF N>=20 THEN PRINT "X";
360 IF N>=30 THEN PRINT "X";
350 LET N=N-N/40*40
340 IF N/10=4 THEN PRINT "XL";
330 LET N=N-N/50*50
Watch out for the lines that contain the sequence, "LET N=N-N/ ...". It is awfully easy to lose your place and drop one of the Ns out.

Well that is about all the program you can get into 4K. If you have more memory you are welcome to expand it. But first let's think a little more about how it works (with a demonstration, of course). Type RUN, and when it asks you for a number, type in 47.

Here is how it does it (you might like to follow the program listing while reading this paragraph): The first thing the program does is remainder the number by 50. That is, we are not interested In any part of the number greater than fifty. If there had been more room, perhaps the program could have been expanded to take numbers up to 5000 or some such. However, the remainder of 47 divided by 50 is 47. No problem. Now 47 divided by 10 is equal to 4, so the rest of line 340 is executed, and an "XL" is printed. The number in N is then remaindered by 40, which is seven. The IFs in lines 360, 370 and 380 are all false, so nothing is printed from them. In fact, the next interesting line is 420, since only then is the IF true,and "V" is printed. Finally, dividing by five the remainder is 2, so 460 is false, but 470 and 480 are true, and two "I"s are printed. Line 490 prints a nothing to end the line. Try another number and see if you understand it.

When we look at this program we see a lot of nearly identical lines, such as for example, lines 460,470, and 480. Wouldn't it be easier to say something like, "if N>O then print "I", subtract one from N, and try again; but if N=0 then quit"? Well, each line has a line number on it; do you think the computer could "go to" a line that was not the next line? Let's see how that would work:

460 IF N=0 THEN GO TO 490
470 PRINT "I";
480 LET N=N-1
485 GOTO 460
Now you see, that takes more lines in the program (we had to add line number 485), but they are much shorter, so we saved a little space. Perhaps we can get some more savings:
360 IF N<10 THEN GO TO 400
370 PRINT "X";
380 LET N=N-10
390 GO TO 360
I hope you are trying each set of changes out to convince yourself that the program still works the same.

Now let's try a real tricky modification. So tricky, in fact, that if you show it to a Computer Science expert, he will tell you it is "bad programming structure." Never mind him; he will also tell you TINY BASIC is a crummy language. He just has no appreciation. Besides that, he is jealous of your low-cost computer. What we will do is, if N is 4 or 9 (you can tell if it is by remaindering by 5), we will print a single "I", then add one and run it back through the tens routine (a routine is a few lines of program that does one thing). Of course if it was 4, the tens routine will do nothing and eventually line 420 will print a "V". On the other hand if it was 9, line 360 will see a 10, and the program will print another "X" after that "I". Do you understand? If not, you should try to follow the program through just as if you were the computer. First type in the six lines of changes (below), so you will not forget them.

To understand a complicated program (and also to get a feel for how much work the computer is really doing), we do what is sometimes called "a hand simulation." On a piece of paper make separate columns for each variable the program will be using; In this case there is only one variable of interest: N. On another piece of paper, or on another part of this piece, we will hand-print (in nice computer-like block letters) exactly what the computer would print out.

We will start at line 360 of the program with N=29, so write "29" in the column labeled "N". Look at line 360 of the program (you can look at a single line by typing LIST 360) and do whatever it says. In this case it says "IF N<10 ..." but the number under N on your paper is not less than ten (it is 29), so ignore the rest of the line and go to the next. You can look at the next line by typing LIST 360+1. This says to PRINT an "X" on your output line (on the paper). Next line (LIST 370+1) toils you to LET N=N-10. In other words, start with the "=" sign and figure out N (which is 29 on your paper) minus 10, then cross out the 29 and write "19" under it, since this command puts a new value in the variable N. The next line tells you to GO TO 360, so go LIST 360 again. The third time around N will be 9, which is less than 10, so you GO TO line 400. Now at line 400 you need to calculate the value of "N-N/5*5" to see if it is less than 4 (it isn't), but this is not a LET command so don't change anything in the "N" column on your paper, just go to the next line, print an "I" on your paper next to the two Xs, then add one to N (that makes 10) and go back to line 360 again. It may seem tiresome, but when you reach the END on line 500 you really understand what happened, and why.

Oh, here are the changes:

440
450
400 IF N-N/5*5<4 THEN GO TO 420
405 PRINT "I";
410 LET N=N+1
415 GO TO 360
Once you are convinced that you understand what this program does (and more important, how it does it), you should be able to add a line (how about line number 320?) that prints "L" if the starting number is greater than or equal to 50. If you have 8K of memory or more, see if you can extend our program with its modifications to numbers over 100. Over 1000? Note that it might help to write down on a piece of paper what you are trying to do.

There is one more thing you can do to your program to make it easier to use. We assume that you probably want to test several numbers in the program each time you modify it or demonstrate it to a friend. Wouldn't it be nice if you did not have to type RUN each time? Can you guess what to add to the program to make the computer go back to input another number after it finishes the previous? Yes, we will use a GO TO:

495 GO TO 10
Gee, that is a lot easier to usel Only one problem - how do you get it to stop? If it is already running you are in a pickle (I will tell you how to get out in a minute). But the clean way to prevent an endless loop (a program that has a GO TO back to some earlier line with no way out) is to provide an exit. Notice that for all the other GO TO commands in the program that go backwards, there is always something being done to N so that the next time by the decision affecting that GO TO is different. But in this last case N is always zero when it reaches the GO TO on line 495. But wait, what is the Roman Numeral for zero? What does the program print out? That's right, there is no Roman Numeral for zero. So let's have the program notice that you gave it a zero input, and make that the escape hatch:
30 IF N=0 THEN GO TO 500
Now actually, line 500 is just the end of the program. We could just as easily tell TINY BASIC to end it right here if N=0:
30 IF N=0 THEN END
I said I would tell you how to get out of the endless loop. Perhaps you already discovered it accidentally.

If the program is waiting for input (you can tell by the question mark prompt), a space will be ignored, and an ESCape or Return will only start a new line with another question mark. Numbers and letters are accepted as input. The way to get out of this condition is to type something illegal, like a period, followed by the RETURN key. TINY will not know what to do with the period, and will respond with error message number 556 and the line number of the INPUT line.

If the program is busy computing (it blanks out the TV screen while it Is computing),' you can stop it by pressing any key on your keyboard. I prefer an ESCape, but if you do not want to lose a line of output that might be on the top of the screen, a space will also do. This will,cause an error message (number 0), and will also tell you the line number that it was about to do. If you change your mind and you wish you had not stopped it, you can type GO TO and the line number it stopped at, and it will continue executing where it left off. For example, if you break out of the Roman Numeral program by hitting the space bar, it might type

!0 AT #390
If you had only bumped the keyboard and you want it to continue, type
GO TO 390
Or if you just want to start over, you can do that by typing RUN.

Incidentally, if you suspect there is a bug in the program, you can always break out (by one of the above techniques), then LIST parts of the program, PRINT any variables to see what is in them, or even make changes in the program or variables, then continue at the line you broke out of.

If you know the program is printing things and you just want to take time to look at them without killing the program, press the "|" key on the corner of your ELF. This works the same as when you are listing.

Now you know quite a bit about programming. In the next chapter we will learn some sophisticated memory-saving techniques, some of which you have already seen in this chapter.
 

Back to Top
Continue with: 5 -- Call for Savings