Classic Computer Magazine Archive CREATIVE COMPUTING VOL. 9, NO. 12 / DECEMBER 1983 / PAGE 156

The first program; what to do after you read the manual. Stephen Kimmel.

The First Program

What To Do After You Read The Manual

You have been told how easy it is to write useful programs on your new $200 Goshwow personal computer. Being a good person who always brushes after every meal, you dutifully worked your way through the Basic instruction book--maybe two of them.

You are confident that you can unravel the secret meaning of any command. You are ready to try a real program. Something worthwhile. Something that will prove to your spouse that you didn't waste that $200. So you sit down at your machine, and you stare at the blank screen. The word READY has never had such an ominous look to it before. No brilliant programming pours forth from your fingers. You know, somehow, that you have done something wrong.

The books told you what all the commands and functions do. They told you what was legal and what was illegal. Programming is a great deal more than knowing the commands and error statements. But most books don't tell you that. They don't tell you how to go about the task of writing a major piece of software. This article presents one logical approach to organizing that job. I will walk you all the way through a program. We will start with an idea and finish with a working program.

By the time we are done, we will have a pretty good set of documentation as well. There will still be room for improvement in the program and our documentation won't be especially beautiful, but that is true of almost all programs. Once you have followed the steps a few times on your own it will be as natural as zapping Klingons.

Thinking Logically

Programming is a discipline of logical thinking. The computer is supremely logical if slightly misguided. It assumes that you know what you are talking about and does exactly what you tell it to do exactly as you tell it to do it. You won't make much progress persuading a machine that would make a tadpole look like Einstein unless you think the project through completely before you start programming.

For the new programmer this is a new experience. We are used to dealing with people who are capable, for the most part, of figuring out what we mean and filling in gaps and inconsistencies in what we say. The computer can't do any of that. You must approach a computer program in a logical manner. You must think logically. It is simply a matter of practice. You can do it. The problem is surviving the panic and uncertainty of the first program.

The key element, then, is the organization of the task. If you had a very good programming instruction book, it told you that one of the most important aspects of writing any computer program is writing the documentation. Documentation is a word that makes some programmers visibly ill. It is the part of programming that is the least fun.

You write out the meanings of all of the variables, explain the functioning of the various routines, and generally explain how the program works and how the user should use it. Doesn't sound like a lot of laughs, does it? The problem that most programmers have with documentation is that they put it off until the very end. Then it is simply required drudgery.

Their approach to documentation is illogical. You must work through the entire program in a logical manner at least once when you do your documentation. If you put it off until the end, you have to do it twice; once when you design the program and once when you write the documentation. If you do it first, or at least start it first, it will make writing the program much easier.

Writing a major piece of software is a question of thinking the matter through in a logical order, of organizing the task, and of breaking the job into manageable portions. All of that can be done by working out the documentation before you start programming.

Not all of these steps are directly related to writing the documentation, but they will carry you through to a program that will do the job. So let's get down to business.

Step One

Get an idea and decide what you want to do. Certainly that much is obvious. It doesn't have to be a big idea. Little ones are just fine. By the time we are finished, even a little idea may have grown into a major program. Even something as trivial as balancing your checkbook can become a major worthwhile program if you allow it to grow. It will do so if you allow your imagination to work on it.

For our example, we will do a stock market program. This one of course will be a little different. There are plenty of programs around that will analyze the value of my portfolio. No, with delusions of adequacy bouncing through my skull, I want something that will predict stock prices for me.

I have observed that the long-term drift of some stocks is up over the years, while others seem to drift lower. If I could project what the high and low prices of a stock would be this year, I could make a bundle. It would be a simple matter of buying low and selling high. This seems like a worthy task for the computer so we will use it.

A brief note is in order here before we go on. The example program here is fully functional. But not even the now famous Cretins From Mars would dream of using it as their primary investment tool. The basic procedure has done very nicely for me, but, I also do a great deal of research into the companies before I buy the stock. Anyone who does less . . . well there is an old saying about those people and their money.

Now we have decided on what we are going to do and have completed step one. Note that the idea isn't magnificent; I am sure we could accomplish the basic task on a pocket calculator. But this basic idea will change and expand before we are done.

Step Two

Design the output. Name the variables that will be printed out. Take two sheets of paper. One will be a rough sketch of the output screen. Put labels across the top and the side. Throw in a few numbers. Give some consideration at this point to how you will deal with the limitations of your screen display. Can you get all the information in 40 columns? Will you need more than one screen to display everything you want? Figure 1 is the preliminary design for my screen display.

My variable list is shown in Table 1. This list is the beginning of our documentation. You can see how much easier it will be to do this now than waiting until later. The other choice is to try to figure everything out after finishing the program. If you try this several weeks later it will be a pain. We will add to our initial list of variables as we go along.

Doing it this way eliminates the possibility of using the same variable name for two different things at different places in the program. That can be a particularly difficult bug to track down. And, for example, we will use this list in creating our PRINT statements. The Basic output statement will be

PRINT NS$ (I); CP (I); HP (I); LP (I); GP (I)

It bears some repeating. Give your variables names that are meaningful. Sure. You could use A$ for Stock Name but what is the point? You can't really hide a Basic program very well. You can just make it harder on yourself and others who have to work on your program. So use SN$. Use STOCKNAME if your machine will support a variable name that long.

Step Three

Write a list of inputs needed to create those outputs. Name those variables and add them to the list. For this task I will need the high and low prices for each stock for several years. I get these from the Stock Guides published by Standard and Poors. I will also need the closing prices, which I will get from the Wall Street Journal. I will take the last dividend said and the 52-week high and low prices. Obviously I will need the names of the stocks, but I can make those up. These variables will form the heart of our INPUT statements. So we extend our variable list with the following:

NY(I)--Number of Years of data on stock I

H(IJ)--High price of stock I in year J

L(IJ)--Low price of stock I in year J

LD(I)--Last Dividend

H5(I)--52-week high price

L5(I)--52-week low price

J--General purpose counter

Step Four

Decide what formulas or procedures you will need. The formulas will be the guts of the program. Most of the rest could be considered utilities to keep everything neat and clean. Some programs don't use formulas in the classic sense. They deal with procedures and you need to work out what those procedures will be.

Two of my formulas are straight-forward. I am now calculating yield using

Y (I)=LD (I)/CP (I) 100

and the possible growth as

GP (I)=(HP (I)/CP (I) - 1) 100

The equation for the curve fitting routine was taken from a book of mathematical tables. I have already done the algebraic manipulations to put those in a form that the program can use. My experience is that many things work faster and are easier to program if you solve some of the preliminaries first.

You will run into this sort of problem only in cases that require algebra. There are plenty of tasks and programs that don't require anything this exotic. But if you choose a task that requires it, you will have to be able to work it out yourself. Or you will have to find someone who can.

The formulas that appear in this program are a Least Means Square fit for a straight line to minimize the amount that the points are off. I have solved the equations for a special case. The general equation for a line is:

Y = M X + C

Since I am interested only in a single year's worth of data, I decided to call this year 0. That means that I need to solve only for C since the value of M will be negated by the X value of zero.

Step Five

Write, in English, a simplified procedure for what you want to do. Number the steps. Now, finally, we are ready to start thinking about the program. Slap these steps down quickly so we will have a form for the entire project before we start to work out the details. An important note here: always put initialization first.

My rough list for this program is:

0. Initialization

1. Get the data on the stocks

2. Make the calculations

3. Display the results

For some programmers this is the point at which they start thinking about drawing a simple flow chart. Everyone should learn to use flow charts if only to find out what they can do. That is a subject for another article. I never use them.

Step Six

Think some more about the project. Add steps to the procedure list to cover anything you can dream up. Imagine as many different possibilities as you can. Hmmm. We might want to look at the same stocks more than once, and it would be quite a hassle to re-enter all that information all the time. Besides, I have a disk drive to use for this sort of thing. So I write:

4. Save stock data on disk

And, of course, that doesn't make much sense without:

5. Get stock data from disk

I also have a printer so I will

6. Print the output as an option

It is also possible, though unlikely, that I will make a mistake in entering the data, so I had better have the program:

7. Check for Input Errors

Speaking of errors, what if the program projects a high that is lower than the low? Or a low that is lower than zero? I guess we should:

8. Check projected highs and lows for errors

9. Check for disk errors

It would be nice if I could see the list of names in alphabetical order. So let's

11. Sort the stocks

and the computer memory isn't unlimited. There may come the time when I will have to

12. Delete a stock

I suppose it is obvious how some relatively simple tasks become major programs. The heart of the program is step 2. We had to have steps 0, 1 and 3. Now we have 12 steps. We could keep this up forever. To some extent, the longer you consider the project before you actually start programming, the better off you will be. Eventually, though, you will have to move on to the next step.

Step Seven

Rearrange the list in the correct order. Or write a "mainline section' that calls the list in the correct order. Adding the mainline section is more in keeping with the structured programming approach. It does offer some significant flexibility features and eventually you will want to consider using it. Using that technique, our list becomes something like this:

0. Initialization and goto mainline

1. Get the data on the stocks

a. Check for input errors

b. If too many, GOSUB delete a stock

c. GOSUB sort the stocks

2. Make the calculations

a. Check for high/low errors

3. Display the results

4. Save stock data on disk

a. GOSUB check for disk errors

5. Get stock data from disk

a. GOSUB check for disk errors

6. Print the output as an option

7. Check for input errors

8. Check projected highs and lows for errors

9. Check for disk errors

10. Sort the stocks

11. Delete a stock

12. Mainline

a. GOSUB get the data from disk

b. GOSUB get the data on the stocks

c. GOSUB make the calculations

d. GOSUB display the results

e. At user option GOSUB print the results

f. GOSUB save the data to disk

We recognize that many of these subroutines will be called by the other subroutines rather than from the mainline so we entered them as subroutines from the main points of the program.

I prefer to rearrange the list into a single sequence. I use the fully structured approach only when I attack a major project. It should be noted that even my approach will end up with major subroutine jumps as we expand and modify what the program does. My list looks like this:

0. Initialize

1. Get the data from the disk

a. Check for disk errors

2. Get the data on the new stocks

a. Check for input errors

b. If too many then delete a stock

c. When done sort the stocks

3. Make the calculations

a. Check for high/low errors

4. Display the results

5. At the user's option print the results

6. Save the data on disk

a. Check for disk errors

This structure will be the basic form of our program.

Step Eight

Take each section of the procedure and write the individual sub-steps for doing that section. This step is a long one. In some special cases you will be able to skip portions of this detailed description. If, for example, you have an acceptable sort routine, use it. There is no point in reinventing the wheel. Just be careful to modify all the variables correctly.

I use an "index card' sort that I find to be much faster than a Bubble sort (but then almost everything is) and almost as stingy with memory. The index card sort works best for a relatively few records that are almost in order. If you plan to sort a large number of records, you will want to use one of the other sorts.

A few examples should illustrate the idea here. As you get more proficient you will find yourself writing these steps in computer language instead of English. For your first couple of programs, though, everything will be easier if you write these steps in English. We will do the translation in a later step. See Figure 2.

After you have done this for every routine from your earlier list and all the ones that have occurred to you as you were writing this out, read through the logic. Do you have everything? Have you made any assumptions? While you are at it, double check your variable list to make sure it is complete. There will be only a few additions after this step.

Step Nine

Go to the computer. Give each step in your procedure a line number in increments of 100. Use larger steps for those sections that you think will be longer. Write a remark as the step instruction. See Figure 3.

Some of the lines will end up being pushed back. Some of the sections will require more room than we originally anticipated. Others will require less room. You will note from the example program that deleting a stock took much more room than I had originally anticipated. And I chose to delete the extra stock before I got the data on the new one. These remarks will form a major portion of our internal program documentation.

Step Ten

Translate your written instructions into the program steps. This is what the exercises in the programming manual were all about. Note how far you have come without getting involved with a programming language. This does not mean that the programming language is unimportant; you won't get beyond this point unless you know it well. The point is that there is a great deal of work to do before starting to write programming code. The initialization section in Microsoft Basic for the TRS-80 is shown in Figure 4.

If you have done the earlier steps correctly, this should be an almost line-for-line conversion. As a general note here, we recognize that we will be adding more lines and modifying them. Normally we number our lines by 10 to make inserting lines easier.

Step Ten

Test the program. Debug and rewrite as necessary. Add in user prompts where helpful and add error trapping routines.

This is the most important step. Try as we may to think things out in advance, there will always be problems that we failed to anticipate. Make sure your testing sends the program through each possible statement. Try some of these:

Did the absurd numbers cause the program to blow up? What does it do when you enter a negative price? Your program should be able to handle, or refuse to handle, all of these cases. Although I haven't done so in this program, it is normally a good idea to give the user the option of correcting the input data. Test and retest. Never assume that a computer program is correct until you have proven that it is correct.

This is the time for correcting display problems. I have noted that my computer memory can handle more stocks than I can display at once. Unless I put in some sort of paging routine, some of the information will go flying off the top of the screen before I can read it. That is not normally considered good programming practice.

Are there long periods when the user is starting at a blank screen? You don't want him to think that the computer has died a silent death. Sort routines frequently give the impression of a locked up computer sitting there using electricity.

There are a couple of ways of handling this problem. One is to put up a large disply for the user to read while the computer is working. If the user is busy, he will never notice that nothing apparent is happening. Another approach is to give periodic updates. Show the user what is happening. I have done this by showing the stocks as they are read.

Pretend that you are a complete idiot. Could you figure out how to use the program with the prompts shown? Does your program need a built-in page of instructions? Why not have the user read the instructions while the computer reads in its data?

Step Eleven

Optional clean up steps:

If you are like most programmers you will find yourself reworking programs until the day you stop using them. These optional steps are only a few of the possible changes. They are strictly optional. We now have a tested, working program and enough documentation to make the revisions feasible. The finished program appears in Listing 1.

Table 1.; Variables Used In This Program

NS$ (I) Name of the Stock I

CP(I) Closing Price

HP(I) High Projected

LP(I) Low Projected

GP(I) Growth Possible

I Index variable

NS Number of Stocks in memory

NY(I) Number of years of data on stock I

H(I, J) High price of stock I in year J

L(I, J) Low price of stock I in year J

LD(I) Last dividend

H5(I) 52-week high price

L5(I) 52-week low price

J General purpose counter

Y(I) Yield

YP(I) Yield Possible

G(I) Growth

D Dummy line fit variable

HS Sum of Highs

HX Sum of Highs times years

LS Sum of Lows

LX Sum of Lows times years

SX Sum of years

S2 Sum of years square

A1 Various Sort holding variables

A2

A3

A4

AD

AE

S$

K Sort counter

L Sort counter

DS Stock to Delete

N Number available for stocks

A$ Answer string

X$ Output format string

YR THis year

DA Date, used only for printout

Figure 2.

0. Initialize.

a. Clear the screen

b. Clear enough string space for the names

c. Zero all the variables

d. Print a title page so I will know what it is

e. Dimension the arrays

f. Set the error trap

2. b. Delete a Stock

1. Ask which stock to delete

2. Make sure it is a legal stock

a. If not then ask again

3. Reduce number of stocks by one

4. For all the stocks from there to top

5. Move stock data up by one

3. Make the calculations

a. Solve the line fit

b. Check for high/low errors

1. if low price is less than zero set it to zero

2. if high price is greater than the low set the high to the average and the low to the average minus one

c. Calculate yield and growth for each stock

6. Save data on disk

a. Open the disk file-- STOCKS/DAT

b. For each stock write to the disk file

(1) Name of Stock, last dividend, 52-week high, 52-week low. Number of years of high/low data

(2) For each year save high/low prices

c. Close the disk file

Figure 3.

001 Rem Stock market program

002 Rem Initialize

100 Rem Get the data from the disk

190 Rem Check for disk errors

200 Rem Get the data on the new stocks

400 Rem If too many then delete a stock

500 Rem Check for input errors

600 Rem When done sort the stocks

700 Rem Make the calculations

830 Rem Check for high/low errors

900 Rem Display the results

1000 Rem At the user's option print the results

1100 Rem Save the data on disk

1200 Rem Check for disk errors

Figure 4.

001 REM INITIALIZATION

002 CLS

003 PRINT "STOCKS PROGRAM'

004 CLEAR 1000

005 N=30

010 DIM NS$ (N), LD(N), H5(N), L5(N), HP(N) . . .

020 ON ERROR GOTO 1200

Table: Figure 1.

Table: Listing 1.