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

Slides:



Advertisements
Similar presentations
Copyright 2006 by Pearson Education 1 Building Java Programs Chapter 5: Program Logic and Indefinite Loops.
Advertisements

Building Java Programs
Copyright 2006 by Pearson Education 1 Building Java Programs Chapter 5: Program Logic and Indefinite Loops.
Loop variations do-while and for loops. Do-while loops Slight variation of while loops Instead of testing condition, then performing loop body, the loop.
Copyright 2006 by Pearson Education 1 reading: 4.1 Cumulative sum.
Copyright 2008 by Pearson Education 1 Building Java Programs Chapter 5 Lecture 5-1: while Loops, Fencepost Loops, and Sentinel Loops reading: 4.1, 5.1.
Copyright 2008 by Pearson Education 1 Midterm announcements Next week on Friday May 8 Must bring an ID Open book, open notes, closed electronics Must attend.
CS305j Introduction to Computing While Loops 1 Topic 15 Indefinite Loops - While Loops "If you cannot grok [understand] the overall structure of a program.
Control Structures II. Why is Repetition Needed? There are many situations in which the same statements need to be executed several times. Example: Formulas.
Chapter 4: Control Structures II
Building Java Programs Chapter 5 Program Logic and Indefinite Loops Copyright (c) Pearson All rights reserved.
1 Logical Assertions. 2 Logical assertions assertion: A statement that is either true or false. Examples: –Java was created in –The sky is purple.
1 Fencepost loops “How do you build a fence?”. 2 The fencepost problem Problem: Write a class named PrintNumbers that reads in an integer called max and.
Logic Our programs will have to make decisions on what to do next –we refer to the decision making aspect as logic Logic goes beyond simple if and if-else.
1 Building Java Programs Chapter 5 Lecture 5-1: while Loops, Fencepost Loops, and Sentinel Loops; Procedural Design reading: 5.1 – 5.2; 4.5.
1 while loops. 2 Definite loops definite loop: A loop that executes a known number of times.  The for loops we have seen so far are definite loops. We.
Chapter 5: Control Structures II J ava P rogramming: From Problem Analysis to Program Design, From Problem Analysis to Program Design,
CS 112 Introduction to Programming Program Analysis Yang (Richard) Yang Computer Science Department Yale University 308A Watson, Phone:
Random numbers. 2 The Random class A Random object generates pseudo-random numbers. –Class Random is found in the java.util package. import java.util.*;
Topic 14 while loops and loop patterns Copyright Pearson Education, 2010 Based on slides bu Marty Stepp and Stuart Reges from
Logic Our programs will have to make decisions on what to do next –we refer to the decision making aspect as logic Logic goes beyond simple if and if-else.
Chapter 4: Control Structures II
Chapter 5: Control Structures II
1 Building Java Programs Chapter 5 Lecture 5-2: Random Numbers reading: 5.1, 5.6.
Building java programs, chapter 5 Program logic and indefinite loops.
Zhen Jiang Dept. of Computer Science West Chester University West Chester, PA CSC141 Computer Science I 12/11/20151.
CONTROL STATEMENTS LOOPS. WHY IS REPETITION NEEDED?  There are many situations in which the same statements need to be executed several times.  Example:
Copyright 2010 by Pearson Education 1 Building Java Programs Chapter 5 Lecture 5-1: while Loops, Fencepost Loops, and Sentinel Loops reading: 4.1, 5.1.
Building Java Programs Program Logic and Indefinite Loops.
Zhen Jiang Dept. of Computer Science West Chester University West Chester, PA CSC141 Computer Science I 2/4/20161.
CONTROL STRUCTURE Chapter 3. CONTROL STRUCTURES ONE-WAY SELECTION Syntax: if (expression) statement Expression referred to as decision maker. Statement.
Flow of Control: Loops Module 4. Objectives Design a loop Use while, do, and for in a program Use the for-each with enumerations Use assertion checks.
CS 112 Introduction to Programming Loop Patterns: break; Fencepost Yang (Richard) Yang Computer Science Department Yale University 308A Watson, Phone:
1 BUILDING JAVA PROGRAMS CHAPTER 5 PROGRAM LOGIC AND INDEFINITE LOOPS.
CS 112 Introduction to Programming Loop Examples; Variable Scoping; Nested Loops; Yang (Richard) Yang Computer Science Department Yale University 208A.
1 Building Java Programs Chapter 5 Lecture 5-1: while Loops, Fencepost Loops, and Sentinel Loops reading: 5.1 – 5.2.
Categories of loops definite loop: Executes a known number of times.
Lecture 5: Program Logic
Chapter 5: Control Structures II
Repetition-Counter control Loop
Repetition-Sentinel,Flag Loop/Do_While
Chapter 5: Control Structures II
Building Java Programs
Building Java Programs Chapter 4
Building Java Programs
Building Java Programs
Building Java Programs
Building Java Programs
Topic 14 while loops and loop patterns
Building Java Programs
Logical assertions assertion: A statement that is either true or false. Examples: Java was created in The sky is purple. 23 is a prime number. 10.
Topic 17 assertions and program logic
Building Java Programs
Control Statements Loops.
Building Java Programs
Building Java Programs
Building Java Programs
Building Java Programs
Building Java Programs
Building Java Programs
Control Statements Loops.
Building Java Programs
Building Java Programs
Indefinite loop variations
Building Java Programs
Building Java Programs
CSE 142, Spring 2013 Chapter 5 Lecture 5-1: while Loops, Fencepost Loops, and Sentinel Loops reading: 5.1 – 5.2.
Building Java Programs
Building Java Programs
Building Java Programs
Presentation transcript:

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

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

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

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

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

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

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 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)

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

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

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.

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

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

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

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

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

 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?

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);

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);

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

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

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

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) { }

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) { }

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) { }

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?

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?

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

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

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,

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);

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

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. }

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 }

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?

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(); }

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.

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?

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);

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

Offline Slides: A More Detailed Example of Program Analysis 41

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; }

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

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

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.

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

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

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 >= print error message for every negative user input number

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.

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);

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 );

Offline Loop Design Slides 52

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 = = = = = 7 You need 5 tries!

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

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!"); }

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!"); }

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 = = = 25 Wrong! The answer was = 13 Wrong! The answer was = = = 42 Wrong! The answer was 32 You earned 9 total points.

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

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.

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

playOneRound Structure = = = = 11 structure: pick n = # of operands to be added (2-5) build problem string output problem to user compute points to return

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

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

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?