Teach Yourself COBOL in 21 days, Second Edition

Previous chapterNext chapterContents


- Day 7 -
Basics of Design

You now have enough tools to begin designing your own programs. A simple approach to design will make your efforts worthwhile. Today, you learn about the following topics:

Why Write a Program?

A program's primary goal is to take a repetitive task that would be mind-numbingly dull for a person to perform, and reduce it to a set of rote steps performed over and over by the machine.

A task is suitable for a program if the task involves doing one thing over and over. For example, going through the list of all books loaned out by a library, checking the return dates, determining which books are overdue, and printing an overdue notice to send to the offending cardholder is an ideal task for a computer program. This task is repetitive because it processes each book with the same steps:

1. Look up the loan date.

2. Check whether it is overdue.

3. If it is overdue, print a notice.

A task also is suitable for a program if it does only one thing once, but the program is run several times. For example, a program would be helpful to design and print signs for a retail store. Someone will design a sign and print it each time there is a sale. Unless you are keen on that individual artistic look, a sign-printing program will do this task repeatedly with a uniform quality of result.

If you are planning to move and need to put up a sign offering a garage sale, this is probably an unsuitable candidate for a program, unless you hold a garage sale every weekend and need to print signs that often.

In the early lessons of this book, several programs were presented that were not true candidates for programs. The "Hello world" program and the programs to display poems really didn't qualify as necessary programs, but they were coded simply to introduce you to the language.

The multiplication tables programs were good candidates. They executed an action repeatedly by multiplying two numbers, displaying the result, and moving on to the next number.

Some repetitive tasks make lousy programs because of the limitations of computers. Although you might make yourself a cup of coffee the same way each morning, it really wouldn't work as a program. Very few computers have a coffee maker as a standard output device.

If the job involves processing data, it is a good bet that a program will help expedite the task. (This is not always true. How about the repetitive task of going through all the people you know and selecting 50 people to invite to a party? Unless the computer knows who is on your A list, it will not be able to do this job even though it is repetitive and is data processing.)

Defining the Job

When you have decided that a job is suitable for a computer, you need to come up with a job description for the program. This doesn't have to be detailed, but it does have to be precise. Some job descriptions of computer programs that have been discussed or have appeared in previous lessons include the following:

Notice the difference between the last two. This is an example of precision without detail. The job descriptions are of two similar but slightly different programs.

Breaking Down the Task

When you have a job description, you can start breaking the job into smaller jobs. This is the point at which you need to have some knowledge of what the programming language is capable of doing.

Let's try breaking down the fourth job description in the previous list, because you're familiar with a version of this program. This will be a version of the multiplication tables that lets the user enter more than one table and display it. The job description is to display multiplication tables for any value from 1 to 99, displaying any number of entries from 1 to 99. Without worrying about the order of things, start by breaking the job description into component tasks, with a brief description of what the computer will have to do to execute this part of the task.

Original Job Description Computer Task
Display multiplication tables Display multiplication tables over and over.
For any value from 1 to 99 Ask the user for the table to display (1-99).
Display any number of entries from 1 to 99 1. Ask the user for the number of entries (1-99).

2. Display each entry from 1 through the number specified by the user.

The smaller tasks themselves might have to be broken down again. This process might have to be performed over and over until the tasks are small enough to be described in terms the computer can process.

Identifying the Processing Loops

Processing loops begin to stand out when the job is broken into smaller tasks. Recall from Day 5, "Using PERFORM, GO TO, and IF to Control Programs," that a processing loop is any task that is done over and over based on the detailed task descriptions.

You should be able to identify two loops now. The first displays a selected table repeatedly. The second displays an entry repeatedly until the number of entries specified by the user is reached.

After you have identified a loop, it is helpful to think of the loop as doing one thing over and over instead of doing all the things once. Table 7.1 illustrates the difference between the normal way of thinking about doing things repeatedly, and the computer-oriented way of thinking about processing loops.

Table 7.1. Normal thinking versus computer thinking.

Normal Thinking Computer Thinking
Display several tables. Display one table over and over, changing some value each time.
Display all the entries. Display one entry over and over, changing some value each time.

New Term: Pseudocode is a convenient way to write code without having to labor over the syntax of every line. It also allows you to leave gaps when you don't know the answer yet. Good pseudocode should be written in something that approximates the target language. There are no real rules for pseudocode, except that it should be helpful when designing a program.

Now that you have the program job, tasks, and processing loops identified, the next step is to start putting it together with pseudocode. The first task is identifying the whole program. What does it do? The program displays a bunch of tables. In computer "loopthink" it displays one table over and over, with something changed during each display. Listing 7.1 is a pseudocode statement for this.

Note that the first example of pseudocode violates two COBOL syntax rules. All words are not in uppercase, and the sentence does not end with a period. This is typical of pseudocode. It is like COBOL but does not have to honor all syntax rules.

TYPE: Listing 7.1. The first pseudocode.

THE-PROGRAM
    DISPLAY-ONE-TABLE over and over

"Over and over" is good enough for the programmer, but a computer program needs to be more precise so that the computer knows when to stop. This translates into an UNTIL condition. For the moment, I will leave things open-ended and change the pseudocode to that of Listing 7.2.

TYPE: Listing 7.2. The main action of the program in pseudocode.

THE-PROGRAM
    DISPLAY-ONE-TABLE
        UNTIL something???

The next step is to look at DISPLAY-ONE-TABLE. What actions do you have to do to display one table? Basically, there are only two actions, which are to get the table and display it. Listing 7.3 expands the pseudocode with these steps.

TYPE: Listing 7.3. Expanding the code.

THE-PROGRAM
    DISPLAY-ONE-TABLE
        UNTIL something???

DISPLAY-ONE-TABLE
    GET-WHICH-TABLE
    DISPLAY-THE-TABLE

GET-WHICH-TABLE resolves into simple COBOL commands to display a message and accept an answer. Now, what do you have to do to display the table? There are also two steps to this. First, get the number of entries. Next, display one entry until that number of entries is exhausted. Listing 7.4 includes the actions for GET-WHICH-TABLE and DISPLAY-THE-TABLE.

TYPE: Listing 7.4. Expanding on DISPLAY-THE-TABLE.

THE-PROGRAM
    DISPLAY-ONE-TABLE
        UNTIL something???

DISPLAY-ONE-TABLE
    GET-WHICH-TABLE
    DISPLAY-THE-TABLE

GET-WHICH-TABLE
    DISPLAY "Which table? (01-99)"
    ACCEPT THE-TABLE

DISPLAY-THE-TABLE
    GET-HOW-MANY-ENTRIES
    DISPLAY-ONE-ENTRY
        UNTIL all entries are displayed

Now you can apply your knowledge of COBOL to the problem. The entries to be displayed range from 1 to the number entered by the user. This seems a good place to use a VARYING option. Listing 7.5 expands on this in DISPLAY-THE-TABLE and also tackles the problem of getting the number of entries.

TYPE: Listing 7.5. The program takes shape.

THE-PROGRAM
    DISPLAY-ONE-TABLE
        UNTIL something???

DISPLAY-ONE-TABLE
    GET-WHICH-TABLE
    DISPLAY-THE-TABLE

GET-WHICH-TABLE
    DISPLAY "Which table? (01-99)"
    ACCEPT THE-TABLE

DISPLAY-THE-TABLE
    GET-HOW-MANY-ENTRIES
    DISPLAY-ONE-ENTRY
      VARYING THE-ENTRY FROM 1 BY 1
        UNTIL THE-ENTRY > HOW-MANY-ENTRIES

GET-HOW-MANY-ENTRIES
    DISPLAY "How many entries (01-99)?"
    ACCEPT HOW-MANY-ENTRIES

The last piece of the program is the task of displaying one entry. Listing 7.6 puts the final piece of the pseudocode together.

TYPE: Listing 7.6. The core of the program in pseudocode.

THE-PROGRAM
    DISPLAY-ONE-TABLE
        UNTIL something???

DISPLAY-ONE-TABLE
    GET-WHICH-TABLE
    DISPLAY-THE-TABLE

GET-WHICH-TABLE
    DISPLAY "Which table? (01-99)"
    ACCEPT THE-TABLE

DISPLAY-THE-TABLE
    GET-HOW-MANY-ENTRIES
    DISPLAY-ONE-ENTRY
      VARYING THE-ENTRY FROM 1 BY 1
        UNTIL THE-ENTRY > HOW-MANY-ENTRIES

GET-HOW-MANY-ENTRIES
    DISPLAY "How many entries (01-99)?"
    ACCEPT HOW-MANY-ENTRIES

DISPLAY-ONE-ENTRY
    COMPUTE THE-PRODUCT = THE-TABLE * THE-ENTRY
    DISPLAY THE-TABLE " * "
            THE-ENTRY " = "
            THE-PRODUCT

You don't want the program to turn into a runaway train, so you still have an UNTIL to resolve in THE-PROGRAM. This is where the user wants the process to stop. You could establish this by asking users whether they want to continue or to see another table.

When should the user be asked? After each table is displayed. Remember the two key parts of a processing loop are the top and the bottom. The question could be asked at the bottom of DISPLAY-ONE-TABLE. Listing 7.7 covers the sections that have been added in DISPLAY-ONE-TABLE and the new section GO-AGAIN. In GO-AGAIN, I made a design choice about the user's answer. I could have checked for y, Y, n, or N and provided an invalid entry message for anything else, but this felt like overkill for such a simple program. Instead, I chose to test only for y and convert it to Y. Then, anything other than Y is changed to N, forcing any entry other than Y or y to be treated as no.

TYPE: Listing 7.7. The pseudocode is almost complete.

THE-PROGRAM
    DISPLAY-ONE-TABLE
        UNTIL YES-NO = "N"

DISPLAY-ONE-TABLE
    GET-WHICH-TABLE
    DISPLAY-THE-TABLE
    GO-AGAIN

GET-WHICH-TABLE
    DISPLAY "Which table? (01-99)"
    ACCEPT THE-TABLE

DISPLAY-THE-TABLE
    GET-HOW-MANY-ENTRIES
    DISPLAY-ONE-ENTRY
      VARYING THE-ENTRY FROM 1 BY 1
        UNTIL THE-ENTRY > HOW-MANY-ENTRIES

GO-AGAIN
    DISPLAY "Go Again (Y/N)?"
    ACCEPT YES-NO
    IF YES-NO = "y"
        MOVE "Y" TO YES-NO
    IF YES-NO NOT = "Y"
        MOVE "N" TO YES-NO

GET-HOW-MANY-ENTRIES
    DISPLAY "How many entries (01-99)?"
    ACCEPT HOW-MANY-ENTRIES

DISPLAY-ONE-ENTRY
    COMPUTE THE-PRODUCT = THE-TABLE * THE-ENTRY
    DISPLAY THE-TABLE " * "
            THE-ENTRY " = "
            THE-PRODUCT

Now comes the tidying up. First, look at the loops. There is a potential problem in the control of the first loop in THE-PROGRAM. Recall the following loop steps:

1. Initialize for the first pass through the loop.

2. Do the loop.

3. Modify the variable that controls the loop as the last step of the loop, or after each pass through the loop.

There is no loop step 1 for DISPLAY-ONE-TABLE. This can be fixed by forcing YES-NO to an initial value of "Y". This ensures that DISPLAY-ONE-TABLE is executed when the loop is entered for the first time.

THE-PROGRAM
    MOVE "Y" TO YES-NO
    DISPLAY-ONE-TABLE
        UNTIL YES-NO = "N"

The second area to clean up has been dealt with once before--the problem of displaying 15 lines at a time. You can use the top of the DISPLAY-ONE-ENTRY loop for a Press ENTER message, and use the bottom of the loop to add 1 to SCREEN-LINES.

Because this program will display more than one table, it is necessary to start SCREEN-LINES at zero before each table is displayed. Listing 7.8 is the final version of the pseudocode.

TYPE: Listing 7.8. The final pseudocode.

THE-PROGRAM
    MOVE "Y" TO YES-NO
    DISPLAY-ONE-TABLE
        UNTIL YES-NO = "N"

DISPLAY-ONE-TABLE
    GET-WHICH-TABLE
    DISPLAY-THE-TABLE
    GO-AGAIN

GET-WHICH-TABLE
    DISPLAY "Which table? (01-99)"
    ACCEPT THE-TABLE

DISPLAY-THE-TABLE
    GET-HOW-MANY-ENTRIES
    MOVE 0 TO SCREEN-LINES
    DISPLAY-ONE-ENTRY
      VARYING THE-ENTRY FROM 1 BY 1
        UNTIL THE-ENTRY > HOW-MANY-ENTRIES

GO-AGAIN
    DISPLAY "Go Again (Y/N)?"
    ACCEPT YES-NO
    IF YES-NO = "y"
        MOVE "Y" TO YES-NO
    IF YES-NO NOT = "Y"
        MOVE "N" TO YES-NO

GET-HOW-MANY-ENTRIES
    DISPLAY "How many entries (01-99)?"
    ACCEPT HOW-MANY-ENTRIES

DISPLAY-ONE-ENTRY
    IF SCREEN-LINES = 15
        PRESS-ENTER
    COMPUTE THE-PRODUCT = THE-TABLE * THE-ENTRY
    DISPLAY THE-TABLE " * "
            THE-ENTRY " = "
            THE-PRODUCT
    ADD 1 TO SCREEN-LINES

PRESS-ENTER
    DISPLAY "Press ENTER to continue"
    ACCEPT A-DUMMY

What's left? I deliberately chose a pseudocode that translated readily into COBOL code. Remember that pseudocode is supposed to help with the design. In fact, the pseudocode is now very close to a COBOL program.

Basically, you need to clean up the punctuation by adding some periods, add some PERFORM statements, create variables in WORKING-STORAGE, compile, and test. The result is shown in Listing 7.9. The pseudocode is almost identical to the PROCEDURE DIVISION.

TYPE: Listing 7.9. The final program.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID. MULT07.
000300*--------------------------------------------------
000400* This program asks the user for a number for a
000500* multiplication table, and a table size
000600* and then displays a table for that number
000700* times the values 1 through HOW-MANY.
000800*
000900* The display is paused after each 15 lines.
001000*--------------------------------------------------
001100 ENVIRONMENT DIVISION.
001200 DATA DIVISION.
001300 WORKING-STORAGE SECTION.
001400
001500 01  THE-TABLE          PIC 99.
001600 01  THE-ENTRY          PIC 999.
001700 01  THE-PRODUCT        PIC 9999.
001800 01  HOW-MANY-ENTRIES   PIC 99.
001900 01  SCREEN-LINES       PIC 99.
002000
002100 01  A-DUMMY            PIC X.
002200
002300 01  YES-NO             PIC X.
002400
002500 PROCEDURE DIVISION.
002600
002700 PROGRAM-BEGIN.
002800     MOVE "Y" TO YES-NO.
002900     PERFORM DISPLAY-ONE-TABLE
003000         UNTIL YES-NO = "N".
003100
003200 PROGRAM-DONE.
003300     STOP RUN.
003400
003500 DISPLAY-ONE-TABLE.
003600     PERFORM GET-WHICH-TABLE.
003700     PERFORM DISPLAY-THE-TABLE.
003800     PERFORM GO-AGAIN.
003900
004000 GET-WHICH-TABLE.
004100     DISPLAY
004200      "Which multiplication table(01-99)?".
004300     ACCEPT THE-TABLE.
004400
004500 DISPLAY-THE-TABLE.
004600     PERFORM GET-HOW-MANY-ENTRIES.
004700
004800     MOVE 0 TO SCREEN-LINES.
004900
005000     PERFORM DISPLAY-ONE-ENTRY
005100         VARYING THE-ENTRY
005200           FROM 1 BY 1
005300           UNTIL THE-ENTRY > HOW-MANY-ENTRIES.
005400
005500 GO-AGAIN.
005600     DISPLAY "Go Again (Y/N)?".
005700     ACCEPT YES-NO.
005800     IF YES-NO = "y"
005900         MOVE "Y" TO YES-NO.
006000     IF YES-NO NOT = "Y"
006100         MOVE "N" TO YES-NO.
006200
006300 GET-HOW-MANY-ENTRIES.
006400     DISPLAY
006500      "How many entries would you like (01-99)?".
006600     ACCEPT HOW-MANY-ENTRIES.
006700
006800 DISPLAY-ONE-ENTRY.
006900
007000     IF SCREEN-LINES = 15
007100         PERFORM PRESS-ENTER.
007200     COMPUTE THE-PRODUCT = THE-TABLE * THE-ENTRY.
007300     DISPLAY
007400         THE-TABLE " * " THE-ENTRY " = " THE-PRODUCT.
007500
007600     ADD 1 TO SCREEN-LINES.
007700
007800 PRESS-ENTER.
007900     DISPLAY "Press ENTER to continue . . .".
008000     ACCEPT A-DUMMY.
008100     MOVE 0 TO SCREEN-LINES.
008200

Identifying the Main Processing Loop

Although a processing loop is supposed to be a section of the program that is performed over and over, it does not have to be. The main processing loop, the main action that the program does, is not always performed repeatedly. You saw in earlier versions of the multiplication tables program in Day 5 that the main processing loop need not be performed over and over. Yet the program is still a valid computer program.

If the main processing loop doesn't have to be a true loop, how do you identify it? One way is to pretend that whatever the program is going to do, it will be doing it over and over. If the original job description had been to display only one multiplication table, you could add "do it over and over" while you are designing it.

When you have used this trick in thinking to identify the main activity (and thereby the main processing loop) of the program, the design can be completed, and the program can be converted easily to a single loop version.

An interesting feature of processing loops is that they work for one occurrence in the loop just as well as they do for all occurrences. Listing 7.10, mult08.cbl, is identical to mult07.cbl, but certain lines have been commented out. Commenting out code is a common practice. Instead of deleting the whole line, simply place an asterisk in column 7. This causes the line to be treated as a comment, and it is therefore ignored by the compiler. It has the same effect as deleting the line, but it leaves the code there. This practice is used when something is being changed and you need to refer to the original.

TYPE: Listing 7.10. Converting mult07.cbl to perform a single loop.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID. MULT08.
000300*--------------------------------------------------
000400* This program asks the user for a number for a
000500* multiplication table, and a table size
000600* and then displays a table for that number
000700* times the values 1 through HOW-MANY.
000800*
000900* The display is paused after each 15 lines.
001000*--------------------------------------------------
001100 ENVIRONMENT DIVISION.
001200 DATA DIVISION.
001300 WORKING-STORAGE SECTION.
001400
001500 01  THE-TABLE          PIC 99.
001600 01  THE-ENTRY          PIC 999.
001700 01  THE-PRODUCT        PIC 9999.
001800 01  HOW-MANY-ENTRIES   PIC 99.
001900 01  SCREEN-LINES       PIC 99.
002000
002100 01  A-DUMMY            PIC X.
002200
002300*01  YES-NO             PIC X VALUE "Y".
002400
002500 PROCEDURE DIVISION.
002600
002700 PROGRAM-BEGIN.
002800*    MOVE "Y" TO YES-NO.
002900     PERFORM DISPLAY-ONE-TABLE.
003000*        UNTIL YES-NO = "N".
003100
003200 PROGRAM-DONE.
003300     STOP RUN.
003400
003500 DISPLAY-ONE-TABLE.
003600     PERFORM GET-WHICH-TABLE.
003700     PERFORM DISPLAY-THE-TABLE.
003800*    PERFORM GO-AGAIN.
003900
004000 GET-WHICH-TABLE.
004100     DISPLAY
004200      "Which multiplication table(01-99)?".
004300     ACCEPT THE-TABLE.
004400
004500 DISPLAY-THE-TABLE.
004600     PERFORM GET-HOW-MANY-ENTRIES.
004700
004800     MOVE 0 TO SCREEN-LINES.
004900
005000     PERFORM DISPLAY-ONE-ENTRY
005100         VARYING THE-ENTRY
005200           FROM 1 BY 1
005300           UNTIL THE-ENTRY > HOW-MANY-ENTRIES.
005400
005500*GO-AGAIN.
005600*    DISPLAY "Go Again (Y/N)?".
005700*    ACCEPT YES-NO.
005800*    IF YES-NO = "y"
005900*        MOVE "Y" TO YES-NO.
006000*    IF YES-NO NOT = "Y"
006100*        MOVE "N" TO YES-NO.
006200
006300 GET-HOW-MANY-ENTRIES.
006400     DISPLAY
006500      "How many entries would you like (01-99)?".
006600     ACCEPT HOW-MANY-ENTRIES.
006700
006800 DISPLAY-ONE-ENTRY.
006900
007000     IF SCREEN-LINES = 15
007100         PERFORM PRESS-ENTER.
007200     COMPUTE THE-PRODUCT = THE-TABLE * THE-ENTRY.
007300     DISPLAY
007400         THE-TABLE " * " THE-ENTRY " = " THE-PRODUCT.
007500
007600     ADD 1 TO SCREEN-LINES.
007700
007800 PRESS-ENTER.
007900     DISPLAY "Press ENTER to continue . . .".
008000     ACCEPT A-DUMMY.
008100     MOVE 0 TO SCREEN-LINES.
008200

ANALYSIS: Listing 7.10 has been modified to remove all the code pertaining to asking the user to continue and to going again if the user answers yes.

Lines 002300, 002800, 003000, 003800, and 005500 through 006100 have been commented out. The resulting program is a slightly different version of the original multiplication tables program that displays only one table. The mult07.cbl program has been stripped back to a single pass by a few well-placed asterisks, and you have completed an efficient design.

Processing loops are not always obvious. The original versions of the multiplication program, mult01.cbl through mult06.cbl, in Day 5, made only one pass through the main processing loop.

If you are designing a program that performs only one pass of some process, you can imitate the process shown in Listing 7.10, mult08.cbl. Pretend that you are making multiple passes, complete the design, and then cut back to one pass through the loop. This is just a trick to help you think of the main action of a program as a processing loop, even if it is executed only once.

A Summary of Design Steps

Before you tackle another design problem, a review of the design steps that you have learned is in order. The following list includes both design and development:

1. Create a job description. This is a precise, but not necessarily detailed, description of what the program will do.

2. Break the job description into tasks. This step adds detail to the precision. The tasks might need to be further broken down until the task descriptions approximate what a computer can do.

3. Identify the processing loops.

4. Identify the main processing loop if it has not become apparent during step 3.

5. Write the program in pseudocode.

6. Convert the pseudocode into actual code.

7. Edit and compile the program.

8. Test the program.

9. Fix any bugs by rewriting the areas of the program that aren't working correctly.

10. Repeat steps 8 and 9 until the program works correctly.

It is not unusual for steps 1 through 5 to take longer than steps 6 through 10, especially if you do a thorough job of design.

A Compound Interest Program

In this example you work through the design of a completely new program that calculates the value of an initial investment after compound interest has accumulated over a period of time.

To calculate compound interest, you need to know the principal, the interest rate over a given period, and the number of periods over which the interest will be compounded. Starting with the steps again, you first create a job description for the program, which is as follows: Calculate the values of investments based on user input of principals, interest rates, and number of periods. This can be broken into the following tasks without regard to their order:

1. Calculate the value of an investment over and over.

2. Display the value.

3. Get user input of the principal.

4. Get user input of the interest.

5. Get user input of the number of periods.

The easiest way to calculate compound interest is to calculate the new value of the investment over one period. Then make the new value the investment, and calculate another new value on one period using the new investment value. (See Table 7.2.) This is repeated until all periods are exhausted. Assuming an interest rate of 10 percent over four periods, the value of the investment is calculated in the four steps shown in Table 7.2.

Table 7.2. Calculating compound interest.

Period 1 2 3 4
Principal 1000.00 1100.00 1210.00 1331.00
Rate (10%) x.10 x.10 x.10 x.10
Interest =100.00 =110.00 =121.00 =133.10
Plus the original principal +1000.00 +1100.00 +1210.00 +1331.00
Equals =1100.00 =1210.00 =1331.00 =1464.10

At the end of each step, the resulting value is moved to the top of the next period and the steps are repeated.

There are more efficient formulas for compound interest, but this one illustrates that even when you don't know the "most proper" formula, you can use a computer to tough it out for you. This helps to add a sixth task to the list.

6. Calculate the new value of an investment for one period over and over.

From these tasks, it is possible to recognize two processing loops at tasks 1 and 6. The loop at task 1 is the main loop for the program.

From your existing experience with pseudocode, put together a quick outline of the program. In Listing 7.11, I've used more formal pseudocode, which approximates COBOL even more closely. Now that you have some experience with DISPLAY and ACCEPT, it's not necessary to spell all this out in pseudocode. Remember that pseudocode is supposed to help during a design, not be extra work to do. The pseudocode is clear enough to indicate that you will display some sort of message and get some user input.

TYPE: Listing 7.11. Pseudocode for compound interest.

THE-PROGRAM
    MOVE "Y" TO YES-NO
    PERFORM GET-AND-DISPLAY-RESULT
        UNTIL YES-NO = "N".

GET-AND-DISPLAY-RESULT.
    PERFORM GET-THE-PRINCIPAL
    PERFORM GET-THE-INTEREST
    PERFORM GET-THE-PERIODS.
    PERFORM CALCULATE-THE-RESULT.
    PERFORM DISPLAY-THE-RESULT.
    PERFORM GO-AGAIN.

GET-THE-PRINCIPAL.
    ( between 0.01 and 999999.99 )

GET-THE-INTEREST.
    ( between 00.1 and 99.9%)

GET-THE-PERIODS.
    ( between 001 and 999 )

CALCULATE-THE-RESULT.
    PERFORM CALCULATE-ONE-PERIOD
        VARYING THE-PERIOD FROM 1 BY 1
         UNTIL THE-PERIOD > NO-OF-PERIODS.

CALCULATE-ONE-PERIOD.
    COMPUTE EARNED-INTEREST ROUNDED =
        THE-PRINCIPAL * INTEREST-AS-DECIMAL.
    COMPUTE THE-NEW-VALUE =
            THE-PRINCIPAL + EARNED-INTEREST.
    MOVE THE-NEW-VALUE TO THE-PRINCIPAL.

GO-AGAIN
    ( YES OR NO)

DISPLAY-THE-RESULT
    (VALUE = THE-PRINCIPAL)

Listing 7.12 is the code that comes from the pseudocode. The paragraphs to get the principal, the interest, and the number of periods have been designed to validate the input data, display an invalid entry message if necessary, and go to the top of the paragraph if an entry error has occurred. Study this listing, code it, compile it, and try it out.


NOTE: Remember that the ACCEPT data-name statements have to be adjusted to your computer to ACCEPT data-name CONVERT or just ACCEPT data-name WITH CONVERSION.

TYPE: Listing 7.12. Compound interest.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID. CMPINT01.
000300*------------------------------------------------
000400* Calculates compound interest
000500*------------------------------------------------
000600 ENVIRONMENT DIVISION.
000700 DATA DIVISION.
000800 WORKING-STORAGE SECTION.
000900
001000 01  YES-NO                           PIC X.
001100 01  THE-INTEREST                     PIC 99V9.
001200 01  INTEREST-AS-DECIMAL              PIC V999.
001300 01  THE-PRINCIPAL                    PIC 9(9)V99.
001400 01  THE-NEW-VALUE                    PIC 9(9)V99.
001500 01  EARNED-INTEREST                  PIC 9(9)V99.
001600 01  THE-PERIOD                       PIC 9999.
001700 01  NO-OF-PERIODS                    PIC 999.
001800
001900 01  ENTRY-FIELD                      PIC Z(9).ZZ.
002000 01  DISPLAY-VALUE                    PIC ZZZ,ZZZ,ZZ9.99.
002100
002200 PROCEDURE DIVISION.
002300 PROGRAM-BEGIN.
002400
002500     MOVE "Y" TO YES-NO.
002600     PERFORM GET-AND-DISPLAY-RESULT
002700         UNTIL YES-NO = "N".
002800
002900 PROGRAM-DONE.
003000     STOP RUN.
003100
003200 GET-AND-DISPLAY-RESULT.
003300     PERFORM GET-THE-PRINCIPAL.
003400     PERFORM GET-THE-INTEREST.
003500     PERFORM GET-THE-PERIODS.
003600     PERFORM CALCULATE-THE-RESULT.
003700     PERFORM DISPLAY-THE-RESULT.
003800     PERFORM GO-AGAIN.
003900
004000 GET-THE-PRINCIPAL.
004100     DISPLAY "Principal (.01 TO 999999.99)?".
004200     ACCEPT ENTRY-FIELD
004300     MOVE ENTRY-FIELD TO THE-PRINCIPAL.
004400     IF THE-PRINCIPAL < .01 OR
004500        THE-PRINCIPAL > 999999.99
004600         DISPLAY "INVALID ENTRY"
004700         GO TO GET-THE-PRINCIPAL.
004800
004900 GET-THE-INTEREST.
005000     DISPLAY "Interest (.1% TO 99.9%)?".
005100     ACCEPT ENTRY-FIELD.
005200     MOVE ENTRY-FIELD TO THE-INTEREST.
005300     IF THE-INTEREST < .1 OR
005400        THE-INTEREST > 99.9
005500         DISPLAY "INVALID ENTRY"
005600         GO TO GET-THE-INTEREST
005700     ELSE
005800         COMPUTE INTEREST-AS-DECIMAL =
005900                 THE-INTEREST / 100.
006000
006100 GET-THE-PERIODS.
006200     DISPLAY "Number of periods (1 TO 999)?".
006300     ACCEPT ENTRY-FIELD.
006400     MOVE ENTRY-FIELD TO NO-OF-PERIODS.
006500     IF NO-OF-PERIODS < 1 OR
006600        NO-OF-PERIODS > 999
006700         DISPLAY "INVALID ENTRY"
006800         GO TO GET-THE-PERIODS.
006900
007000 CALCULATE-THE-RESULT.
007100     PERFORM CALCULATE-ONE-PERIOD
007200         VARYING THE-PERIOD FROM 1 BY 1
007300          UNTIL THE-PERIOD > NO-OF-PERIODS.
007400
007500 CALCULATE-ONE-PERIOD.
007600     COMPUTE EARNED-INTEREST ROUNDED =
007700         THE-PRINCIPAL * INTEREST-AS-DECIMAL.
007800     COMPUTE THE-NEW-VALUE =
007900             THE-PRINCIPAL + EARNED-INTEREST.
008000     MOVE THE-NEW-VALUE TO THE-PRINCIPAL.
008100
008200 GO-AGAIN.
008300     DISPLAY "GO AGAIN?".
008400     ACCEPT YES-NO.
008500     IF YES-NO = "y"
008600         MOVE "Y" TO YES-NO.
008700     IF YES-NO NOT = "Y"
008800         MOVE "N" TO YES-NO.
008900
009000 DISPLAY-THE-RESULT.
009100     MOVE THE-NEW-VALUE TO DISPLAY-VALUE.
009200     DISPLAY "RESULTING VALUE IS " DISPLAY-VALUE.
009300

Here is the output of cmpint01.cbl for $1,000.00 invested at 1.1 percent per month, and compounded for 48 months:

OUTPUT:

Principal (.01 TO 999999.99)?
1000
Interest (.1% TO 99.9%)?
1.1
Number of periods (1 TO 999)?
48
RESULTING VALUE IS       1,690.65
GO AGAIN?

Before anyone complains about using GO TO in Listing 7.12, I have included Listing 7.13, cmpint02.cbl, which avoids the GO TO logic by using an ENTRY-OK flag. Study the differences in cmpint01.cbl and cmpint02.cbl. The second listing illustrates that you can avoid using a GO TO even when a GO TO seems like a logical choice.

TYPE: Listing 7.13. Avoiding GO TO.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID. CMPINT02.
000300*------------------------------------------------
000400* Calculates compound interest
000500*------------------------------------------------
000600 ENVIRONMENT DIVISION.
000700 DATA DIVISION.
000800 WORKING-STORAGE SECTION.
000900
001000 01  YES-NO                           PIC X.
001100 01  ENTRY-OK                         PIC X.
001200 01  THE-INTEREST                     PIC 99V9.
001300 01  INTEREST-AS-DECIMAL              PIC V999.
001400 01  THE-PRINCIPAL                    PIC 9(9)V99.
001500 01  THE-NEW-VALUE                    PIC 9(9)V99.
001600 01  EARNED-INTEREST                  PIC 9(9)V99.
001700 01  THE-PERIOD                       PIC 9999.
001800 01  NO-OF-PERIODS                    PIC 999.
001900
002000 01  ENTRY-FIELD                      PIC Z(9).ZZ.
002100 01  DISPLAY-VALUE                    PIC ZZZ,ZZZ,ZZ9.99.
002200
002300 PROCEDURE DIVISION.
002400 PROGRAM-BEGIN.
002500
002600     MOVE "Y" TO YES-NO.
002700     PERFORM GET-AND-DISPLAY-RESULT
002800         UNTIL YES-NO = "N".
002900
003000 PROGRAM-DONE.
003100     STOP RUN.
003200
003300 GET-AND-DISPLAY-RESULT.
003400     PERFORM GET-THE-PRINCIPAL.
003500     PERFORM GET-THE-INTEREST.
003600     PERFORM GET-THE-PERIODS.
003700     PERFORM CALCULATE-THE-RESULT.
003800     PERFORM DISPLAY-THE-RESULT.
003900     PERFORM GO-AGAIN.
004000
004100 GET-THE-PRINCIPAL.
004200     MOVE "N" TO ENTRY-OK.
004300     PERFORM ENTER-THE-PRINCIPAL
004400         UNTIL ENTRY-OK = "Y".
004500
004600 ENTER-THE-PRINCIPAL.
004700     DISPLAY "Principal (.01 TO 999999.99)?".
004800     ACCEPT ENTRY-FIELD.
004900     MOVE ENTRY-FIELD TO THE-PRINCIPAL.
005000     IF THE-PRINCIPAL < .01 OR
005100        THE-PRINCIPAL > 999999.99
005200         DISPLAY "INVALID ENTRY"
005300     ELSE
005400         MOVE "Y" TO ENTRY-OK.
005500
005600 GET-THE-INTEREST.
005700     MOVE "N" TO ENTRY-OK.
005800     PERFORM ENTER-THE-INTEREST
005900         UNTIL ENTRY-OK = "Y".
006000
006100 ENTER-THE-INTEREST.
006200     DISPLAY "Interest (.1% TO 99.9%)?".
006300     ACCEPT ENTRY-FIELD.
006400     MOVE ENTRY-FIELD TO THE-INTEREST.
006500     IF THE-INTEREST < .1 OR
006600        THE-INTEREST > 99.9
006700         DISPLAY "INVALID ENTRY"
006800     ELSE
006900         MOVE "Y" TO ENTRY-OK
007000         COMPUTE INTEREST-AS-DECIMAL =
007100                 THE-INTEREST / 100.
007200
007300 GET-THE-PERIODS.
007400     MOVE "N" TO ENTRY-OK.
007500     PERFORM ENTER-THE-PERIODS
007600         UNTIL ENTRY-OK = "Y".
007700
007800 ENTER-THE-PERIODS.
007900     DISPLAY "Number of periods (1 TO 999)?".
008000     ACCEPT ENTRY-FIELD.
008100     MOVE ENTRY-FIELD TO NO-OF-PERIODS.
008200     IF NO-OF-PERIODS < 1 OR
008300        NO-OF-PERIODS > 999
008400         DISPLAY "INVALID ENTRY"
008500     ELSE
008600         MOVE "Y" TO ENTRY-OK.
008700
008800 CALCULATE-THE-RESULT.
008900     PERFORM CALCULATE-ONE-PERIOD
009000         VARYING THE-PERIOD FROM 1 BY 1
009100          UNTIL THE-PERIOD > NO-OF-PERIODS.
009200
009300 CALCULATE-ONE-PERIOD.
009400     COMPUTE EARNED-INTEREST ROUNDED =
009500         THE-PRINCIPAL * INTEREST-AS-DECIMAL.
009600     COMPUTE THE-NEW-VALUE =
009700             THE-PRINCIPAL + EARNED-INTEREST.
009800     MOVE THE-NEW-VALUE TO THE-PRINCIPAL.
009900
010000 GO-AGAIN.
010100     DISPLAY "GO AGAIN?".
010200     ACCEPT YES-NO.
010300     IF YES-NO = "y"
010400         MOVE "Y" TO YES-NO.
010500     IF YES-NO NOT = "Y"
010600         MOVE "N" TO YES-NO.
010700
010800 DISPLAY-THE-RESULT.
010900     MOVE THE-NEW-VALUE TO DISPLAY-VALUE.
011000     DISPLAY "RESULTING VALUE IS " DISPLAY-VALUE. 
011100

ANALYSIS: In Listing 7.13, the data entry is treated as a processing loop that is performed until the data that is entered is correct.

For example, at line 004200, the ENTRY-OK flag is set to "N" (not okay) before the loop ENTER-THE-PRINCIPAL is performed. Then ENTER-THE-PRINCIPAL is performed UNTIL ENTRY-OK = "Y" (the data entry is okay). This forces ENTER-THE-PRINCIPAL to be performed at least once. Because the code ENTER-THE-PRINCIPAL is used, the user is prompted for an entry, the entry is accepted, and the entry is checked.

If the entry is okay, the ENTRY-OK flag is set to "Y". This ends the PERFORM UNTIL at lines 004300 and 004400.

If the entry is not okay, an INVALID ENTRY message is displayed, but the ENTRY-OK flag is not changed. On exit, the PERFORM UNTIL at lines 004300 and 004400 finds that the ENTRY-OK flag is not yet "Y" and ENTER-THE-PRINCIPAL is performed one more time. This continues until the user gets it right and the ENTRY-OK flag is set to "Y".

Summary

Today, you learned the basics of program design. The following are the key steps of design and development:

1. Create a job description for the program.

2. Break the job description into tasks until the tasks approximate what the computer will do.

3. Identify the processing loops.

4. Identify the main processing loop if it has not become apparent during step 3.

5. Write the program in pseudocode.

6. Convert the pseudocode into actual code.

7. Edit and compile the program.

8. Test the program.

9. Fix any bugs by rewriting the areas of the program that aren't working correctly.

10. Repeat steps 8 and 9 until the program works correctly.

Pseudocode is any convenient English-like method of describing what a program does. Pseudocode helps with the design of a program and easily converts into the code for the program.

You can avoid GO TO using the PERFORM verb and its variations.

Q&A

Q Do I have to do all of the design steps before I start coding?

A When you are learning, it is good practice to do all steps. This helps you clarify what the program eventually is supposed to do. Even so, you will notice that in the second example, I left out some of the steps of the pseudocode.

You will reach a point when you can "think" in sections of code. For example, you probably already have a rough idea of what the code would look like to ask the user whether to go again. You will be able to shortcut some of the design steps because you will actually be doing them in your head without having to write them all out on paper.

Workshop

Quiz

1. What is the first step in designing the program for the following job description?

Ask the user for sales amounts and sales tax rates, and use these values to calculate the sales tax on the amount.

2. What are the six design steps?

Exercises

1. Perform all the design steps up to and including the coding of the job described in Quiz question 1. The steps for this are given in the back of the book. If you hit a snag on any step, go ahead and look at the answer for that step. Designing is a skill that comes only with a vast amount of experience. Occasionally, I have seen competent programmers freeze or produce a bad design when they have been asked to design certain programs, and I still have plenty to learn about design. There is no shame in getting help for this exercise.

Hint: You will be able to use quite a bit of the logic from cmpint02.cbl (shown in Listing 7.13) as the basic model for the program.

2. Complete the following last four steps of the development on the design you did in Exercise 1.
7. Edit and compile the program.

8. Test the program.

9. Fix any bugs by rewriting the areas of the program that aren't working correctly.

10. Repeat steps 8 and 9 until the program works correctly.

3. Modify the program that you created in Exercise 2 so that it asks for the sales tax percentage only once as the first step of the program, and then asks for sales amounts repeatedly, calculating the sales tax for each entry.

Hint: Use the answer to Exercise 2 from Appendix A, "Answers." You should be able to make this change by moving only one line of code up to become the first line of code in PROGRAM-BEGIN.


Previous chapterNext chapterContents


© Copyright, Macmillan Computer Publishing. All rights reserved.