CS1101: Programming Methodology Recitation 3 – Control Structures Checksum Validation Objective: Develop a program that validates a Universal Product Code (UPC) number. A valid UPC is a 12 digit value that meets the criteria: • m is the sum of 2nd, 4th, 6th, 8th, 10th digits • n is the sum of the 1st, 3rd, 5th, 7th, 9th, 11th digits • r = 10 – ((m + 3.n) mod 10) • Valid UPC number if 12th digit is equal to r 2 Checksum Validation Example: 780070121354 m = 8 + 0 + 0 + 2 + 3 = 13 n = 7 + 0 + 7 + 1 + 1 + 5 = 21 r = 10 – ((13 + 3.21) mod 10) = 10 – (76 mod 10) = 10 – 6 = 4 Example: 123456789011 m = 2 + 4 + 6 + 8 + 0 = 20 n = 1 + 3 + 5 +7 + 9 + 1 = 26 r = 10 – ((20 + 3.26) mod 10) = 10 – (98 mod 10) = 10 – 8 = 2 3 Analysis and Design: − Values m, n and r − Input string s and its numeric representation number − With number, the 12 component digits d1, d2 …, d12 can be determined for initializing m, n and r 4 Analysis and Design: − − − − Prompt user to supply 12 digit number Extract input and assign to s Convert s to a numeric representation number. If number is negative or has more than 12 digits Then report number is not a UPC code Else Assign least significant (12th) digit of number to d12 Assign 11th digit of number to d11 : Assign 1st digit of number to d1 Compute m = d2+d4+d6+d8+10 Compute n = d1+d3+d5+d7+d9+d11 Compute r = 10 – ((m – 3.n) mod 10) If r = d12 Then report number is a feasible UPC code Else report number is not a UPC code // Checks whether a user-specified value meets the UPC criteria import java.io.*; public class UPC { // main(): application entry point public static void main(String[] args) throws IOException { final long MAX_POSSIBLE_UPC_CODE = 999999999999L; // set input stream and get number BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); System.out.print("Enter a 12-digit whole number: "); String s = stdin.readLine(); long number = Long.parseLong(s); max int value is only 10 digits. Use long to represent UPC code // determine whether number is a possible upc code if ((number < 0) || (number > MAX_POSSIBLE_UPC_CODE)) { // not a upc code System.out.println(s + " is an invalid UPC code"); } else { // might be a upc code, determine individual digits int d12 = (int) (number % 10); number /= 10; int d11 = (int) (number % 10); number /= 10; int d10 = (int) (number % 10); number /= 10; int d9 = (int) (number % 10); number /= 10; int d8 = (int) (number % 10); number /= 10; int d7 = (int) (number % 10); number /= 10; int d6 = (int) (number % 10); number /= 10; int d5 = (int) (number % 10); number /= 10; int d4 = (int) (number % 10); number /= 10; int d3 = (int) (number % 10); number /= 10; int d2 = (int) (number % 10); number /= 10; int d1 = (int) (number % 10); number /= 10; % - Java modulus operator // compute sums of first 5 even digits and the odd digits int m = d2 + d4 + d6 + d8 + d10; int n = d1 + d3 + d5 + d7 + d9 + d11; // use UPC formula to determine required value for d12 int r = 10 - ((m + 3*n) % 10); // based on r, can test whether number is a UPC code if (r == d12) { // is a upc code System.out.println(s + " is a feasible UPC code"); } else { // not a upc code System.out.println(s + " is an invalid UPC code"); } } } } Nested if statements Print three messages depending on test score and student age if (testScore >= 70) { if (studentAge < 10) System.out.println (“You did a great job!”); else System.out.println (“You did pass”); //test score >= 70 and age >=10 } else System.out.println (“You did not pass”); //test score < 70 if (testScore >= 70 && studentAge < 10) { System.out.println (“You did a great job!”); } else { //either test score < 70 OR age >=10 if (testScore >= 70) System.out.println (“You did pass”); else System.out.println (“You did not pass”); } Nested if statements Input 3 integers and determine how many of them are negative if (num1 < 0) { if (num2 < 0) { if (num3 < 0) negativeCount = 3; else negativeCount = 2; } else { if (num3 < 0) negativeCount = 2; else negativeCount = 1; } } else { if (num2 < 0) { if (num3 < 0) negativeCount = 2; else negativeCount = 1; } else { if (num3 < 0) negativeCount = 1; else negativeCount = 0; } } //all three are negative //num1 and num2 are negative // num1 and num3 are negative // num1 is negative // num2 and num3 are negative // num2 is negative // num3 is negative // no negative numbers Nested if statements Input 3 integers and determine how many of them are negative More elegant version! negativeCount = 0; if (num1 < 0) negativeCount ++; if (num2 < 0) negativeCount ++; if (num3 < 0) negativeCount ++; Rules for if statements 1. Minimize number of nestings 2. Avoid complex boolean expressions. - Make them as simple as possible. - Don’t include many ANDs and ORs. 3. Eliminate unnecessary comparisons. 4. Don’t be satisfied with first correct statement. Always look for improvement 5. Read your code again. Can you follow the statement easily ? If not, try to improve it. Dataset Analysis Objective: Develop a program that finds the min, max, and mean of a dataset of values. Analysis and Design: Methods: 1. public double getMinimum() 2. public double getMaximum() 3. public double getAverage() These methods return double.NaN if dataset is empty 13 Dataset Analysis Analysis and Design: Constructors: 1. public DataSet () – initialize representation of an empty dataset 2. Public DataSet (String s) – initialize dataset with values from file with name s 3. member methods – getSize(), addValue (double x), clear(), load (String s) Instance variables: • private int n • private double minimumValue • private double maximumValue • private double xSum 14 import java.io.*; public class DataSetTester { public static void main(String[] args) throws IOException { DataSet dataset = new DataSet("age.txt"); System.out.println(); System.out.println("Minimum: " + dataset.getMinimum()); System.out.println("Maximum: " + dataset.getMaximum()); System.out.println("Mean: " + dataset.getAverage()); System.out.println("Size: " + dataset.getSize()); System.out.println(); dataset.clear(); dataset.load("stature.txt"); System.out.println("Minimum: " + dataset.getMinimum()); System.out.println("Maximum: " + dataset.getMaximum()); System.out.println("Mean: " + dataset.getAverage()); System.out.println("Size: " + dataset.getSize()); System.out.println(); } } // Data set summary representation import java.io.*; public class DataSet { // instance variables private int n; private double xSum; private double minimumValue; private double maximumValue; // DataSet(): default constructor public DataSet() { clear(); } // DataSet(): specific constructor public DataSet(String s) throws IOException { load(s); } // clear(): empties the data set public void clear() { n = 0; xSum = 0; minimumValue = Double.NaN; maximumValue = Double.NaN; } // add(): adds the value to the set public void addValue(double x) { xSum += x; ++n; if (n == 1) { minimumValue = maximumValue = x; } else if (x < minimumValue) { minimumValue = x; } else if (x > maximumValue) { maximumValue = x; } } // load(): adds the values from the file to set public void load(String s) throws IOException { // get a reader for the file BufferedReader fileIn = new BufferedReader( new FileReader(s)); // add values one by one String currentLine = fileIn.readLine(); while (currentLine != null) { double x = Double.parseDouble(currentLine); addValue(x); currentLine = fileIn.readLine(); } // close up file fileIn.close(); } // getAverage(): compute data set average public double getAverage() { if (n == 0) return Double.NaN; else return xSum / n; } // getMinimum(): produce minimum data set value public double getMinimum() { return minimumValue; } // maximum(): produce maximum data set value public double getMaximum() { return maximumValue; } // getSize(): produce data set size public int getSize() { return n; } }