INTRODUCTION TO PROGRAMMING IN JAVA: SELECTION (IF-ELSE)

NOTE: This set of www pages is not the set of www pages for the curent version of COMP101. The pages are from a previous version that, at the request of students, I have kept on line.


CONTENTS

1. Selection
2. "If-else" statements
3. Example problem - power 4
3.1. Requirements
3.2. Analysis
3.3. Design
3.4. Implementation
3.5. Testing
 
4. Black box and white box testing
5. Example problem - linear equations (includes an example of a Boolean function)
5.1. Requirements
5.2. Analysis
5.3. Design
5.4. Implementation
5.5. Testing
6. Summary

First example includes a simple if, and second example an "if-else". The second example also includes a cast (for revision purposes).




1. SELECTION

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

  1. If-else statements
  2. Switch (or case) statements



2. "IF-ELSE" STATEMENTS

An "if-else" 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> ) { < Action Y> }
    
  2. if ( < Condition X> ) { < Action Y> }
    else { < Action Z> }
    

Where the condition is a Boolean expression (or a sequence of Boolean expressions), and the action part comprises one or more statements. Note that where the action part comprises only a single statement we can omit the "curly" brackets. We can also identify a number of variations of the above which are particular to individual programming languages. For example in Java we can write:

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

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

if (valueA < 50) ... ;

if (valueB == 0) ... ;

if (valueX > 10 & valueX < 20) ... ;

if (valueX < 10 | valueX > 20) ... ;

if (valueA <= 20.0 & (valueB != 'q' 
     | testFun(valueA,valueC) == 1)) ... ;


3. EXAMPLE PROBLEM --- POWER 4


3.1 Requirements

Design and create a Java program that takes a single 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 (Figure 1).

POWER 4 PROBLEM

Figure 1: Power 4 problem


3.2 Analysis

A class diagram for the proposed solution is given in Figure 2.


3.3 Design

From Figure 2 it can be seen that we require only one class, Power4App.

POWER 4 CLASS DIAGRAM

Figure 2: Power 4 class diagram


3.3.1 Power4app Class

Field Summary
private static Scanner input
           A class instance to facilitate input from the input stream.

Method Summary
public static void main(String[] args)
           Main (and only) method for resolution of problem. Takes input, carries out check on input using a simple if, and then outputs the result. A data table for the method is given to the right.

A Nassi-shneiderman chart is given in Figure 3. Note the way that the "choice point" is incorporated into the chart. If the test is satisfied (i.e. produces an anonymous data item of type Boolean which has the value true then flow of control proceeds down the left hand side of the chart. However, if the result is false then flow of control proceeds down the right hand side.

NASSI-SHNEIDERMAN CHART FOR POWER 4 APPLICATION CLASS

Figure 3: Nassi-Shneiderman charts for Power4app class main method

It is sometimes useful to produce an activity diagram (Figure 4) indicating flow of control through a method. Such a diagram is presented in Figure 4. The choice point (selection) is indicated by a "diamond", other sequences of statements by simple boxes. Flow of control is indicated by the directed lines. Flow starts at the "start" oval (referred to as the riser) and ends at the "end" oval (referred to as the sink). Thus we can imagine the flow of control being indicated by a fluid that comes out of the "riser", flows through the system, and disappears down the "sink". The principal advantages of such a diagram is that it clearly indicates the paths through the system, essential information required when testing software systems that include choice points (see below).

NASSI-SHNEIDERMAN CHART FOR POWER 4 APPLICATION CLASS MAIN 
	METHOD

Figure 4: Activity Diagram for Power4app class main method


3.3. Implementation

// POWER 4 APPLICATION
// Frans Coenen
// Tuesday 22 March 1999
// Revised: Wednesday 5 July 2005
// The University of Liverpool, UK   

import java.util.*;

class Power4app {

    // ------------------- FIELDS ------------------------ 
        
    // Create Scanner class instance
    private static Scanner input = new Scanner(System.in);
    
    // ------------------ METHODS ------------------------  
    
    /* Main method */
    
    public static void main(String[] args) {
    	int inputInteger;
	
    	// Input 
    
    	System.out.print("Input an integer: ");
    	inputInteger = input.nextInt();
	
	// Calculation
	
	if (inputInteger < 50) inputInteger += 10;
	inputInteger = (int) Math.pow((double)inputInteger,4.0); 
	
	// Output
	
	System.out.println("Result is:    " + inputInteger);
	}
    }

Table 1: Power 4 application class


3.4. Testing

1. Arithmetic testing: We should derive test cases incorporating positive, negative and zero sample values. An appropriate set of cases is given in the table to the right.

TEST CASEEXPECTED RESULT
inputIntegerOUTPUT
-10 0
0 10000
10160000

2. Path testing: An "if" statement should always be tested using at least 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. It is also a good idea, when using discrete data items in the condition expression, to test at the "cut-off" point where appropriate, i.e. 49 and 50 in this case (in the spirit of range and limit testing). A suitable set of test cases are given in the table to the right.

TEST CASEEXPECTED RESULT
inputIntegerOUTPUT
10 160000
4912117361
50 6250000
5912117361
Note that, as we would expect, inputs of 49 and 59 produce the same result. Note also that one of the test cases was also included in the arithmetic test case set. It is a good idea to "double-up" test cases where ever possible (i.e. design a test cases that address several aspect of the software at the same time), as this reduces the overall testing effort required.

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




4. BLACK BOX AND WHITE BOX TESTING

Techniques such as 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 a Java 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 input as integers and that the output is to be presented in the form of a real number. Note that to find a value for x we must rearrange the above equation:

LINEAR EQUATION EXPRESSION

Figure 5: Linear equation expressions

x = -c/b

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


5.2 Analysis

A class diagram for the proposed solution is given in Figure 6.


5.3 Design

From Figure 6 programmer two defined classes are required, LinearEquation and LinearEquationApp.

LINEAR EQUATION CLASS DIAGRAM

Figure 6: Linear equation class diagram


5.3.1 LinearEquation class

Field Summary
private int bValue
           An instance variable to store "b" value of an instance of the class LinearEquation.
private int cValue
           An instance variable to store "c" value of an instance of the class LinearEquation.
private double xValue
           An instance variable to store "x" value of an instance of the class LinearEquation.

Constructor Summary
LinearEquation(int b_intInput, int c_intInput)
           Constructs an instance of the class LinearEquation given b and c values as input.

Method Summary
public boolean resolveLinearEquation()
           Method to calculate x_value. Returns true if a result can be calculated and false in the event that b_value is equal to zero (and consequently a divide by zero error would occur if the calculation was attempted).
public double getXvalue()
           Method to access the private instance field x_value..

A Nassi-Shneiderman design for the above is presented in Figure 7.

LINEAR EQUATION CLASS N-S DIAGRAM

Figure 7: Nassi-Shneiderman chart for LinearEquation class


5.3.2 LinearEquationApp Class

Field Summary
private static Scanner input
           A class instance to facilitate input from the input stream.

Method Summary
public static void main(String[] args)
           Main method for resolution of linear equation problem. Allows input of two integers (as specified in requirements statement) which must be cast to doubles when the constructor is called. Once an instance of the class LinearEquation has been created the main method invokes the ResolveLinearEquation method to carry out the necessary calculation. If ResolveLinearEquation returns true output the result for x, and otherwise output an error message.

A Nassi-Shneiderman chart for the above is given in Figure 7.

LINEAR EQUATION APPLICATION CLASS N-S DIAGRAM

Figure 7: Nassi-Shneiderman chart for LinearEquationApp class

For completeness an activity diagram for the entire system is given in Figure 8.


5.4 Implementation


5.4.1 LinearEquation class

ACTIVITY DIAGRAM FOR LINEAR EQUATION PROBLEM

Figure 8: Activity diagram for linear equation problem

// LINEAR EQUATION CLASS
// Frans Coenen
// Tuesday 22 March 1999
// The University of Liverpool, UK   

class LinearEquation {

    // ------------------- FIELDS ------------------------ 
        
    private int b_value, c_value;
    private double x_value;
    
    // ---------------- CONSTRUCTOR ------------------------  
    
    public LinearEquation(int b_intInput, int c_intInput) {
    	b_value = b_intInput;
	c_value = c_intInput;
	}
    
    // ------------------ METHODS ------------------------  
    
    /* Resolve linear equation, returns true if successful and 
    false otherwise. */
    
    public boolean resolveLinearEquation() {
    
    	// Test for divide by 0 error, if found return false
	// otherise do calculation
	if (b_value != 0) {
            // Determine value for x and return true
	    x_value = ((double) -c_value)/(double) b_value;
	    return(true);
            }
        else return(false);	
	}
	
    /* Get x_value */
    
    public double getXvalue() {
    	return(x_value);
	}
    }

Table 2: Source code for linear equation class

Notes on the above:

  • We test whether the b_value is not 0. Testing against integer values is fine, but this should not be dome using real numbers as sometimes these include some rounding where zero may not actually be represented as 0.0.
  • Note the use of the cast and the - unary (monadic) prefix operator contained in the ResolveLineareEquation method. We could have written this as (- (double) c_value) but this would have been less clear. Casts and the - operator have lower precedence (i.e. are evaluated first) than the division operator.
  • The outer most brackets included in the arithmetic sub-statement, containing the unary - operator, ((double) -c_value) are superfluous, however they have been included to again enhance readability/understandability.
  • We could have used a single "simple if" instead of the "if-else" as follows:
    // Test for divide by 0 error, if found return false
    if (b_value == 0) return(false);
    	
    // Determine value for x and return true
    x_value = ((double) -c_value)/(double) b_value;
    return(true);
    
    both approaches are equally "right".

5.4.2 LinearEquationApp class

// LINEAR EQUATION APPLICATION
// Frans Coenen
// Tuesday 22 March 1999
// Revised: Wednesday 5 July 2005
// The University of Liverpool, UK   

import java.util.*;

class LinearEquationApp {

    // ------------------- FIELDS ------------------------ 
        
    // Create Scanner class instance

    private static Scanner input = new Scanner(System.in);
        
    // ------------------ METHODS ------------------------  
    
    /** Main method */
    
    public static void main(String[] args) {
    	LinearEquation newEquation;
	int            newBvalue, newCvalue;
	
    	// Input 
    
    	System.out.println("Input an integer values for b and c: ");
    	newBvalue = input.nextInt();
	newCvalue = input.nextInt();
	
	// Create linear equation instance
	
	newEquation = new LinearEquation(newBvalue,newCvalue);
	
	// Calculation. If method returns true output result, 
	// otherwiase produce error message.
	
	if (newEquation.resolveLinearEquation()) { 
	    System.out.print("Result is: "); 
	    System.out.println(newEquation.getXvalue());
	    }
	else
	    System.out.println("ERROR 1: Divide by zero error");
	}
    }

Table 3: Source code for linear equation application class

Note the way that the selection statement is encoded. The condition part of the statement is evaluated first and then one or other of the action parts is invoked according to the result. It is considered bad practice (and also pointless) to test the result of a Boolean method against itself, i.e. we should not write the condition part as (newEquation.resolveLinearEquation() == true).


5.4. Testing

5.4.1. Black box testing

Arithmetic testing: A suitable set of arithmetic test cases is given in the table to the right.


5.4.2. White box testing

Path testing: The activity diagram given in Figure 8 identifies two paths through the system; one where b_value is 0 and the other where b_value is non-zero. We should devise test cases to exercise both paths.

TEST CASEEXPECTED RESULT
b_valuec_valuex_value
-4-2-0.5
-4 0 0.0
-4 2 0.5
0-2Error
0 0Error
0 2Error
4-2 0.5
4 0 0.0
4 2-0.5

Two appropriate test cases are given in the Table to the right. Note that both are duplicates duplicate of a black box test case, thus we do nor need to run either.


5.4.3. Data validation testing

This should also be carried out

TEST CASEEXPECTED RESULT
b_valuec_valuex_value
0 2Error
4 2-0.5



6. "IF-ELSE" SUMMARY

Here we have described the selection process using an "if-else" statement. This comes in two forms:

  1. Simple: "If" part of statement only, no "else" part.
  2. Standard: Both "if" and "else" parts.

A generic Nassi-Shneiderman charts and Activity Diagram for both forms are given in Figure 9.

Simple (Lineaer) ifStandard if-else
Activity Diagrams
SIMPLE IF ACTIVITY DIAGRAM
STANDARD IF-ELSE ACTIVITY DIAGRAM
Nassi-Shneiderman Charts>
SIMPLE IF NS CHART
STANDARD IF-ELSE NS CHART

Figure 9 Generic Activity Diagrams and Nassi-Shneiderman charts "if-else" statements (simple/linear and standard forms)




Created and maintained by Frans Coenen. Last updated 10 February 2015