Example 3: Multiple Alternative Decision ( if/else if/else )
This example processes a customer record using the multiple alternative decision structure. Decision statements are not just for controlling input and output. They control the flow of your program; that is really important when you write complex programs. When we branch our code using a multiple alternative decision structure, we choose different paths depending on the situation.
Problem Statement
A program is required to read a customer's name, a purchase amount, and a tax code. The tax code must be a valid whole number between 0-3 inclusive:
0 = Tax Exempt 1 = 3% tax 2 = 5% tax 3 = 7% tax
The program must then compute the sales tax and the total amount due, and print the customer's name, purchase amount, sales tax, and total amount due.
1. Nouns and Verbs
Identify the nouns and verbs in the problem statement.
PROBLEM STATEMENT: A program is required to read a customer's name, a purchase amount, and a tax code. If the purchase amount and tax code are valid, the program must then compute the sales tax and the total amount due, and print the customer's name, purchase amount, sales tax, and total amount due. Nouns: customer name, purchase amount, tax code, sales tax, total amount due Verbs: read, validate, compute, print
Validate is implied because the purchase amount and tax code must be valid
2. Defining Diagram
Convert the nouns and verbs into variable names and processes and create a defining diagram.
INPUTS: customerName purchaseAmount taxCode PROCESSING: read customer details validate customer details calculate sales tax calculate total amount print customer details OUTPUTS (if not valid): Error message Program ends OUTPUTS (if valid): customerName purchaseAmount salesTax totalAmount
3. Solution Algorithm
Create a solution algorithm based on the defining diagram.
public Constructor(){
call processCustomerRecord();
}
private method processCustomerRecord(){
declare and initialize String customerName that will hold end-user input
declare and initialize double purchaseAmount that will hold end-user input
declare and initialize int taxCode that will hold end-user input
declare and initialize double totalAmount which is calculated by the program
declare and initialize double salesTax which is calculated by the program
instantiate Scanner object using input as its variable
instantiate StringBuilder object using sb as its variable
print to the console "Please enter your name"
set input.next() into the customerName variable
print to the console "Please enter your purchase amount"
validate input
save the input.nextDouble() value into the purchaseAmount variable
print to the console "Please enter a tax code"
validate input insuring the entry is within range
save the input.nextInt() value into the taxCode variable
if (taxCode is 0) {
salesTax = 0
}
else if (taxCode is 1) THEN{
salesTax = purchaseAmount * 0.03
}
else if (taxCode is 2) THEN{
salesTax = purchaseAmount * 0.05
}
else{
salesTax = purchaseAmount * 0.07
}
set totalAmount = purchaseAmount + salesTax
display customerName, purchaseAmount, salesTax, totalAmount
}// end of processCustomerRecord()
4. Test Plan
Create a test plan for the algorithm.
VARIABLES: customerName purchaseAmount taxCode TEST CASE 1: INPUT VALUES: Fred, 10, 7 EXPECTED RESULT: taxCode is out of range, so display error message and end program ACTUAL RESULT: Error message is displayed and program ends TEST CASE 2: INPUT VALUES: Bill, e EXPECTED RESULT: purchaseAmount is not valid, so display error message and end program ACTUAL RESULT: Error message is displayed and program ends TEST CASE 3: INPUT VALUES: Sue, 149.99, 2 EXPECTED RESULT: Sue, 149.99, 7.50, 157.49 ACTUAL RESULT: Sue, 149.99, 7.50, 157.49
5. Java Code
Write the Java source code based on the solution algorithm. Test your code using the test plan.
Below is a Java code snippet. A working Java solution must also include a class, constructor, as well as the main method and necessary import statements. Please study the code. Better yet, create a working Java project in NetBeans.
REALLY IMPORTANT! The hasNextDouble() and hasNextInt() methods are to get you used to end-user validation. As is, the results are not what you may expect if the end-user does not enter a number. Also, this code does not give the end-user the opportunity to try again. These details were left out in the interest of clarity for the topic at hand...Decision Structures.
Notice I nested all the processing code inside of the first if statement. This is because there is no reason to process the record if the end-user did not enter a valid number in the beginning. Notice what happens if the tax code is out of range. Pay attention to the comments and notice how I print the sales tax with only two decimal places.
// Process Customer Record
private void processCustomerRecord() {
final String NEW_LINE = System.lineSeparator();
String customerName = "";
double purchaseAmount = 0.0;
double salesTax = 0.0;
int taxCode = 0;
double totalAmount = 0;
StringBuilder sb = new StringBuilder(30);
Scanner input = new Scanner(System.in);
// Get input from user
System.out.println("Please enter Customer Name");
customerName = input.next();
System.out.println("Please enter Purchase Amount");
if(input.hasNextDouble()){
purchaseAmount = input.nextDouble();
System.out.println("Please choose from the following menu"
+ NEW_LINE
+ "0 = Tax Exempt"
+ NEW_LINE
+ "1 = 3% tax"
+ NEW_LINE
+ "2 = 5% tax"
+ NEW_LINE
+ "3 = 7% tax");
System.out.println();
System.out.println("Please enter Tax Code");
if(input.hasNextInt()){
taxCode = input.nextInt();
if(taxCode >= 0 && taxCode <= 3){
// convert purchase amount to cents to avoid rounding errors
purchaseAmount *= 100;
//calculate using if statements (example 3)
if (taxCode == 0) {
salesTax = 0;
}
else if (taxCode == 1) {
salesTax = purchaseAmount * 0.03;
}
else if (taxCode == 2) {
salesTax = purchaseAmount * 0.05;
}
else {
salesTax = purchaseAmount * 0.07;
}
// Calculate purchase amount
totalAmount = purchaseAmount + salesTax;
// convert cents back to dollars for output
//notice I use compound assignment operators
purchaseAmount /= 100;
salesTax /= 100;
totalAmount /= 100;
//create the purchases message using StringBuilder
sb.append("Purchase for ").append(customerName).append (":");
sb.append(NEW_LINE);
sb.append("Amount: $").append(purchaseAmount);
sb.append(NEW_LINE);
sb.append("Sales Tax: $");
//Use the library function .format of the String class to
//format sales tax with a dollar sign and two decimal places
sb.append(String.format("%.2f", salesTax));
sb.append(NEW_LINE);
sb.append("Total: $");
//Use the library function .format of the String class to
//format total amount with a dollar sign and two decimal places
sb.append(String.format("%.2f", totalAmount));
// Print the purchase to the page
System.out.println(sb.toString());
}//end if for testing taxCode
else{
System.out.println(customerName + ", you almost did the right thing. "
+ "But since you did not enter a number for the tax code, "
+ "the program will end.");
System.exit(0);
}
}//end if(input.hasNextInt())
}//end of if(input.hasNextDouble())
else{
System.out.println(customerName + ", you did not enter a number. "
+ "This program will end.");
System.exit(0);
}//end of else that goes with if(input.hasNextDouble())
}//end processCustomerRecord
Here is the output with 5% tax:
Think About It
We added the menu selection so the end-user could choose a tax code without having to re-think what they are. Do you think the tax codes election numbers should match with the tax rates?