The Design of High Quality Programs and Using PDL

There are several important steps that must be followed in order to design and create a high quality program. The first step in high quality design is to identify and define the prerequisites, which are the answers to the critical "what I am doing and how will I do it" questions. Remember that although you may learn more about requirements during the development process, and requirements may change, you will do well to nail down as much as possible before starting any coding.  It is very important to determine the prerequisites at the outset because it is far less costly, in terms of time and money, to catch a mistake early in the project. After you know what your prerequisites are, you can use tools such as Programming Design Language (PDL) to create your detailed design.

Here are some prerequisites that are common to most projects:

Figuring out all the prerequisites will seem to take a long time, but the more time you spend planning the less time you will have to spend debugging or rewriting code because it doesn't do what you wanted it to. According to Steve McConnell's Code Complete, on a larger project the requirements stage should take between twenty and thirty percent of the time that the project is expected to take.  Don't be afraid to take longer - in my personal experience we have had projects where we intentionally spent up to fifty percent of the time in the design stage.  They turned out to be significantly  cheaper to create and easier to maintain than earlier projects in which we did not take the extra time to ensure that we knew as many of the requirements as possible.


Well, now that all the prerequisites are figured out, it's time to start coding, right? Well, not quite yet. First we have to write the PDL, which stands for Program Development Language. PDL is a series of English-like statements that describe what you want to do. These statements should not include programming language specific syntax, and should describe what you want to do rather than how you plan to do it. Write PDL at the level of intent.

Writing PDL is an iterative process that takes you from the general problem definition to the doorstep of coding.  You will first write the problem definition, then write a more specific description of each part of your program should do. Then you need to go back to each description and write down a more detailed version of what needs to be done. As the descriptions become more detailed, you may start to introduce the data structures into the PDL. With each iteration, it should become more clear how the actual code should be written. Eventually, it will be easier for you to write the code, and describe what you want to have happen. At this point, it is time to start writing the code. Import the PDL into your programming language editor (if you didn't already develop it there), then turn it into comments. After each piece of PDL, write the code that does what the PDL says.

There are many benefits to writing PDL:

 

Here are some examples of PDL for a swap sort. Which one is the best?

Example 1:
With the index i going from the maximum number 
of elements of the list less 1 down to 1 
and then within that the index j going from 
one up to i in increments of 1, 
if array (j) < array(j+1), then swap them
around; otherwise go on.

 

As you can see Example 1 isn't very helpful. It wouldn't be simple to write the code using this PDL, because it's far too general. It isn't structured, and it uses computer-ese terms such as "i" and "j".  At best, it might be a starting point to write the rest of the PDL from, but it isn't a good final product.

 

Example 2:

 

for i = (max-1) downto 1 do
     for j = 1 to i do
          if array[j] > array[j+1] then
               Begin
                    Temp := array[j];
                    Array[j] := array[j+1];
                    Array[j+1] := Temp;
               End;
     // end of inner loop

//end of outer loop

While Example 2 is more specific than Example 1 it is still bad PDL. As was mentioned before, PDL should not include any language specific syntax. This example includes comments such as a for loop, and syntax that is specific to Pascal. None of the descriptions here are written in plain English. If you were unfamiliar with Pascal, and wanted to translate this logic into another language, you'd probably first want to translate it to better PDL!.

 

Example 3:

 

The purpose of a swap sort is to put an array of 
numbers into sequential order. This sorting is 
accomplished by comparing the values of two adjacent 
values in the array. If the two numbers are already 
in proper numerical order, the numbers remain in 
position. If the two adjacent numbers are out of 
proper sequence, their positions are interchanged. 
The sorting mechanism is best explained by example.
Given the sequence of numbers:
     8    3    5    1
On the first pass, the first two numbers are compared
     8    3    5    1
Since the 8 and 3 are out of order, their positions 
are interchanged, and the next two numbers are compared
     3    8    5    1
Since the 8 and 5 are out of order, their positions 
are interchanged, and the next two numbers are compared
     3    5    8    1                     
Since the 8 and 1 are out of order, their positions are 
interchanged.
     3    5    1    8
After the first pass, the 8 has "swapped" to the end 
of the list (hence the term swap sort). Since the 8 
is already in the correct position, on the second pass,
 only the 3, 5, and 1 are considered:
     3    5    1    8    (3 and 5 in proper position)
     3    5    1    8    (5 and 1 are out of order)
     3    1    5    8    (5 has "swapped" into the correct position)
Third and final pass:
     3    1    5    8    (5 and 8 are in the correct positions)
     3    1    5    8    (3 and 1 are out of order)
     1    3    5    8    (Correct order)
The function needs an array of numbers and the total number of numbers.
The outer loop controls the last position in the array to be examined.
The inner loop controls which pair of numbers are being considered.
The outer loop index goes from the maximum number of numbers 
minus 1 down to 1
Begin
The inner loop index goes from 1 to the current value of the outer loop counter
Begin
(Assuming the value of the inner loop index is n:)
If the nth element in the array is larger than the (n+1)th element
Begin
Assign the nth array element to a temporary variable
Assign the (n+1)th array element to the nth array element
Assign the temporary variable to the (n+1)th element in the array
End of the if statement
End of the inner loop
End of the outer loop


Example 3 is a better example of PDL. This example clearly describes what the swap sort is, and how it is going to work. It would be fairly simple to write the code using a section of this PDL, and since it isn't language specific it could be translated into more than one language.  It is a bit lengthy, however, and does not use indentation to show the structure of the logic.

 

Example 4:
The purpose of a swap sort is to put an array of numbers into 
sequential order. This sorting is accomplished by comparing the 
values of two adjacent values in the array. If the two numbers 
are already in proper numerical order, the numbers remain in 
position. If the two adjacent numbers are out of proper sequence,
their positions are interchanged.
The function needs to know the content of an array of numbers 
and the count of numbers in that array.

Print the original array contents
Loop, counting down from the count of numbers to 1
   Loop, counting from 1 to the current value of the outer loop counter
      (Assuming the value of the inner loop index is n:)
      If the nth element in the array is larger than the (n+1)th element
         Assign the nth array element to a temporary variable
         Assign the (n+1)th array element to the nth array element
         Assign the temporary variable to the (n+1)th element in the array
      Endif
   End loop
End loop
Print the sorted array contents

 

Example 4 succinctly describes what the swap sort is, and how it is going to work. Again, it would be fairly simple to write the code using a section of this PDL, and since it isn't language specific it could be translated into more than one language.  It is not so long that it impedes comprehension, and it uses indentation to show the structure of the logic. Unfortunately it is impossible to completely avoid the use of mathematical terms when describing a swap sort, but outside of this quibble we have our final PDL.

Below are three links that show how this PDL may be used to develop code.

View an example in C

View an example in Java

View an example in C++


After the PDL and the code have been written it is time for you to pretend to be the computer. It is important for you to go through the code and ensure that the program is really doing what you want it to do. At this point you might find things like missing semi-colons or small logic errors. It would be a good idea to mentally test all the operations using both reasonable data, and data that you know is incorrect to make sure that the error handling in your program works like it should.

Now you can finally compile the program. If everything went well there should be very few errors. If you get some warnings from the compiler make sure to resolve them as well as the more serious errors that you might have. Correcting the warnings may help to solve some otherwise less discernable logic problems in the program. It is tempting to ignore the warnings, but it pays off to fix them.

Once the program compiles it is time to test the program. Remember to test all of the paths in the selection statements including error checks.

References:
McConnell, Steve. Code Complete, A Practical Handbook of Software Construction. Microsoft Press (1993).



Created by Allan Caine, Laura Drever, Gorana Jankovic, Megan King, and Marie Lewis.
Revised by Vince Sorensen and Mandy Aldcorn.
Last Modified: June 8, 2000

Copyright 2000 Department of Computer Science, University of Regina.


[CS Dept Home Page]