
         INVENTING A PROGRAM
  First, decide on your ultimate goal. Be optimistic. Maybe you'd 
like the computer to play the perfect game of chess? Or translate 
every English sentence into French?

          Research the past
  Chances are, whatever you want the computer to do, someone else 
has thought of the same idea already, and written a program for 
it.
  Find out. Ask your friends. Ask the people in nearby schools, 
computer stores, computer centers, companies, libraries, and 
bookstores. Look through books and magazines. There are even 
books that list what programs have been written. Ask the company 
you bought your computer from.
  Even if you don't find exactly the program you're looking for, 
you may find one that's close enough to be okay, or that will 
work with just a little fixing, or can serve as part of your 
program, or will at least give you a clue as to where to begin. 
In one of the textbooks or magazines, you'll probably find a 
discussion of the problem you're trying to solve, and the pros 
and cons of various solutions to it ___ some methods are faster 
than others.
  Remember: if you keep your head in the sand, and don't look at 
what other people have done already, your programming effort may 
turn out to be a mere exercise useless to the rest of the world.

              Simplify
  All too often, programmers embark on huge projects and never 
get them done. Once you have an idea of what's been done before, 
and how hard your project seems to be, simplify it. Instead of 
making the computer play a perfect game of chess, how about 
settling for a game in which the computer plays unremarkably but 
at least doesn't cheat? Instead of translating every English 
sentence into French, how about translating just English colors? 
(We wrote that program already.) In other words, pick a less 
ambitious, more realistic goal, which if you achieve it, will 
make you feel good and will be a steppingstone to your ultimate 
goal.
  Finding a bug in a program is like finding a needle in a 
haystack: removing the needle is easier if the haystack is small 
than if you wait until more hay's been piled on.

           Specify the I/O
  Make your new, simple goal more precise. That's called 
specification. One way to be specific is to draw a picture, 
showing what your screen will look like if your program's running 
successfully.
  In that picture, find the lines typed by the computer. They 
become the PRINT statements in your program. Find the lines typed 
by the human: they become the INPUT statements. Now you can start 
writing your program: write the PRINT and INPUT statements on 
paper, with a pencil, and leave blank lines between them. You'll 
fill in the blanks later.
                                         Suppose you want the 
computer to find the average of two numbers. Your picture will 
look like this:
RUN
WHAT'S THE FIRST NUMBER? number
WHAT'S THE SECOND NUMBER? number
THE AVERAGE IS number
Your program at this stage will be:
10 INPUT "WHAT'S THE FIRST NUMBER";A
20 INPUT "WHAT'S THE SECOND NUMBER";B
etc.
100 PRINT "THE AVERAGE IS";C
All you have left to do is figure out what the ``etc.'' is. 
Here's the general method. . . . 

                                              Choose your statements
                                         Suppose you didn't have 
a computer. Then how would you get the answer?
                                         Would you have to use a 
mathematical formula? If so, put the formula into your program, 
but remember that the left side of the equation must have just 
one variable. For example, if you're trying to solve a problem 
about right triangles, you might have to use the Pythagorean 
formula A2+B2=C2; but the left side of the equation must have 
just one variable, so your program must say A=SQR(C^2-B^2), or 
B=SQR(C^2-A^2), or C=SQR(A^2+B^2), depending on whether you're 
trying to compute A, B, or C.
                                         Would you have to use a 
memorized list, such as an English-French dictionary or the 
population of each state or the weight of each chemical element? 
If so, that list becomes your DATA, and you need to READ it. If 
it would be helpful to have the data numbered, so the first piece 
of data is called X(1), the next piece of data is called X(2), 
etc., use the DIM statement.
                                         Subscripts are 
particularly useful if one long list of information will be 
referred to several times in the program.
                                         Does your reasoning 
repeat? That means your program should have a loop. If you know 
how many times to repeat, say FOR . . . NEXT. If you're not sure 
how often, say GO TO. If the thing that's to be repeated isn't 
repeated immediately, but only after several other things have 
happened, call the repeated part a subroutine, put it at the end 
of your program (followed by RETURN), and say GOSUB whenever you 
want it done.
                                         At some point in your 
reasoning, do you have to make a decision? Do you have to choose 
among several alternatives? The way to say ``choose'' is: IF . . 
. THEN. If you want the computer to make the choice arbitrarily, 
``by chance'', rather than because of a reason, say: IF RND(2)=1 
THEN.
                                         Do you have to compare 
two things? The way to say ``compare A with B'' is: IF A=B THEN.
          Write pseudocode
  Some English teachers say that before you write a paper, you 
should make an outline. Some computer teachers give similar 
advice about writing programs.
  The ``outline'' can look like a program in which some of the 
lines are written in plain English instead of computerese. For 
example, one statement in your outline might be:
130 A = the average of the twelve values of X
Such a statement, written in English instead of in computerese, 
is called pseudocode. Later, when you fill in the details, expand 
that pseudocode into the following:
130 S=O
131 FOR I = 1 TO 12
132     S=S+X(I)
133 NEXT
134 A=S/12

          Organize yourself
  Keep the program's over-all organization simple. That will make 
it easier for you to expand it and find bugs. Here is some 
folklore, handed down from generation to generation of 
programmers, that will simplify your organization. . . . 
  Use top-down programming. That means write a one-sentence 
description of your program; then expand that sentence to several 
sentences; then expand each of those sentences to several more 
sentences; and so on, until you can't expand any more. Then turn 
each of thse new sentences into lines of program. Your program 
will then be in the same order as the English sentences, and 
therefore organized the same way as an English-speaking mind.
  A variation is to use subroutines. That means writing the 
essence of the program as a very short main routine; instead of 
filling in the grubby details immediately, replace each piece of 
grubbiness by the word GOSUB. After the main routine is written, 
write each subroutine. Your program will be like a good book: 
your main routine will move swiftly, and the annoying details 
will be relegated to the appendices at the back; the appendices 
are called subroutines. Keep each subroutine down to 50 lines; if 
it starts getting longer and grubbier, replace each piece of 
grubbiness by a GOSUB to another subroutine, written afterwards 
and having higher line numbers.
  Avoid GO TO. It's hard for a human to understand a program 
that's a morass of GO TO statements. It's like trying to read a 
book where each paragraph says to turn to a different page! When 
you must say GO TO, try to go forward instead of backwards, and 
not go too far.
  Divide your program into modules. A module is a bunch of 
consecutive lines forming a unit that cannot be ``punctured''; in 
other words, there is no GO-TO-type statement outside the module 
that sends the computer to the module's middle; the only way the 
module can be activated is by starting with its top line. (If the 
module's particularly nice, the only way it can be deactivated is 
by arriving at its bottom line; in other words, there is no 
GO-TO-type statement in the module's middle that sends the 
computer outside the module.) If you used top-down programming, 
each module probably corresponds to one sentence in your 
program's description. Write that sentence at the top of the 
module, and put an apostrophe to the left of it.
                                                   Use variables
                                         After you've written a 
few lines of your program, you may find that your reasoning 
``almost repeats''; several lines bear a strong resemblance to 
each other. You can't use GO TO or FOR . . . NEXT or GOSUB . . . 
RETURN unless the lines repeat exactly. To make the repetition 
complete, use a variable to represent the parts that are 
different.
                                         For example, suppose 
your program contains these lines:
130 PRINT 29.3428+9.87627*SQR(5)
140 PRINT 29.3428+9.87627*SQR(7)
150 PRINT 29.3428+9.87627*SQR(9)
160 PRINT 29.3428+9.87627*SQR(11)
170 PRINT 29.3428+9.87627*SQR(13)
180 PRINT 29.3428+9.87627*SQR(15)
190 PRINT 29.3428+9.87627*SQR(17)
200 PRINT 29.3428+9.87627*SQR(19)
210 PRINT 29.3428+9.87627*SQR(21)
Each of those lines says PRINT 29.3428+9.87627*SQR(a number). The 
number keeps changing, so call it X. Lines 130-210 can be 
replaced by:
130 FOR X= 5 TO 21 STEP 2
140     PRINT 29.3428+9.87627*SQR(X)
150 NEXT
                                         Here's a harder example 
to fix:
130 PRINT 29.3428+9.87627*SQR(5)
140 PRINT 29.3428+9.87627*SQR(97.3)
150 PRINT 29.3428+9.87627*SQR(8.62)
160 PRINT 29.3428+9.87627*SQR(.4)
170 PRINT 29.3428+9.87627*SQR(200)
180 PRINT 29.3428+9.87627*SQR(12)
190 PRINT 29.3428+9.87627*SQR(591)
200 PRINT 29.3428+9.87627*SQR(.2)
210 PRINT 29.2428+9.87627*SQR(100076)
Again, let's use X. Those nine lines can be combined like this:
130 DATA 5,97.3,8.62,.4,200,12,591,.2,100076
140 FOR I = 1 TO 9
150     READ X
160     PRINT 29.3428+9.87627*SQR(X)
170 NEXT
                                         This one's even tougher:
130 PRINT 29.3428+9.87627*SQR(A)
140 PRINT 29.3428+9.87627*SQR(B)
150 PRINT 29.3428+9.87627*SQR(C)
160 PRINT 29.3428+9.87627*SQR(D)
170 PRINT 29.3428+9.87627*SQR(E)
180 PRINT 29.3428+9.87627*SQR(F)
190 PRINT 29.3428+9.87627*SQR(G)
200 PRINT 29.3428+9.87627*SQR(H)
210 PRINT 29.3428+9.87627*SQR(I)
Let's assume A, B, C, D, E, F, G, H, and I have been computed 
earlier in the program. The trick to shortening those lines is to 
change the names of the variables. Throughout the program, say 
X(1) instead of A, say X(2) instead of B, say X(3) instead of C, 
etc. Say DIM X(9) at the beginning of your program. Then lines 
130-210 can be written:
130 FOR I=1 TO 9
140     PRINT 29.3428+9.87627*SQR(X(I))
150 NEXT


    MAKE IT EFFICIENT
  Your program should be efficient. That means it should use as 
little of the computer's time and memory as possible.
  To use less of the computer's memory, make your DIMensions as 
small as possible. Try writing the program without any arrays at 
all; if that turns out to be terribly inconvenient, use the 
smallest and fewest arrays possible.
  To use less of the computer's time, avoid having the computer 
do the same thing more than once.
  These lines force the computer to compute SQR(8.2*N+7) three 
times:
50 PRINT SQR(8.3*N+7)+2
60 PRINT SQR(8.3*N+7)/9.1
70 PRINT 5-SQR(8.3*N+7)
You should change them to:
49 K=SQR(8.3*N+7)
50 PRINT K+2
60 PRINT K/9.1
70 PRINT 5-K
  These lines force the computer to compute X^9+2 a hundred 
times:
50 FOR I = 1 TO 100
60     PRINT (X^9+2)/I
70 NEXT
You should change them to:
49 K=X^9+2
50 FOR I = 1 TO 100
60     PRINT K/I
70 NEXT
  These lines force the computer to count to 100 twice:
50 S=0
60 FOR I = 1 TO 100
70     S=S+X(I)
80 NEXT
90 PRINT "THE SUM OF THE X'S IS";S
100 P=1
110 FOR I = 1 TO 100
120    P=P*X(I)
130 NEXT
140 PRINT "THE PRODUCT OF THE X'S IS";P
You should change them to:
50 S=0
51 P=1
60 FOR I = 1 TO 100
70     S=S+X(I)
71     P=P*X(I)
80 NEXT
90 PRINT "THE SUM OF THE X'S IS";S
140 PRINT "THE PRODUCT OF THE X'S IS";P
  Here are more tricks for making your program run faster. . . . 
  Instead of exponents, use multiplication:
Slow          Faster
50 Y=X^2      50 Y=X*X

                             Combine statements, to form a single 
line:
Slow                                     Faster
50 A=3                                   50 A=3: B=7
60 B=7
Warning: an IF statement cannot be combined with a later 
statement.
Cannot be combined
50 IF I<1 THEN GO TO 200
60 B=7
                             If a number contains a decimal point 
and is in a loop, turn the number into a variable:
Slow                                     Faster
                                         49 C=3.1
50 FOR I = 1 TO 900                      50 FOR I = 1 TO 900
60     S=S+3.1/I                         60     S=S+C/I
70 NEXT                                  70 NEXT
                             Omit the variable after NEXT (unless 
the FOR...NEXT loop contains another FOR...NEXT loop):
Slow                                     Faster
50 NEXT I                                50 NEXT
                             If your program doesn't involve 
decimals or large numbers, put this statement at the beginning of 
your program:
1 DEFINT A-Z
If your program involves just a few decimals or large numbers, 
begin your program by saying DEFINT A-Z, and put an exclamation 
point after every variable that stands for a real number.

                                             Alphabetizing
                             Suppose you want the computer to 
alphabetize a list of names. What's the best strategy?
                             Imagine trying to alphabetize the 
list yourself ___ each name is written on a file card, and you 
have to put the deck of cards in alphabetical order.
                             One strategy would be to compare the 
second card with the first, and swap them if necessary; then look 
at the third card, and swap if necessary; and so on to the end of 
the deck. A different strategy would be to put all the A's in one 
pile, all the B's in another, etc., and then sort each pile.
                             Which strategy is better? If the 
file has ten cards or less, the swap method is faster; if the 
file is very long, the 26-pile method is faster but requires 
space to lay out 26 piles.
                             Which method would make a more 
efficient program? That depends on how long the file is and 
whether your computer lacks fast parts or large memory.

                                             Prime numbers
                             An integer is called composite if 
it's the product of two other integers. 35 is composite, because 
it's 5*7; 9 is composite, because it's 3*3; 12 is composite, 
because it's 2*6; 13 is not composite, and is therefore called 
prime. This program tells whether a number is prime or composite:
10 INPUT "WHAT'S YOUR FAVORITE POSITIVE INTEGER";N
20 FOR I = 1 TO N-1
30     FOR J = 1 TO N-1
40         IF N=I*J THEN PRINT N;"IS";I;"TIMES";J;"AND 
COMPOSITE": END
50     NEXT
60 NEXT
70 PRINT N;"IS PRIME"
Line 10 waits for you to type a number N. Line 40 checks whether 
N is the product of two other integers; if it is, the computer 
says N is composite.
  How efficient is that program? Since it contains no arrays, it 
doesn't require much space in the memory. But if N turns out to 
be prime, line 40 is encountered once for every I and once for 
every J; altogether it's encountered (N-1)2 times. If N is a 
large number, around a million, (N-1)2 is around a trillion. To 
do line 40 a trillion times will take a typical microcomputer 
many years. In fact, if you say that your favorite number is 
999983 (which is close to a million), the typical microcomputer 
will take about 200 years before it comes to the conclusion that 
your number is prime! By the time the program finishes running, 
you'll be dead and so will your children! The program's very 
inefficient.
  Some small improvements are possible; for example, I and J can 
start at 2 instead of 1. But so long as you have a loop inside a 
loop, the time will remain very large.
  The following strategy requires just one loop: divide N by 
every integer less than it, to see whether the quotient is ever 
an integer. Here's the program:
10 INPUT "WHAT'S YOUR FAVORITE POSITIVE NUMBER";N
20 FOR I = 2 TO N-1
40     Q=N/I: IF Q=INT(Q) THEN PRINT N;"IS";I;"TIMES";Q;"AND 
COMPOSITE":END
60 NEXT
70 PRINT N;"IS PRIME"
Line 40 consists of two parts. The first part says to divide N by 
an integer (I); the quotient's called Q. The second part says 
that if Q is an integer, N is composite.
  How efficient is our new program? If N turns out to be prime, 
line 40 is encountered once for every I; altogether it's 
encountered N-2 times. That's less than in the previous program, 
where it was encountered (N-1)2 times. If N is about a million, 
our new program is nearly a million times faster than the 
previous one! To determine whether 999983 is prime, the new 
program takes a typical microcomputer about 3 hours instead of 
200 years.
  We can improve the program even further. If an N can't be 
divided by 2, it can't be divided by any even number; so after 
checking divisibility by 2, we have to check divisibility by just 
3, 5, 7, . . . , N-2. Let's put that short-cut into our program, 
and also say that every N less than 4 is prime:
10 INPUT "WHAT'S YOUR FAVORITE NUMBER";N
11 IF N<4 THEN PRINT N;"IS PRIME":END                                 
12 Q=N/2: IF Q=INT(Q) THEN PRINT N;"IS 2 TIMES";Q;"AND 
COMPOSITE": END
20 FOR I = 3 TO N-2 STEP 2
40     Q=N/I: IF Q=INT(Q) THEN PRINT N;"IS";I;"TIMES";Q;"AND 
COMPOSITE": END
60 NEXT
70 PRINT N;"IS PRIME"
Line 12 checks divisibility by 2; lines 20-60 check divisibility 
by 3, 5, 7, . . . , N-2. If N is prime, line 40 is encountered 
N/2 - 2 times, which is about half as often as in the previous 
program; so our new program takes about half as long to run. On a 
typical microcomputer, it takes about 1 hours to handle 999983.
  Our goal was to find a pair of integers whose product is N. If 
there is such a pair of integers, the smaller one will be no more 
than the square root of N, so we can restrict our hunt to the 
integers not exceeding the square root of N:
10 INPUT "WHAT'S YOUR FAVORITE NUMBER";N
11 IF N<4 THEN PRINT N;"IS PRIME":END
12 Q=N/2: IF Q=INT(Q) THEN PRINT N;"IS 2 TIMES";Q;"AND 
COMPOSITE": END
20 FOR I = 3 TO SQR(N)*1.00001 STEP 2
40     Q=N/I: IF Q=INT(Q) THEN PRINT N;"IS";I;"TIMES";Q;"AND 
COMPOSITE": END
60 NEXT
70 PRINT N;"IS PRIME"
The ``1.00001'' is to give a margin of safety, in case the 
computer rounds SQR(N) a bit down. If N is near a million, line 
40 is encountered about 500 times, which is much less than the 
500,000 times encountered in the previous program and the 
1,000,000,000,000 times in the original. This program lets the 
typical microcomputer handle 999983 in about 6 seconds. That's 
much quicker than the earlier versions, which required 1 hours, 
or 3 hours, or 200 years!
  Moral: a few small changes in a program can make the computer 
take 6 seconds instead of 200 years.
  The frightening thing about this example is that the first 
version we had was so terrible, but the only way to significantly 
improve it was to take a totally fresh approach. To be a 
successful programmer, you must always keep your mind open, and 
hunt for fresh ideas.


                 DON'T BE SILLY
  After you've written a program, skim through it to see whether 
any of its lines are silly. Eliminate the silly lines, so that 
your program becomes briefer, simpler, and more pleasant.
  In the following examples, I assume your program is numbered 
10, 20, 30, 40, . . . 

 Don't tell the computer to GO TO the next line
  For example, don't say:
30 GO TO 40
Omit it. The computer will go to line 40 anyway.
  Here's another example of a GO TO that goes to the next line:
30 IF X<7 THEN GO TO 40
Omit it. The computer will go to line 40 anyway.
  Here's another example of a GO TO that goes to the next line:
30 IF X<7 THEN PRINT "WOW" ELSE GO TO 40
Omit the ``ELSE GO TO 40''; just say:
30 IF X<7 THEN PRINT "WOW"

 Don't write an IF that skips over just one line
  For example, don't write:
30 IF X<7 THEN GO TO 50
40 PRINT "WOW"
That line 30 is an IF that skips over just line 40. It's silly! 
Combine lines 30 and 40 into a single line:
30 IF X>=7 THEN PRINT "WOW"

   Don't write an IF followed by its opposite
  For example, don't write:
30 IF X<7 THEN PRINT "GEE"
40 IF X>=7 THEN PRINT "WOW"
Combine them into a single line:
30 IF X<7 THEN PRINT "GEE" ELSE PRINT "WOW"
(That combination works only on computers that understand the 
word ELSE.)
  Here's another example of an IF followed by its opposite:
30 IF X<7 THEN GO TO 100
40 IF X>=7 THEN PRINT "WOW"
Remove the IF from line 40:
30 IF X<7 THEN GO TO 100
40 PRINT "WOW"
The new version does the same thing as the original, because the 
computer reaches the new 40 only if X is not less than 7.
                                                     Here's 
another IF followed by its opposite:
30 IF X<7 THEN GO TO 50
40 IF X>=7 THEN PRINT "WOW"
Applying the same technique as before, remove the IF from line 
40:
30 IF X<7 THEN GO TO 50
40 PRINT "WOW"
But also notice that line 30 is an IF that skips over just one 
line; we've uncovered another piece of silliness! Applying more 
cosmetics, we get down to a single line:
30 IF X>=7 THEN PRINT "WOW"
                                                     Here's 
another IF followed by its opposites:
30 IF X<7 THEN GO TO 100
40 IF X=7 THEN GO TO 200
50 IF X>7 THEN PRINT "WOW"
Remove the last IF:
30 IF X<7 THEN GO TO 100
40 IF X=7 THEN GO TO 200
50 PRINT "WOW"


       AVOID ROUND-OFF ERRORS
  The computer cannot handle decimals accurately. If you say 
X=.1, the computer can't set X equal to .1 exactly; instead, it 
will set X equal to a number very, very close to .1. The reason 
for the slight inaccuracy is that the computer thinks in 
``binary'', not decimals; and .1 cannot be expressed in binary 
exactly.
  Usually you won't see the slight inaccuracy: when you ask the 
computer to PRINT a number, the computer prints it rounded to six 
significant figures, and the inaccuracy is so small it doesn't 
show up in the rounded result. But there are three situations in 
which the inaccuracy can be noticed:
  1. Telling the computer to do A-B, where A is almost equal to 
B, and the first several digits of A are the same as the first 
several digits of B. For example, if you ask a typical 
microcomputer to print 8.001-8, the computer will not print .001; 
instead it will print .000999451. The same thing happens if you 
do 8.001+(-8).
  If you ask the typical microcomputer to print 987654.1-987654, 
it will print .125 instead of .1. The error can get magnified: if 
you ask the computer to multiply 987654.1-987654 by 1000, it will 
print .125*1000, which is 125, instead of .1*1000, which is 100. 
If you ask it to find the reciprocal of 987654.1-987654, it will 
print 1/.125, which is 8, instead of 1/.1, which is 10.
  Those are the errors produced by a typical microcomputer. The 
errors produced by your computer might be slightly more or less. 
But even if your computer is a maxi that costs $10,000,000, it 
makes those same kinds of errors.
  2. Saying ``FOR X = A TO B STEP C'', where C is a decimal and 
the loop will be done many times. For example:
10 FOR X = 1 TO 2 STEP .1
20     PRINT X
30 NEXT
Theoretically, the computer should print 1, 1.1, 1.2, 1.3, 1.4, 
1.5, 1.6, 1.7, 1.8, 1.9, and 2. But that's not what actually 
happens. In line 10, the computer can't handle the decimal .1 
accurately. The last few numbers the typical microcomputer thinks 
of are:
slightly more than 1.7
slightly more than 1.8
slightly more than 1.9
The computer does not think of the next number, slightly more 
than 2.0, because line 10 says not to go past 2. In line 20, the 
word PRINT makes the computer print the numbers rounded to six 
significant digits, so it prints:
 1
 1.1
 1.2
 1.3
 1.4
 1.5
 1.6
 1.7
 1.8
 1.9
It does not print 2.
  If you want to compute 1 + 1.1 + 1.2 + 1.3 + 1.4 + 1.5 + 1.6 + 
1.7 + 1.8 + 1.9 + 2, you might be tempted to write this program:
5 S=0
10 FOR X = 1 TO 2 STEP .1
20     S=S+X
30 NEXT
40 PRINT S
The computer will print a reasonable-looking answer: 14.5. But 
that ``answer'' is wrong, because the last number it added was 
slightly more than 1.9; it never added 2. The correct answer is 
16.5.
                                         One remedy is to change 
line 10 to this:
10 FOR X = 1 TO 2.05 STEP .1
The .05 after the 2 allows for the margin of error. The general 
strategy is to change ___ 
10 FOR X = A TO B STEP C
to this:
10 FOR X = A TO B+C/2 STEP C
                                         An alternative remedy is 
to replace ___ 
10 FOR X = 1 TO 2 STEP .1
by this pair of lines:
10 FOR I = 10 TO 20
11     X= I/10
As I goes from 10 to 20, X will go from 1 to 2 in steps of .1. 
This remedy is the most accurate of all, since it eliminates 
decimals from line 10. But the division in line 11 makes the 
program very slow.
                                         3. Asking the computer 
whether two numbers X and Y are equal. It's unwise to ask whether 
X is exactly equal to Y, since both X and Y have probably been 
affected by some slight error. Instead, ask the computer whether 
the difference between X and Y is much tinier than Y:
Bad                                              Good
IF X=Y THEN                                      IF 
ABS(X-Y)<=.000001*ABS(Y) THEN
The .000001 is requesting that the first six significant digits 
of X be the same as the first six significant digits of Y (except 
that the sixth significant digit might be off by one).

                                                    Why binary?
                                         From those discussions, 
you might think computers should be made differently, and that 
they should use the decimal system instead of binary. There are 
two counterarguments.
                                         First, binary arithmetic 
is faster.
                                         Second, even if 
computers were using the decimal system, inaccuracy would still 
occur. To store the fraction 2/3 accurately by using the decimal 
system, the computer would have to store a decimal point followed 
by infinitely many 6's. That would require an infinite amount of 
space in memory, which is impossible (unless you know how to 
build an infinitely large computer?) So even in the decimal 
system, some fractions must be approximated instead of handled 
exactly.

                                                Begin with the tiny
                                         According to 
mathematicians, addition is supposed to obey these laws:
A+0 is exactly the same as A
A+B is exactly the same as B+A
A+-A is exactly the same as 0
(A+B)+C is exactly the same as A+(B+C)
                                         On the computer, the 
first three laws hold, but the last does not. If A is a decimal 
tinier than C, the computer does (A+B)+C more accurately than 
A+(B+C). So to add a list of numbers accurately, begin by adding 
together the tiniest decimals in the list.

    TEST YOUR PROGRAM
  When you've written a program, test it: type RUN and see 
whether it works.
  If the computer does not gripe, your tendency will be to say 
``Whoopee!'' Don't cheer too loudly. The answers the computer is 
printing may be wrong. Even if its answers look reasonable, don't 
assume they're right: the computer's errors can be very subtle. 
Check some of its answers by doing them with a pencil.
  Even if the answers the computer prints are correct, don't 
cheer. Maybe you were just lucky. Type different input, and see 
whether your program still works. Chances are, there's something 
you can input that will make your program go crazy or print a 
wrong answer. Your mission: to find input that will reveal the 
existence of a bug.
  Try six kinds of input. . . . 

    Try simple input
  Type in simple integers, like 2 and 10, so the computation is 
simple, and you can check the computer's answers easily.

Try input that increases
  See how the computer's answer changes when the input changes 
from 2 to 1000.
  Does the change in the computer's answer look reasonable? Does 
the computer's answer go up when it should go up, and down when 
it should go down? . . . and by a reasonable amount?

Try input testing each IF
  For a program that says ___ 
30 IF X<7 THEN GO TO 100
input an X less than 7 (to see whether line 100 works), then an X 
greater than 7 (to see whether line 40 works), then an X equal to 
7 (to see whether you really want ``<'' instead of ``<=''), then 
an X very close to 7, to check round-off error.
  For a program that says ___ 
30 IF A^2+B<C THEN GO TO 100
input an A, B, and C that make A^2+B less than C. Then try inputs 
that make A^2+B very close to C.

    Try extreme input
  What happens if you input:
a huge number, like 45392000000 or 1E35?
a tiny number, like .00000003954 or 1E-35?
a trivial number, like 0 or 1?
a typical number, like 45.13?
a negative number, like -52?
Find out.
                             If the input is supposed to be a 
string, what happens if you input AAAAA or ZZZZZ? If there are 
supposed to be two inputs, what happens if you input the same 
thing for each?

                                Try input making some lines act strange
                             If your program contains division, 
try input that will make the divisor be zero or a tiny decimal 
close to zero. If your program contains the square root of a 
quantity, try input that will make the quantity be negative. If 
your program says ``FOR I=A TO B'', try input that will make B be 
less than A, then equal to A. If your program mentions X(I), try 
input that will make I be zero or negative or greater than the 
DIM.
                             Try input that causes round-off 
error: for a program that says ``A-B'' or says ``IF A=B THEN'', 
try input that will make A almost equal B.

                                              Try garbage
                             Many people hate computers because 
they often print wrong answers. A computer can print a wrong 
answer because its machinery is broken, or because a program has 
a bug. But the main reason why computers print wrong answers is 
that the input is incorrect. Incorrect input is called garbage. 
It has several causes. . . . 
                             The user's finger slips Instead of 
400, he inputs 4000. Instead of 27, he inputs 72. Trying to type 
.753, he leaves out the decimal point.
                             The user got wrong information He 
tries to input the temperature, but his thermometer is leaking. 
He tries to input the results of a questionnaire, but everybody 
who filled out his questionnaires lied.
                             The instructions aren't clear The 
program asks HOW FAR DID THE BALL FALL, and the user doesn't know 
whether to type the distance in feet or in meters.
                             Is time to be given in seconds or 
minutes? Are angles to be measured in degrees or radians?
                             If the program asks WHAT IS YOUR 
NAME, should the user type JOE SMITH or ``SMITH,JOE'' or just 
JOE?
                             Can the user input Y instead of YES?
                             Maybe the user isn't clear about 
whether to insert commas, quotation marks, and periods. If 
several items are to be typed, should they be typed on the same 
line or on separate lines? If your program asks HOW MANY BROTHERS 
AND SISTERS DO YOU HAVE, and the user has 2 brothers and 3 
sisters, should he type 5 or ``2,3'' or ``2 BROTHERS AND 3 
SISTERS''?
                             For a quiz that asks WHO WAS THE 
FIRST U.S. PRESIDENT, what if the user answers GEORGE WASHINGTON 
or simply WASHINGTON or G. WASHINGTON or GENERAL GEORGE 
WASHINGTON or PRESIDENT WASHINGTON or MARTHA'S HUSBAND? Make the 
instructions clearer:
WHO WAS THE FIRST U.S. PRESIDENT (GIVE JUST HIS LAST NAME)?
                             The user is trying to be funny or 
sabotage the computer Instead of inputting his name, he types an 
obscene comment. When asked how many brothers and sisters he has, 
he says 275.
                             Responsibility It's your 
responsibility as a programmer to make sure that the directions 
for using your program are clear, and that the program rejects 
ridiculous input.
                             For example, if your program is 
supposed to print weekly paychecks, it should refuse to print 
checks for more than $10000. Your program should contain these 
lines:
20 INPUT "HOW MUCH MONEY DID THE EMPLOYEE EARN";E
30 IF E>10000 THEN PRINT E;"IS QUITE A BIG PAYCHECK! I DON'T 
BELIEVE YOU.": PRIN T "PLEASE RETYPE YOUR REQUEST.": GO TO 20
Line 30 is called an error trap (or an error-handling routine). 
Your program should contain several, to prevent printing checks 
that are too small (2?) or negative or otherwise ridiculous 
($200.73145?)
                             To see how your program reacts to 
input that's either garbage or unusual, ask the person sitting 
next to you to run your program. That person might input 
something you never thought of.

                   DOCUMENT IT
  Write an explanation that helps other people understand your 
program. An explanation is called documentation; when you write 
an explanation, you're documenting the program.
  You can write the documentation on a separate sheet of paper 
(to be put in the computer center's library), or you can make the 
computer print the documentation when the user types RUN or LIST.
  A popular device is to begin the RUN by making the computer ask 
the user:
DO YOU NEED INSTRUCTIONS?
  You need two kinds of documentation: how to use the program, 
and how the program was written.

             How to use the program
  Your explanation of how to use the program should include:
the program's name
how to get the program from the disk
the program's purpose
a list of other programs that must be combined with this program, 
to make a workable combination
the correct way to type the input and data (show an example)
the correct way to interpret the output
the program's limitations (input it can't handle, a list of error 
messages that might be printed, round-off error)
a list of bugs you haven't fixed yet

           How the program was written
  An explanation of how you wrote the program will help other 
programmers borrow your ideas, and help them expand your program 
to meet new situations. It should include:
your name
the date you finished it
the computer you wrote it for
the language you wrote it in (probably BASIC)
the name of the method you used (``solves quadratic equations by 
using the quadratic formula'')
the name of the book or magazine where you found the method
the name of any program you borrowed ideas from
an informal explanation of how program works (``It loops until 
A>B, then computes the weather forecast.'')
the purpose of each module
the meaning of each variable
the meaning of reaching a line (if the program says IF X<60 THEN 
GO TO 1000, say ``Reaching line 1000 means the student 
flunked.'')
