Presentation is loading. Please wait.

Presentation is loading. Please wait.

CS 112 Introduction to Programming Program Analysis; Fencepost Loops Yang (Richard) Yang Computer Science Department Yale University 208A Watson, Phone:

Similar presentations


Presentation on theme: "CS 112 Introduction to Programming Program Analysis; Fencepost Loops Yang (Richard) Yang Computer Science Department Yale University 208A Watson, Phone:"— Presentation transcript:

1 CS 112 Introduction to Programming Program Analysis; Fencepost Loops Yang (Richard) Yang Computer Science Department Yale University 208A Watson, Phone: 432-6400 Email: yry@cs.yale.edu

2 Admin.  PS6 posted [allows pair programming]  Replacement PS1 (RPS1) posted [Not encouraged] 2

3 Recap: Program Flow Control  We have covered all syntax of program flow control  Program flow control is among the most challenging parts in terms of mastering computer programming m it may involve complex logical analysis m it often has substantial flexibility and hence depends on personal style multiple types of conditional statements –if/else; switch; conditional operator multiple types of loop statements –for, while, do/while break/return in the middle of a loop

4 How to Grasp Program Flow Control  Learn common loop patterns  Conduct program analysis  Read and practice m Try out the offline exercises m Read sample programs 4

5 Roadmap  Today m Program analysis of flow control m Loop pattern for robust input processing  Mar. 28 m Loop pattern for arrays: sorting  Mar. 30 m Loop pattern for two-dimensional arrays: Page rank 5

6 Program Analysis  A useful tool to understand flow control better is program analysis 6 Requirements Analyze program to check if program satisfies requirements Program

7 Foundation of Program Analysis: Logical Assertions  Assertion: A statement that we focus on whether it is true, false, or sometime true/sometime false (unknown). Examples: m Yale was founded in 1776. m The sky is purple. m The capital of Connecticut is New Haven. m Prof. Yang met a donkey this morning. m int x; … x = x+10; x divided by 2 equals 7. (depends on the value of x)

8 Logical Assertions on Program Variables  One can make assertions on program variables at each point of a program m For example, right after a variable is initialized, its value is known, and we can make true/false statement: int x = 3; // is x > 0?  A common confusion: An assertion is not part of your program; it is a claim/property of your program at each point of your program True

9 Difficulty of Making Assertions  The value of a variable may become unknown after certain operations (hence leading to ”unknown/sometimes” assertions)  reading from a Scanner m assigned a number from a random number m a parameter's initial value to a method public static void mystery(int a, int b) { // is a == 10? UNKNOWN

10 Control Structure Establishes Assertions  At certain execution point of a control structure (e.g., if, while, break), we may know something: public static void mystery(int a, int b) { if (a < 0) { // is a == 10?... } FALSE We know a < 0, which implies a != any positive number.

11 Assertions and Controls  At the start of an if or loop's body, the test must be true : while (y < 10) { // is y < 10?... }  In the else or after a loop w/o break, the test must be false : while (y < 10) {... } // is y < 10?  Note: Inside a loop's body, the loop's test may become false : while (y < 10) { y++; // is y < 10? // if y < 12 } TRUE FALSE UNKNOWN TRUE

12 Program Analysis 12 Requirements Derive assertions to check if program satisfies requirements Program

13 Outline  Admin and recap  Program flow analysis and assertions  Robust user input processing loops 13

14 14 User Input Protocol  Two input styles m Header control protocol User first specifies the number of data items (e.g., MatchDB) m In-band control protocol User finishes input by entering a sentinel value –e.g., -1 to signal the end of input grades; “quit” to finish the program Why in-band sentinel: flexibility. Complexity of in-band sentinel: a data item just read can be either a real data item or the signaling sentinel N data 1 data N data || control

15 Outline  Admin and recap  Program flow analysis and assertions  Robust user input processing loops m Sentinel input 15

16  sentinel: A value that signals the end of user input. m sentinel loop: Repeats until a sentinel value is seen.  Example: Write a program that prompts the user for exam grade until the user types -1, then outputs the average grade. m (In this case, the value -1 is the sentinel value.) Type a grade (-1 to exit): 100 Type a grade (-1 to exit): 90 Type a grade (-1 to exit): -1 The average is 95. Sentinel Values Design question: for, while, or do loop?

17 Potential Solution Scanner console = new Scanner(System.in); int sum = 0, count = 0; int grade; do { System.out.print("Type a grade (-1 to exit): "); grade = console.nextInt(); sum += grade; count ++; } while (grade != -1); System.out.println(”The average is “ + count > 0? sum /count : 0);

18 Potential Solution: Test Type a grade (-1 to exit): 100 Type a grade (-1 to exit): 90 Type a grade (-1 to exit): -1 Output: The average is 63 The output is incorrect! Scanner console = new Scanner(System.in); int sum = 0, count = 0; int grade; do { System.out.print("Type a grade (-1 to exit): "); grade = console.nextInt(); sum += grade; count ++; } while (grade != -1); System.out.println(”The average is “ + count > 0? sum /count : 0);

19 Program Analysis 19 Requirements Derive assertions to check if program satisfies requirements Program

20 Precise Requirements Specification 20 reads in a valid grade add grade to sum/count => grade is not sentinel => add it to sum/count

21 Program Analysis Scanner console = new Scanner(System.in); int sum = 0, count = 0; int grade; do { System.out.print("Type a grade (-1 to exit): "); grade = console.nextInt(); sum += grade; count ++; } while (grade != -1); System.out.println(”The average is “ + count > 0? sum /count : 0); Condition to guarantee safety: sum and count include only valid grades sum and count are updated only when grade != -1 // assertion grade != -1 should be always true

22 Program Revision to Establish Assertion Scanner console = new Scanner(System.in); int sum = 0, count = 0; int grade; do { System.out.print("Type a grade (-1 to exit): "); grade = console.nextInt(); sum += grade; count ++; } while (grade != -1); System.out.println(”The average is “ + count > 0? sum /count : 0); if (grade != -1) { }

23 Rewrite: do/while -> while Scanner console = new Scanner(System.in); int sum = 0, count = 0; int grade; while (grade != -1) { System.out.print("Type a grade (-1 to exit): "); grade = console.nextInt(); sum += grade; count ++; } System.out.println(”The average is “ + count > 0? sum /count : 0); if (grade != -1) { }

24 Rewrite: do/while -> while Scanner console = new Scanner(System.in); int sum = 0, count = 0; int grade = 0; // any value other than sentinel while (grade != -1) { System.out.print("Type a grade (-1 to exit): "); grade = console.nextInt(); sum += grade; count ++; } System.out.println(”The average is “ + count > 0? sum /count : 0); if (grade != -1) { }

25 Sentinel Loop with break Scanner console = new Scanner(System.in); int sum = 0, count = 0; int grade; do { System.out.print("Type a grade (-1 to exit): "); grade = console.nextInt(); if (grade == -1) break; // break stops the containing loop sum += grade; count ++; } while (grade != -1); System.out.println(”The average is “ + count > 0? sum /count : 0); // Do we have assertion grade != -1?

26 Design Analysis int sum = 0; int grade = 0; while ( grade != -1 ) { System.out.print("Enter a number (-1 to quit): "); grade = console.nextInt(); if ( grade != -1 ) { sum = sum + grade; } We test grade != -1 twice Issue: Can we remove the duplication?

27 A “Simpler” Problem...  Revisit the countDown method that prints from a given maximum (>=1) to 1, separated by commas. For example, the call: countDown(5) should print: 5, 4, 3, 2, 1

28 Previous “Solution”  public static void countDown(int max) { for (int i = max; i >= 1; i--) { System.out.print(i + ", "); } System.out.println(); // to end the line of output }  Output from countDown(5) :  public static void countDown(int max) { for (int i = max; i >= 1; i--) { System.out.print(", " + i); } System.out.println(); // to end the line of output }  Output from countDown(5) :, 5, 4, 3, 2, 1 5, 4, 3, 2, 1, 5, 4, 3, 2, 1

29 Problem: Fence Post Analogy  We print n numbers but need only n - 1 commas.  If we use a loop algorithm that repeatedly places a post + wire, the last post will have an extra dangling wire. loop (length of fence-wire pair) { place a post. // e.g., place some wire. // e.g.,, } 5, 4, 3, 2, 1,

30 Problem: Fence Post Analogy The sentinel input loop pattern is also a fencepost problem: Must read N grades, but sum/count only the first N-1. Scanner console = new Scanner(System.in); int sum = 0, count = 0; int grade; do { System.out.print("Type a grade (-1 to exit): "); grade = console.nextInt(); sum += grade; count ++; } while (grade != -1); System.out.println(”The average is “ + count > 0? sum /count : 0);

31 Previous Design Pattern loop (length of fence) { place a post. if (! last post) place a wire. } Detect if it is the last post in the loop, if it is, do not place the wire

32 Alternative Design Pattern  Add a statement outside the loop to place the initial "post.” Also called a "loop-and-a-half" solution. place a post. loop (length of fence - 1) { place some wire. place a post. }

33 Fencepost Method Solution public static void countDown(int max) { System.out.print(max); // first post for (int i = max-1; i >= 1; i--) { System.out.print(", " + i); // wire + post } System.out.println(); // to end the line }  Alternate solution: Either first or last "post" can be taken out: public static void countDown(int max) { for (int i = max; i >= 2; i--) { System.out.print(i + ", "); // post + wire } System.out.println(1); // last post }

34 Fencepost Sentinel Loop: Grade public static final int SENTINEL = -1; public static final String PROMPT = "Type a grade (" + SENTINEL + ” to exit): “; public static GradeAnalyzer() { Scanner console = new Scanner(System.in); int sum = 0; int count = 0; // pull one prompt/read ("post") out of the loop int grade = getInt(PROMPT, console); while ( grade != SENTINEL ) { sum += grade; count++; // wire grade = getInt(PROMPT, console); // post } if (count > 0) System.out.println(”Avg: ” 1.0 * sum / count); } public static String getInt(String prompt, Scanner console { System.out.print(prompt); return console.nextInt(); } // Do we have assertion grade != -1 before updates?

35 Fencepost Sentinel Loop: Grade 35 read a number update sum int sum = 0; int count = 0; System.out.print("Enter a number (-1 to quit): "); int grade = console.nextInt(); while ( grade != -1 ) { sum = sum + grade; count ++; System.out.print("Enter a number (-1 to quit): "); grade = console.nextInt(); }

36 Comparison int sum = 0; int grade = 0; while ( grade != -1 ) { System.out.print("Enter a number (-1 to quit): "); grade = console.nextInt(); if ( grade != -1 ) { // detect the last post sum = sum + grade; } int sum = 0; System.out.print("Enter a number (-1 to quit): "); int grade = console.nextInt(); while ( grade != -1 ) { sum = sum + grade; System.out.print("Enter a number (-1 to quit): "); grade = console.nextInt(); } Duplicated code Duplicate execution Some programmers feel “heart-broken” to see there is “redundancy” in both designs.

37 Remove Redundancy int sum = 0; int grade = 0; while ( grade != -1 ) { System.out.print("Enter a number (-1 to quit): "); grade = console.nextInt(); if ( grade != -1 ) { // detect the last post sum = sum + grade; } So that we can exit the loop So that we don’t have an extra wire Q: Can we remove the duplication, say the first test?

38 Infinite Loop with Sentinel break Scanner console = new Scanner(System.in); int sum = 0; while (true) { System.out.print("Enter a grade (-1 to quit): "); int grade = console.nextInt(); if (grade == -1) { // detect the last post break; } sum = sum + number; // number != -1 here } System.out.println("The total was " + sum);

39 Comments  Choice between “infinite loop with sentinel break” vs “non- break ” is typically a personal style  The “non- break ” version is typically preferred, because m the high-level structure (“topical sentence”) indicates that the loop is controlled by a sentinel m the high-level structure (“topical sentence”) of the “break” version indicates that the loop is an infinite loop, which does not read right 39

40 40

41 Offline Slides: A More Detailed Example of Program Analysis 41

42 Program Analysis  Informal specification: m write a method to read a non-negative number from user; if the user input is negative, output an error message and try again.  Program: 42 public static double getNonNegativeNumber(Scanner console) { System.out.print("Type a nonnegative number: "); double number = console.nextDouble(); while (number < 0.0) { System.out.print(“Error: Negative; try again: "); number = console.nextDouble(); } return number; }

43 From Informal to Precise Requirements Specification 43 Requirement on returning number: reads in a non-negative number return number Requirement on error message: if user input negative if print error message => it is non-negative => return it => print error message => user input negative

44 Program Analysis: Returning Number public static double getNonNegativeNumber(Scanner console) { System.out.print("Type a nonnegative number: "); double number = console.nextDouble(); while (number < 0.0) { System.out.print(“Error: Negative; try again: "); number = console.nextDouble(); } return number; } Precise requirement on returning number: reads in a non-negative number => return it return number => it is non-negative look where we get number, make sure we return if non-negative

45 Program Analysis: Returning Number public static double getNonNegativeNumber(Scanner console) { System.out.print("Type a nonnegative number: "); double number = console.nextDouble(); while (number < 0.0) { System.out.print(“Error: Negative; try again: "); number = console.nextDouble(); } return number; } Precise requirement on returning number: reads in a non-negative number => return it return number => it is non-negative look where we return number; check precondition (TRUE assertion) to make sure non-negative number is non-negative because it is right after the while loop.

46 Using Assertions to Understand Program (II) public static double getNonNegativeNumber(Scanner console) { System.out.print("Type a nonnegative number: "); double number = console.nextDouble(); while (number < 0.0) { System.out.print(“Error: Negative; try again: "); number = console.nextDouble(); } return number; } Precise requirement on error message: if user input negative => print error message if print error message => user input negative look where we get number, make sure we print error if negative

47 Using Assertions to Understand Program (II) public static double getNonNegativeNumber(Scanner console) { System.out.print("Type a nonnegative number: "); double number = console.nextDouble(); while (number < 0.0) { System.out.print(“Error: Negative; try again: "); number = console.nextDouble(); } return number; } Precise requirement on error message: if user input negative => print error message if print error message => user input negative look where we print error; check precondition (TRUE assertion) to make sure user input is negative number is negative because it is right after we check

48 Summary: Program Analysis public static double getNonNegDouble(Scanner console) { System.out.print("Type a nonnegative number: "); double number = console.nextDouble(); while (number < 0.0) { System.out.print(“Error: Negative; try again: "); number = console.nextDouble(); } return number; } Requirements // ASSERTION: number < 0 - print an error message only if user number is negative - return number only if non-negative - return the first non-negative number // ASSERTION: number >= 0.0 - print error message for every negative user input number

49 Practice: Sentinel Sum 49 int sum = 0; System.out.print("Enter a number (-1 to quit): "); int grade = console.nextInt(); while ( grade != -1 ) { sum = sum + grade; System.out.print("Enter a number (-1 to quit): "); grade = console.nextInt(); } Analyze this program.

50 Practice: Analyze if They Give the Same Result 50 // set initial value of month so that the while // condition below is true initially to force a loop int month = -1; while (month 12) { month = getInt( console, “Enter a month (1 to 12): “); } // set initial value of month so that the while // condition below is true initially to force a loop int month = -1; do { month = getInt( console, “Enter a month (1 to 12): “); } while (month 12);

51 Practice: Analyze if They Give the Same Result 51 int sum = 0; int grade = 0; while ( true ) { System.out.print("Enter a number (-1 to quit): "); grade = console.nextInt(); if ( grade == -1 ) { // detect the last post break; } sum = sum + grade; } int sum = 0; int grade = 0; do { System.out.print("Enter a number (-1 to quit): "); grade = console.nextInt(); if ( grade == -1 ) { // detect the last post break; } sum = sum + grade; } while ( true );

52 Offline Loop Design Slides 52

53 Offline: NaturalCraps Game  Write a program that simulates rolling of two 6-sided dice until their sum comes up as a “natural” (i.e., 7 or 11) in the casino game of craps. 2 + 4 = 6 3 + 5 = 8 5 + 5 = 10 1 + 1 = 2 4 + 3 = 7 You need 5 tries!

54 Design Questions  Is the loop better controlled by for or while/do/while ? m Indeterminate logical condition (sum == 7 or 11) -> more likely a while or do/while loop  How many times may the loop execute, at least once? m at least once => we may try a do/while loop 54 NaturalCraps.java

55 Answer // Rolls two dice until a sum of 7 or 11 import java.util.*; public class NaturalCraps { public static void main(String[] args) { int tries = 0; int sum; do { int roll1 = randInt(1,6); // one roll int roll2 = randInt(1,6); sum = roll1 + roll2; System.out.println(roll1 + " + " + roll2 + " = " + sum); tries++; } while (sum != 7 && sum != 11); System.out.println("You need " + tries + " tries!"); }

56 Answer 2: do->while // Rolls two dice until a sum of 7 import java.util.*; public class NaturalCraps { public static void main(String[] args) { int tries = 0; int sum = 0; // force initial while to be true while (sum != 7 && sum != 11) { int roll1 = randInt(1, 6); // one roll int roll2 = randInt(1, 6); sum = roll1 + roll2; System.out.println(roll1 + " + " + roll2 + " = " + sum); tries++; } System.out.println("You won after " + tries + " tries!"); }

57 Offline: MathAdding Game  Write a program that plays an adding game. m Ask user to solve random adding problems with n (2-5) numbers. m The user gets n-1 points for an addition with n numbers, 0 for incorrect.  A user has 3 lives (3 chances) to make mistakes. 4 + 10 + 3 + 10 = 27 9 + 2 = 11 8 + 6 + 7 + 9 = 25 Wrong! The answer was 30 5 + 9 = 13 Wrong! The answer was 14 4 + 9 + 9 = 22 3 + 1 + 7 + 2 = 13 4 + 2 + 10 + 9 + 7 = 42 Wrong! The answer was 32 You earned 9 total points.

58 Design Questions  Is the loop better controlled by for or while/do/while ?  Indeterminate logical condition (cumulate 3 errors) -> more likely a while or do/while loop  How many times may the loop execute, at least once?  at least once => we may try a do/while loop 58

59 MathAddingGame Structure // Asks the user to do adding problems and scores them. import java.util.*; public class MathAddingGame { public static void main(String[] args) { Scanner console = new Scanner(System.in); // init. state int totalPoints = 0; int nChances = 3; do { // play a round; // update state: nChances, totalPoints } while (nChances > 0); System.out.println("You earned " + totalPoints + " total points."); } Design question: we design a method playOneRound, what should the return be? The user gets n-1 points for an addition with n numbers, 0 for incorrect.

60 playOneRound Requirement // play a round: // return the # of points earned; // 0 means user made a mistake static int playOneRound()

61 playOneRound Structure 1 + 2 + 3 + 4 + 5 = 15 4 + 10 + 3 + 10 = 27 4 + 9 + 9 = 22 9 + 2 = 11 structure: pick n = # of operands to be added (2-5) build problem string output problem to user compute points to return

62 playOneRound... // Builds one addition problem and presents it to the user. // Returns # of points earned. public static int playOneRound(Scanner console) { // print the operands being added, and sum them int nOperands = randInt(2, 5); int sum = 0; int n = randInt(1, 10); String question = “” + n; // post for (int i = 2; i <= nOperands; i++) { n = randInt(1, 10); question += " + " + n; // wire + post sum += n; } question += " = "; // read user's guess int guess = getInt( console, question ); if (guess == sum) return nOperands - 1; else return 0; } // end of playOneRound

63 MathAddingGame Program // Asks the user to do adding problems and scores them. import java.util.*; public class MathAddingGame { public static void main(String[] args) { Scanner console = new Scanner(System.in); // play until user gets 3 wrong int totalPoints = 0; int nChances = 3; do { int roundPoints = playOneRound(console); totalPoints += roundPoints; if ( roundPoints == 0) { nChances--; } } while (nChances > 0); System.out.println("You earned " + totalPoints + " total points."); } MathAdding.java

64 MathAddingGame Program // Asks the user to do adding problems and scores them. import java.util.*; public class MathAddingGame { public static void main(String[] args) { Scanner console = new Scanner(System.in); // play until user gets 3 wrong int totalPoints = 0; int nChances = 3; while (nChances > 0) { int roundPoints = playOneRound(console); totalPoints += roundPoints; if ( roundPoints == 0) { nChances--; } System.out.println("You earned " + totalPoints + " total points."); } Move the while condition up. Do we have the same result?


Download ppt "CS 112 Introduction to Programming Program Analysis; Fencepost Loops Yang (Richard) Yang Computer Science Department Yale University 208A Watson, Phone:"

Similar presentations


Ads by Google