Back to DFS's Pascal Page


Program Development: Top-Down

Developing a non-trivial program can be a major undertaking. To make the work as painless as possible, it is best to have a method of attack. There are two techniques which are commonly used: bottom-up and top-down.

Both require pre-planning. This is best done by creating pseudocode.

Typically, when a problem is posed, you will have an idea of what the output should be like. From there you determine what sort of information is required to develop the output. Then you can fill in the middle of your algorithm -- how to process the input so you can produce the output.

Alternatively, you can brainstorm the kinds of tasks that will be required, making a list as they come to mind. These can then be organized into a coherent algorithm, thus producing the requisite pseudocode.

Once the pseudocode has been written, it will be much easier to write the individual procedures/functions to perform the required tasks.

For the purposes of this discussion, let us consider the overworked area-of-a-triangle program. Here is simple pseudocode:

  1. Introduction
  2. Get values for the base and height
  3. Calculate the area
  4. Print results

We will be developing the program discussed in Procedures II. There you will find a complete presentation of the parameters used.

Top-Down

Creating the Skeleton

To begin, we will write a simple program which does absolutely nothing but call a set of procedure stubs in sequence. These stubs currently perform no useful purpose other than to serve as placeholders for the individual steps in the algorithm. Each of the procedures matches up with one of the steps in the pseudocode.

Although this initial program generates no output, it should be noted that a considerable amount of preplanning has already occurred, parameters having been selected for three of the procedures.

program TriangleAreaProcedures(input, output);

procedure Introduction;
 begin
 end;  {procedure Introduction}

procedure InputtingData(var b, h: integer);
 begin
 end; {procedure InputtingData}

procedure Calculation(b, h: integer; var A: real);
 begin
 end; {procedure Calculation}

procedure PrintingResults(b, h: integer; A: real);
 begin
 end; {procedure PrintingResults}

var
  base: integer;
  height: integer;
  Area: real;

begin {main line}
 Introduction;
 InputtingData(base, height);
 Calculation(base, height, Area);
 PrintingResults(base, height, Area)
end.

Putting Flesh on the Bones

We can now start writing the code to make the procedures actually do their tasks. Since Introduction is not directly involved in the inputting, processing and outputting of the data, it can be written at any time. If you are new to programming, you may want to fill it in right away so that you have a constant reminder about what the final program is supposed to do.

There are also deadline considerations. If you get the main algorithm working with time to spare, you can spend the remaining time fancying up the introduction and user interface; on the other hand, if you spend too much time perfecting the introduction, you could run out of time before you finish the main task.

We will look briefly at two techniques for proceeding with the programming solution.

  1. Hardsetting values to test parameter passing

    For beginning programmers, it may be wise to ascertain that we have indeed chosen the right kind of parameters for the procedures. The easiest way do this is to hardset the parameters inside the particular procedure where global variables are to receive their values. (If value parameters are to be tested, the global variables should be hardset in the main line before the procedure is called.) The following is an example using InputtingData(). If the parameters are not specified as variable, the global variables will remain unaffected.

    procedure InputtingData(var b, h: integer);
     begin
      b := 7;
      h := 5
     end; {procedure InputtingData}
    

    There are two easy ways to make sure that the values have made it out of the procedure.

    These methods have conflicting disadvantages: the former requires that you alter the program by adding lines which will have to be eliminated later; the latter requires that you set up watches which may only be needed once. If you do not have a debugger (which is sometimes the case with other programming languages), writing values to the screen or a disk file may be the most efficient way, and sometimes the only way, to develop a program.

  2. First Things First

    A second technique, for (slightly) more advanced programmers, is to continue the development process by initially filling in the procedure(s) which handle input, then the ones which process the data, and finally those which output the results. This order of doing things is very intuitive, because it typically follows the design of the algorithm as set out in the pseudocode. Assuming that the Introduction() procedure has already been written and tested, let us look at InputtingData() and the main line.

    procedure InputtingData(var b, h: integer);
     begin
      write('What is the length of the triangle''s base? ');
      readln(b);
      write('What is the triangle''s height? ');
      readln(h)
     end; {procedure InputtingData}
    .
    .
    .
    begin {main line}
     Introduction;
     InputtingData(base, height);
     writeln('base = ', base);
     writeln('height = ', height);
     Calculation(base, height, Area);
     PrintingResults(base, height, Area)
    end.
    

    The printing of the values of the global variables base and height allows us to see the results of the procedure.

    While each of the succeeding procedures can be written one at a time and the expanded program tested, this may not be the most efficient method. It is often better to turn a procedure back into a stub once it has been perfected, and to hardset the global values which were affected just after its call in the main line. This can spare you from a lot of repetitive typing while developing the rest of the program. For example, the following main line could be used to test the Calculation() procedure.

    begin {main line}
     Introduction;
     InputtingData(base, height);
     base := 7;
     height := 5;
     Calculation(base, height, Area);
     writeln('base = ', base);
     writeln('height = ', height);
     writeln('Area = ', Area:0:1)
     PrintingResults(base, height, Area)
    end.
    

Conclusion

The techniques discussed above are not used to the exclusion of others. In fact, the method outlined on the Bottom-Up page is frequently utilized to develop individual procedures which are then substituted for their corresponding stubs. This combined approach is especially important when a group of programmers is working on a single project.


© 2001 DFStermole
Created: 25 Nov 01
Last modified: 28 Nov 01