Example 5: Switch Structure Algorithm
This example processes a customer record. However, in this version we use a switch 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
SWITCH on (taxCode){
case 0:
salesTax is 0
break out of case statement
case 1:
salesTax is purchaseAmount * 0.03
break out of case statement
case 2:
salesTax is purchaseAmount * 0.05
break out of case statement
default:
salesTax is purchaseAmount * 0.07
break out of case statement
}//end switch structure
}// end of processCustomerRecord()
4. Test Plan
Create a test plan for the algorithm. Please note, in the test plan, “CASE” is not the same as the case in the switch structure.
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){
// Calculate sales tax using switch statement
switch (taxCode) {
case 0:
salesTax = 0;
break;
case 1:
salesTax = purchaseAmount * 0.03;
break;
case 2:
salesTax = purchaseAmount * 0.05;
break;
default:
salesTax = purchaseAmount * 0.07;
break;
}//end of switch structure
// Calculate purchase amount
totalAmount = purchaseAmount + salesTax;
// convert cents back to dollars for output
//notice the compound 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
Study the above code again. Did you notice the code inside of the default case option? I chose to use the last tax code as default. Default can contain the default option if the end-user does not choose a valid option or even an error message. You have to logically think about code as you are writing. Remember to test with data that makes the application fail because that often leads you to a better solution.