Design 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
Whatever you want the computer to do, someone else probably thought of the same idea already and wrote a program for it.
Find out. Ask your friends. Ask folks 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 serve as part of your program or at least give you a clue as to where to begin. In a 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 programmers have done already, your programming effort may turn out to be a mere exercise, useless to the rest of the world.
Simplify
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 is, 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 achieved will please you and 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 your program’s PRINT statements. 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:
What's the first number? 7
What's the second number? 9
The average is 8
Your program at this stage will be:
CLS
INPUT "What's the first number"; a
INPUT "What's the second number"; b
etc.
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 equation’s left side 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 a²+b²=c²; 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 DO...LOOP. If the thing to be repeated isn’t repeated immediately, but just after several other things have happened, make the repeated part be a SUB procedure.
At some point in your reasoning, do you have to make a decision? Do you have to choose among several alternatives? To choose between two alternatives, say IF...THEN. To choose among three or more alternatives, say SELECT CASE. If you want the computer to make the choice arbitrarily, "by chance" instead of for a reason, say IF RND<.5.
Do you have to compare two things? The way to say "compare x with y" is: IF x = y 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:
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:sum = 0
FOR i = 1 TO 12
sum = sum + x(i)
133 NEXT
average = sum / 12
Organize yourself
Keep the program’s over-all organization simple. That will make it easier for you to expand the program and find bugs. Here’s 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 those new sentences into lines of program. Then your program will 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 SUB procedures. That means writing the essence of the program as a very short main procedure; instead of filling in the grubby details immediately, replace each piece of grubbiness by a SUB procedure. Your program will be like a good book: your main procedure will move swiftly, and the annoying details will be relegated to the appendices at the back; the appendices are the SUB procedures. Make each procedure brief — no more than 20 lines — so the entire procedure can fit on the screen; if it starts getting longer and grubbier, replace each piece of grubbiness by another SUB procedure.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.Use variables
After you’ve written some lines of your program, you may notice that your reasoning "almost repeats": several lines bear a strong resemblance to each other. You can’t use DO...LOOP or FOR...NEXT 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:
PRINT 29.34281 + 9.876237 * SQR(5)
PRINT 29.34281 + 9.876237 * SQR(7)
PRINT 29.34281 + 9.876237 * SQR(9)
PRINT 29.34281 + 9.876237 * SQR(11)
PRINT 29.34281 + 9.876237 * SQR(13)
PRINT 29.34281 + 9.876237 * SQR(15)
PRINT 29.34281 + 9.876237 * SQR(17)
PRINT 29.34281 + 9.876237 * SQR(19)
PRINT 29.34281 + 9.876237 * SQR(21)
Each of those lines says PRINT 29.3428 + 9.87627 * SQR(a number). The number keeps changing, so call it x. All those PRINT lines can be replaced by this loop:
FOR x = 5 TO 21 STEP 2
PRINT 29.34281 + 9.876237 * SQR(x)
NEXT
Here’s a harder example to fix:
PRINT 29.34281 + 9.876237 * SQR(5)
PRINT 29.34281 + 9.876237 * SQR(97.3)
PRINT 29.34281 + 9.876237 * SQR(8.62)
PRINT 29.34281 + 9.876237 * SQR(.4)
PRINT 29.34281 + 9.876237 * SQR(200)
PRINT 29.34281 + 9.876237 * SQR(12)
PRINT 29.34281 + 9.876237 * SQR(591)
PRINT 29.34281 + 9.876237 * SQR(.2)
PRINT 29.24281 + 9.876237 * SQR(100076)
Again, let’s use x. All those PRINT lines can be combined like this:
DATA 5,97.3,8.62,.4,200,12,591,.2,100076
FOR i = 1 TO 9
READ x
PRINT 29.34281 + 9.876237 * SQR(x)
NEXT
This one’s even tougher:
PRINT 29.34281 + 9.876237 * SQR(a)
PRINT 29.34281 + 9.876237 * SQR(b)
PRINT 29.34281 + 9.876237 * SQR(c)
PRINT 29.34281 + 9.876237 * SQR(d)
PRINT 29.34281 + 9.876237 * SQR(e)
PRINT 29.34281 + 9.876237 * SQR(f)
PRINT 29.34281 + 9.876237 * SQR(g)
PRINT 29.34281 + 9.876237 * SQR(h)
PRINT 29.34281 + 9.876237 * 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 replace all those PRINT lines by this loop:
FOR i = 1 TO 9
PRINT 29.34281 + 9.876237 * SQR(x(i))
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:
PRINT SQR(8.3 * n + 7) + 2
PRINT SQR(8.3 * n + 7) / 9.1
PRINT 5 - SQR(8.3 * n + 7)
You should change them to:
k = SQR(8.3 * n + 7)
PRINT k + 2
PRINT k / 9.1
PRINT 5 - k
These lines force the computer to compute x ^ 9 + 2 a hundred times:
FOR i = 1 TO 100
PRINT (x ^ 9 + 2) / i
NEXT
You should change them to:
k = x ^ 9 + 2
FOR i = 1 TO 100
PRINT k / i
NEXT
These lines force the computer to count to 100 twice:
sum = 0
FOR i = 1 TO 100
sum = sum + x(i)
NEXT
PRINT "The sum of the x's is"; sum
product = 1
FOR i = 1 TO 100
product = product * x(i)
NEXT
PRINT "The product of the x's is"; product
You should combine the two FOR...NEXT loops into a single FOR...NEXT loop, so the computer counts to 100 just once. Here’s how:
sum = 0
product = 1
FOR i = 1 TO 100
sum = sum + x(i)
product = product * x(i)
NEXT
PRINT "The sum of the x's is"; sum
PRINT "The product of the x's is"; product
Here are more tricks to make your program run faster.…
Instead of exponents, use multiplication.
slow:
y = x ^ 2faster:
y = x * xIf your program doesn’t involve decimals or big numbers, put this statement at the top of your program:
DEFINT A-Z
If your program involves just a few decimals or big numbers, begin your program by saying DEFINT A-Z; then put the symbol "&" after every variable that stands for a long integer, and put the symbol "!" after every variable that stands for a single-precision real number.
Test it
When you’ve written a program,
test it: run it 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 might be wrong. Even if its answers look reasonable, don’t assume they’re right: the computer’s errors can be subtle. Check some of its answers by computing 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. Probably you can input something 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 —
IF x < 7 THEN GOTO 10
input an x less than 7 (to see whether line 10 works), then an x greater than 7 (to see whether the line underneath the IF line 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 —
IF x ^ 2 + y < z THEN GOTO 10
input an x, y, and z that make x ^ 2 + y less than z. Then try inputs that make x ^ 2 + y very close to z.
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? What happens if you capitalize the input? If there are supposed to be two inputs, what happens if you input the same thing for each?
Try input making a line 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 = x TO y", try input that will make y be less than x, then equal to x. 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 "x - y" or says "IF x = y", try input that will make x almost equal y.
Try garbage
Computers often print wrong answers. A computer can print a wrong answer because its circuitry is broken or because a program has a bug. But
the main reason why computers print wrong answers is incorrect input. Incorrect input is called garbage and 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?" but 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 & 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 "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 tries to joke or sabotage
Instead of inputting his name, he types an obscene comment. When asked how many brothers and sisters he has, he says 275.Responsibility
As a programmer, it’s your duty to include clear directions for using your program, and you must make the program reject 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:
10 INPUT "How much money did the employee earn"; e
IF e > 10000 THEN
PRINT e; "is quite a big paycheck! I don't believe you."
PRINT "Please retype your request."
GO TO 10
END IF
That IF line is called an
error trap (or 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 a friend 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, or you can make the computer print the documentation when the user runs or lists the program.
A popular device is to begin the program 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 x>y, then computes the weather forecast.")
the purpose of each SUB procedure
the meaning of each variable
the significance of reaching a line (for a program saying "IF x < 60 THEN GOTO 1000", say "Reaching line 1000 means the student flunked.")