SELECTION (IF-ELSE)


1. SELECTION

A selection statement provides for selection between alternatives. We can identify two broad types of selection construct:

  1. If-else statements
  2. Case statements

2. IF-ELSE STATEMENTS

An if statement, sometimes referred to as a conditional, can be used in two forms (the first is often referred to as a linear if):

  1. if <Condition X> then
            <Action Y>
    end if;
    
  2. if <Condition X> then
            <Action Y>
    else
            <Action Z>
    end if;
    

Where the condition is a Boolean expression (or a sequence of Boolean expression). We can also identify a number of variations of the above which are particular to individual programming languages. For example in Ada we can write:

if <Condition X1> then
        <Action Y1>
elsif <Condition X2> then
        <Action Y2>
...
elsif <Condition Xn> then
        <Action Yn>
else
        <Action Z>
end if;

The following are all examples of valid Boolean expressions, or sequences there of, that may form the condition part of "if-else" statements:

if A < 50 then ...

if B = 0 then ...

if X > 10 and X < 20 then ...

if X < 10 or X > 20 then ...

if A <= 20.0 and (B /= 'q' or testFun(A,C) = 1) then ...

3. EXAMPLE PROBLEM POWER 4


3.1 Requirements

Design and create an Ada program that takes a single positive integer as input, if the input is less than 50 adds 10 and returns the result raised to the power of 4, otherwise simply returns the input raised to the power of 4.


3.2 Design

Commence by using a top down analysis of the problem as illustrated by the hierarchical deconstruction presented below:

TOP DOWN ANALYSIS

A single procedure will be sufficient to implement these tasks:

  1. POWER_4 (top level procedure): Input data, process, and output result.
    NAMEDESCRIPTIONTYPERANGE
    NUMBERInput variablePOSITIVEDefault
    Remember that the type POSITIVE is a standard "built-in"
    subtype of the type INTEGER available in the package STANDARD (as is the type NATURAL). This package is always linked in automatically on compilation of an Ada program.

A Nassi-Shneiderman design is presented below. Note how we include selection.

NASSI_SHNEIDERMAN CHART

Note also that the top down analysis given above only identifies the required operations and not the nature of the flow of control through the desired software system, i.e. the presence of a choice point in this case. We can indicate the flow of control using a Flow Chart as shown below. The diagram indicates all the paths (two in this example) through the proposed program.

DATA FLOW DIAGRAM

3.3. Implementation

-- POWER 4
-- 6 August 1997
-- Frans Coenen
-- Dept Computer Science, University of Liverpool

with TEXT_IO;
use TEXT_IO;

procedure POWER_4 is
        package INTEGER_INOUT is new INTEGER_IO(INTEGER);
        use INTEGER_INOUT;
        NUMBER: POSITIVE;
begin
-- Read value A
        PUT_LINE("Input a value: ");
        GET(NUMBER);
-- Check for NUMBER < 50, if so add 10
        if NUMBER < 50 then
                NUMBER := NUMBER + 10;
        end if;
-- Output A^4
        PUT_LINE("Result is: ");
        PUT(NUMBER**4);
        NEW_LINE
end POWER_4;

Notes:

  1. A data item of the type POSITIVE is included. This type is linked in automatically and thus we do not need to expressly include it using with and use clauses.
  2. The code incorporates a linear "if" statement.

3.4. Testing

TEST CASEEXPECTED RESULT
NUMBEROUTPUT
0CONSTRAINT ERROR
114641
220736
21474836462.126764785333e+37
21474836472.126764789294e+37

BVA and limit testing: Use BVA and limit testing to analyse and test limits of input values. Suitable test cases are presented in the table to the right. Note that the expected result of the last two test cases is beyond the maximum value for the integer type used in the implementation. An incorrect answer will therefore be produced when these test cases are run, and consequently a return to the requirements phase in the software life cycle is indicated.

TEST CASEEXPECTED RESULT
NUMBEROUTPUT
2152136750625

Arithmetic testing: To test the arithmetic operation of the software we should include some arithmetic testing. This dictates a test case with a positive sample value (zero and negative values are precluded). We have already devised a test cases incorporating positive input values, however these were all at the limits of the input range. A test case which uses a "middle of the range" value might therefore be appropriate here (see table given to the right).

TEST CASEEXPECTED RESULT
NUMBEROUTPUT
4912117361
50 6250000

Path testing:. An "if" statement should always be tested using two test cases, one that causes the if statement to succeed and one that causes it to fail. In other words both "paths" through the procedure should be tested. Consequently this type of testing is referred to as path testing. Two appropriate test cases are given in the table to the right.

Data validation: In addition we should undertake some data validation testing


Example Problem Power 4 Report.

4. BLACK BOX AND WHITE BOX TESTING

Techniques such as BVA, limit and arithmetic testing are generally regarded as Black Box Testing techniques. The term is intended to convey the idea that the software to be tested is to be regarded as a box, the internal workings of which cannot be seen, into which we feed input data as a result of which output data is produced. Thus black box test cases are only concerned with input and output and not the nature of the transformation(s) that causes the first to become the second. In some cases, for example arithmetic testing, we may make use of knowledge of the inner workings of a program to reduce the number of test cases that need to be considered, but such tests are still considered to be black box in nature.

The opposite of black box testing is white box (or glass box) testing. White box testing is concerned with the inner workings of a software systems. Path testing, as demonstrated above, is an example of a while box testing technique.

Data validation is not generally considered to fall into either the black box or white box categories.


5. EXAMPLE PROBLEM LINEAR EQUATION


5.1 Requirements

A linear equation with one unknown can be expressed as follows:

bx + c = 0

where b and c represent numeric quantities. Produce an Ada program which will solve equations of this form (i.e. find a value for x - the root of the equation). Assume b and c are integers and that the output is to be presented accurate to four decimal places. Note that to find a value for x we must rearrange the above equation:

x = -c/b

Consequently b must not have a value of 0 (otherwise a "divide by zero error will occur").


5.2 Design

A top level analysis is presented below:

TOP DOWN ANALYSIS

We will encode these operations using a single procedure:

  1. LINEAR_EQUATION (Top level procedure): Input data, test for "b = 0", resolve equation and output result.
    NAMEDESCRIPTIONTYPERANGE
    B_VALUEGlobal input variableINTEGERDefault
    C_VALUEGlobal input variableINTEGERDefault
    X_VALUEGlobal output variableFLOATDefault
    B_FLOATGLobal variableFLOATDefault
    X_FLOATGLobal variableFLOATDefault
NASSI_SHNEIDERMAN CHART

A Nassi-Shneiderman design for this procedure is presented to the right and a flow chart below. In the design note that if the value for B_VALUE is equal to zero we output the message "Invalid value for B". Otherwise we obtain a value for C_VALUE, carry out the necessary calculation (X_VALUE = -C_VALUE/B_VALUE) and then output the resulting value for X_VALUE.

DATA FLOW DIAGRAM

5.3. Implementation

-- LINEAR EQUATION
-- 6 August 1997
-- Frans Coenen
-- Dept Computer Science, University of Liverpool

with TEXT_IO;
use TEXT_IO;

procedure LINEAR_EQUATION is
        package INTEGER_INOUT is new INTEGER_IO(INTEGER);
        use INTEGER_INOUT;
        package FLOAT_INOUT is new FLOAT_IO(FLOAT);
        use FLOAT_INOUT;
        B_VALUE, C_VALUE          : INTEGER;
        B_FLOAT, C_FLOAT, X_VALUE : FLOAT;
begin
-- Read value for B_VALUE
        PUT_LINE("Input value for B: ");
        GET(B_VALUE);
-- Check B_VALUE = 0, if so output error message
        if B_VALUE = 0 then
                PUT_LINE("Invalid value for B_VALUE (B_VALUE = 0)");
-- Otherwise continue, obtain value for C_VALUE, convert B_VALUE and
-- C_VALUE to type FLOAT, and then  calculate and output X_VALUE
        else
                PUT_LINE("Input value for C: ");
                GET(C_VALUE);
                B_FLOAT := FLOAT(B_VALUE);
                C_FLOAT := FLOAT(C_VALUE);
                X_VALUE := (-1.0*C_FLOAT)/B_FLOAT;
                PUT("X is ");
                PUT(X_VALUE, FORE=>3, AFT=>4, EXP=>0);
                NEW_LINE;
        end if;
end LINEAR_EQUATION;

Note Ada does not like it if you write C_VALUE*-1 therefore we must write either -1*C_VALUE, or C_VALUE*(-1).


5.4. Testing

5.4.1. Black box testing

TEST CASEEXPECTED RESULT
B_VALUEC_VALUEX_VALUE
-2147483647-2147483647-1
21474836462147483646-1
2147483647 2147483647-1.0000
2147483647-2147483648 1.0000
-2147483648 2147483647 1.0000
-2147483648-2147483648-1.0000

BVA and limit testing: Input values have a notional range associated with them dictated by the machine dependent lowest and highest numbers available in the default integer range. We should therefore carry out some BVA testing based on knowledge of this range. We should also test the effect of all possible combinations of input at the default limits of this range. A suitable set of test cases is given in the table to the right.

TEST CASEEXPECTED RESULT
B_VALUEC_VALUEX_VALUE
-1000.0000
0*Invalid value
1000.0000

Arithmetic testing: Arithmetic testing involves test cases using negative, zero and positive sample input values. We have tested combinations of positive and negative input values, therefore we only need to test values which involve a zero value (a suitable set of test cases is presented in the table given to the right).

TEST CASEEXPECTED RESULT
B_VALUEC_VALUEX_VALUE
0*Invalid value
1004004

5.4.2. White box testing

Path testing: The DFD given above indicates two paths through the program, one where B_VALUE is 0 and tbne other where B_VALUE is non-zero. We should devise test cases to exercise both paths. Two appropriate test cases are given in the Table to the right. Note that the first is a duplicate of a black box test case, thus we only need to run the second.

5.4.3. Data validation testing

This should also be carried out


Example Problem Linear Equation Report.


6. BOOLEAN FUNCTIONS

We can write our own Boolean expression functions (functions that return true or false). The following code fragments gives a function that returns TRUE if its argument is an even number (the remainder after division by two using rem is zero) and FALSE otherwise.

function ODD_NUMBER(NUMBER: INTEGER) return BOOLEAN is
begin
        if NUMBER REM 2 = 0 then
                RETURN(TRUE);
        else
                RETURN(FALSE);
        end if;
end ODD_NUMBER;

This Boolean function could now be used in some other if..else statement as the selector. For example consider the following (slightly nonsensical) program:

with TEXT_IO;
use TEXT_IO;

procedure TEST_PROG is
          package INTEGER_INOUT is new INTEGER_IO(INTEGER);
          use INTEGER_INOUT;
          NUM: INTEGER;

----------------------------------------------------------------
-- ODD NUMBER BOOLEAN FUNCTION (returns true if input is an odd integer
-- and false otherwise
        function ODD_NUMBER(NUMBER: INTEGER) return BOOLEAN is
        begin
                if NUMBER REM 2 = 1 then
                        RETURN(TRUE);
                else
                        RETURN(FALSE);
                end if;
        end ODD_NUMBER;

----------------------------------------------------------------
-- TOP LEVEL PROCEDURE
begin
        PUT_LINE("Input an integer ");
        GET(NUM);
        if ODD_NUMBER(NUM) then
                PUT_LINE("Odd number");
        else
                PUT_LINE("Even number");
        end if;
end TEST_PROG;

Boolean functions can be particularly useful for error checking where range and number of digit declarations will not suffice.




Created and maintained by Frans Coenen. Last updated 11 October 1999