Module 0094: Writing pseudocode subroutines

Tak Auyeung, Ph.D.

November 8, 2018

Contents

1 About this module
2 Parameters
3 Return value
4 Working on the subroutine
 4.1 What is it supposed to do?
 4.2 Fix on one objective
 4.3 Does it need a loop?
  4.3.1 Loop objective(s)
  4.3.2 Loop exit conditions
  4.3.3 Loop body
  4.3.4 Initialization
  4.3.5 Does it process an array?
  4.3.6 Prechecking or postchecking?
 4.4 Does it need a conditional statement?
 4.5 Does it need to invoke a subroutine?

1 About this module

2 Parameters

Parameters are very important to a subroutine. They help define what a subroutine is supposed to do. As a result, it is important to spend some time to think about the following:

3 Return value

A return value is a handy feature, but it is not necessary. A return value makes it possible for a subroutine to complete a computation and reply with the result without needing a by-reference parameter. A by-reference parameter is cumbersome because it requires the caller (the invoking code) to own a local variable, and specify it as a parameter in the invocation.

4 Working on the subroutine

4.1 What is it supposed to do?

What is the subroutine supposed to do? This is the most important question. As you gain experience as a programmer, you’ll learn how to express the objectives of a subroutine more formally. Nonetheless, even now, you need to specify the result of a subroutine informally using a mixture of English and mathematical symbols.

For example, if a subroutine takes a parameter ‘a’ that is an array, and it returns the minimum value of the array, then the result can be specified as follows:

r a[0],r a[1],r a[|a| 1] (1)

This notation is not particularly concise, but it is fine for a beginning programmer. As you take more courses in mathematics and programming, you will learn to use more formal symbols, such as

i [0|a| 1] : r a[i] (2)

This obscure notation means “for all i from 0 to |a| 1, r is less than or equal to a[i].”

However, you may realize that this definition is not entire correct. For example, the value ‘6’ is not the minimum of the array with the values 12, 34, 6, 8, 10 and 21.

To correct our definition, we need to add one more constraint that r = a[i] for some i that is between 0 and |a| 1. The informal definition becomes the following:

r a[0],r a[1],r a[|a| 1],r = a[i] (3)

The formal definition becomes as follows:

(i [0|a| 1] : r a[i]) (k [0..|a| 1] : r = a[k]) (4)

The second part means “there exists a ‘k’ between 0 and |a| 1 inclusively such that r = a[k].

If you do not feel comfortable with mathemtical notations, then try your best to express the objective of the subroutine in English.

4.2 Fix on one objective

When you work on a subroutine, fix on one objective at a time. Do not get distracted (too much) by “minor details”.

Let us use the “check sort” subroutine as an example. The objective of the subroutine as a whole is to check if an array is sorted or not. The subroutine returns true if (and only if) the following condition is true:

a[0] a[1] a[|a| 1] (5)

Note that this expression can also be expressed as

(a[0] a[1]) (a[1] a[2]) (a[|a| 2] a[|a| 1]) (6)

4.3 Does it need a loop?

A piece of pseudocode if one of the following conditions is satisifed:

If you determine that you need a loop, then you need to think about the following as well.

4.3.1 Loop objective(s)

What is the loop supposed to do? In our example, the loop needs to determine whether elements in an array are sorted or not.

The objective(s) of a loop is imporant, as it ultimately determines the condition(s) that control when we exit a loop.

4.3.2 Loop exit conditions

Once you identify the objective(s) of a loop, then you can determine the exit conditions. Note that you may not be able to use pseudocode right away, but at least you should be able to state the conditions in English.

In our example, we can say that we want to exit the loop when “the array ‘a’ is confirmed to be sorted or confirmed to be unsorted.”

4.3.3 Loop body

The body of a loop is where the bulk of the work goes. Ina beginning class, there may not be a lot of code in the body of a loop. However, in general, the body of a loop contains a lot of code.

Note that the body of a loop must have some connections to the exit condition of a loop. Otherwise, if the exit condition of a loop is false, it will remain false forever!

4.3.4 Initialization

Every variable that gets used in a loop must be considered for initialization. Some variables do not need to be initialized because they are parameters, or have their values determined by some other means. Other variables do not need to be intiialized because they are “write only”, which means any initialized value is overwritten before it can be utilized.

4.3.5 Does it process an array?

Any loop that processes an array needs to keep track of at least which element in the array it is handling. This means the exit condition often involves at least one variable that serves as an index in the exit condition itself or the body of the loop.

If a loop processes an array, you should also ask the question “do I need to check if the index variable is in a valid range”. This condition is often a part of the exit condition.

With certain exceptions, most algorithms explore an array in a “linear” way. This means an algorithm either begins with the first element, and work its way to the last one, or vice versa. Consequently, the body of the loop should include either an increment or decrement statement for the index variable.

Last, but not least, don’t forget the initialization of the index variable before the loop!

4.3.6 Prechecking or postchecking?

In general, a prechecking loop is more general and useful than a postchecking loop. The only exception is that the loop body itself sets the exit condition. In this case, only a postchecking loop is valid.

4.4 Does it need a conditional statement?

A conditional statement is not a loop! The main difference between a conditional statement and a prechecking loop is that after we perform the statements in either the “then” or “else” portion of a conditional statement, we do not go back to the “if” part again!

There are cases, however, that we need to use a conditional statement (and not a prechecking loop). In general, if you have a number of alternative actions to perform, and the selection criteria (of each action) can be expressed as a yes/no (true/false, Boolean) question, then you need a conditional statement.

4.5 Does it need to invoke a subroutine?

If there is a subroutine that performs a function that your pseudocode needs to perform, just invoke the subroutine.