3.5 Results
3.5.2 Design Validity
Even the simplest of programs calls for a sequence of computations/activities to be executed with its associated constraints (Guttag2013). Let us take such a simple program by way of illustration.
Example 3.1 Compute the sum of nrnatural numbers.
The steps [1]–[5] in the sequence in Fig.3.1achieve this for nr= 12; the result is output—[6] and the related output in the following line. Any other (positive) integral value can be assigned to nrand the corresponding sum computed in the same manner.
Figure3.2aids the understanding of the program and its working.‘while’ is a keyword.‘while i:’ tests the value of i; as long as it is True—that is it is non-zero
—the group of statements following is executed. The colon ‘:’ following i signifies this. This set of statements forming the group is to be indented with respect to the beginning of the line (incidentally in Python such a group is often referred to as a
‘suite’). The indentation can be achieved through tabs or spaces. But all the statements within the group should have the same indentation—done consistently with tabs or spaces (preferably spaces). One line left free after the group [4] and [5]
here—signifies the end of the group. In the specific program here if i (equal to nr) at the start is non-zero, it is added to the sum [4] and decremented [5]. The sequence continues untili becomes zero; i.e., nr(12), nr− 1 (11), nr− 2 (10), … 2, and 1 are
© Springer Nature Singapore Pte Ltd. 2016 T.R. Padmanabhan, Programming with Python, DOI 10.1007/978-981-10-3277-6_3
19
all successively added to the sum. Once the loop operation is over the program proceeds to the following line [6] and continues execution. Here the values of nr and sums are printed out. The simplicity of the loop structure is striking. There is no need to put parentheses around the condition to be tested, no need to identify the group by enclosing it within curly brackets and so on. The group may have as many executable statements as desired. The whole condition is checked after every execution of the group sequence.
Example 3.2 Identify all the numbers in the interval {100 to 200} which are divisible by 13 and output them.
The 6-line program from [7]–[11] achieves this; it is a bit more involved compared to the previous one. The program accepts three integers—l1 (lower limit),l2 (upper limit), and a specified number n—and prints out all the numbers between l1 and l2 which are divisible by n. j—a dummy/running variable—is assigned the value of the lower limit to start with. Two successive checks are done on j. First check whether j < l2; if so enter the loop/continue within the loop execution. Within the loop 1 check whetherj is divisible by n. If so enter loop 2 and execute it. Else do not enter loop 2/keep away from it. Loop 2 here demands a single action—print the value of the number and proceed to the next line. Once you
>>> sum, Nr = 0, 12 [1]
>>> i = Nr [2]
>>> while i: [3]
... sum += i [4]
... i -= 1 [5]
... >>> print('The sum of all natural numbers up to (and inclusive of) ' + repr(Nr) + ' is ' +
repr(sum)) [6]
The sum of all natural numbers up to (and inclusive of) 12 is 78
>>> l1, l2, n = 100, 200, 13 [7]
>>> j = l1
>>> while j < l2: [8]
... if j%n == 0: [9]
print(repr(j) + ', ') [10]
... j += 1 [11]
... 104, 117, 130, 143, 156, 169, 182,
195, [12]
Fig. 3.1 Python Interpreter sequence for Examples3.1and3.2
20 3 Simple Programs
exit loop 2, you are back in loop 1. Increment the value ofj [11]. This forms the last line of the program within loop 1. In the specific case here all numbers in the interval—100–200—that are divisible by 13 are printed out in the same sequence as they are encountered.
The program brings out a number of additional aspects of Python.
• Loop 2 is within loop 1. All statements within loop 2 form a sub-group.
(Incidentally loop 2 has only a single statement here.) They appear with the same indentation within loop 1 (see Fig.3.3).
• ‘if’ is a keyword. It is used to check a condition and execute a loop if the condition is satisfied.
• The operator ‘==’ checks whether the values of quantities on either side are identical. Specifically here if j%n is zero, j%n == 0 is true (or 1); if it is non-zero, it is false (or 0).
>>> sum, Nr = 0, 12 [1]
>>> i = Nr [2]
>>> while i: [3]
... sum += i [4]
... i -= 1 [5]
...
>>> print('The sum of all natural numbers up to (and inclusive of) ' + repr(Nr) + ' is ' + repr(sum)) [6]
The sum of all natural numbers up to (and inclusive of) 12 is 78 All inputs following the primary prompt given without indentation
All inputs in the ‘while i’ group given with the same indentation Primary prompt
Secondary prompt
An ‘enter’ without any input following a secondary prompt signifies end of the group: Python interpreter reverts to primary prompt in the next line
Fig. 3.2 Structure of the program for the sequence [1]–[6] in Fig.3.1(Example3.1)
>>> l1, l2, n = 100, 200, 13 [7]
>>> j = l1
>>> while j < l2: [8]
... if j%n == 0: [9]
print(repr(j) + ', ') [10]
... j += 1 [11]
...
104,
Inner loop (loop 2) Outer loop (loop 1) Main program Fig. 3.3 Structure of the
program for the sequence [7]–[11] in Fig.3.1(Example 3.2)
Incidentally if a loop has only a single statement in it, the same can follow the condition on the same line. The Python Interpreter sequence is as in Fig.3.4.
Any normal/useful program will require a sequence of activities (representing the corresponding executable statements) to be carried out. The sequence will be linked through specific conditional decisions (as in the two small illustrations above). It is necessary to conceive of the overall computation, fully understand the same, represent it in a clear logical sequence and then do the program coding. Such a structured representation is conveniently done in‘pseudo-code’ form. It is good programming practice to represent the program in pseudo-code form and then proceed with the coding proper. The pseudo code for a program with one condi-tional loop within is shown in Fig.3.5a; Example3.1can be seen to be of this type.
The pseudo-code in Fig.3.5b has two conditional loops—loop 2 being executed within loop 1; Example 3.2 can be seen to be of this type. The following are noteworthy here:
• Any sequence of executions which does not involve conditional checks is represented by one/a few statements. The suite of these statements together constitutes one logical block to be executed. ‘begin’ and ‘end’ signify the beginning and the end of the block/suite.
• Every logical block is entered after a conditional check. To clarify this, the logical block is identified through a definite indent on the left of the parent block.
• For successive logical checks followed by corresponding logical blocks similar indentations are used.
In general the pseudo code of a program may involve a number of conditional loops in a sequence; some of these loops may have single or multiple loops within in cascaded/sequential forms. A number of such pseudo code structures appear with the examples to follow here as well as in subsequent chapters.
>>> l1, l2, n = 100, 200, 13
>>> j = l1
>>> while j < l2:
... if j%n == 0:print(repr(j) + ', ') ... j += 1
... 104, 117, 130, 143, 156, 169, 182, 195,
>>>
Fig. 3.4 The sequence in Fig.3.3with its loop 2 being in a single line
22 3 Simple Programs
The pseudo code representation of the program enables the programmer to conceive of the program in its totality, identify the conditions and activities at the highest level and represent it in a compact form. Subsequently each of the activities identified can be looked into separately and split into separate connected condi-tional blocks (See Fig.3.6). The process can be continued as much as necessary;
finally each block in the representation can be coded separately. All such coded blocks can be combined conforming to the representations at different stages and finally the overall program can be realized. This is the ‘top down’ approach used for the program. The approach has many advantages:
(a) (b)
Fig. 3.5 a Pseudo codes for the sequence in Fig.3.1: a First example and b Second example
• Visualization of the program in the proper perspective—in terms of major blocks and their connections/links at the top level.
• Identification of the activities at each block, their connections, and sequences.
• Clarity in visualization and program realization.
• Easiness in testing and debugging: each of the identified smallest blocks can be programmed, tested, and debugged separately and blocks combined in a step by step manner.
• With large programs different segments can be developed individually, and (if necessary) separately by different groups. All segments can be knitted together with the least interface problems.