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:
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:
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.)
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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:
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.
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.
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
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.
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.
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:
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.
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:
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.
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.
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.
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.
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".
Today, you learned the basics of program design. The following are the key steps of design and development:
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.
© Copyright, Macmillan Computer Publishing. All rights reserved.