asserting java, ch 7: repetition
TRANSCRIPT
Chapter 6
Repetition
Asserting Java
© Rick Mercer
Algorithmic Pattern:
The Determinate loop
We often need to perform some action a specific
number of times:
— Produce 89 paychecks.
— Count down to 0 (take 1 second of the clock).
— Compute grades for 81 students
The determinate loop pattern repeats some action
a specific number of times.
Pattern: Determinate Loop
Problem: Do something exactly n times, where n is known in
advance.
Algorithm determine n repeat the following n times
perform these actions
CodeExample:
public boolean catDog(String str) {
int cats = dogs = 0;
int i = 0;
while(i <= str.length()-3) {
if(str.substring(i, i+3).equals("cat"))
cats = cats + 1;
if(str.substring(i, i+3).equals("dog"))
dogs = dogs + 1;
i++;
}
return cats == dogs;
}
Determinate Loops with while
The determinate loop pattern can be implemented with
the Java while loop
This template repeats a process n times:
int n = /* how often we must repeat the process */int counter = 1;
while ( counter <= n ) {
// the process to be repeated counter = counter + 1;
}
— determinate loops must know the number of repetitions before
they begin: know exactly how many employees, or students, or
whatever that must be processed, for example
Example for loop that produces an
average
Scanner keyboard = new Scanner(System.in);
double sum = 0.0;
double number;
System.out.print("How many do you want to average? ");
int n = keyboard.nextInt();
int counter = 1;
// Do something n times
while (counter <= n) {
System.out.print("Enter number: "); // <- Repeat 3
number = keyboard.nextDouble(); // <- statements
sum = sum + number; // <- n times
counter = counter + 1; // make sure the loop stops
}
double average = sum / n;
System.out.print("Average of "+ n
+ " numbers is "+ average);
Active Learning
What is the output :
int j = 1;
int n = 5;
while(j <= n) {
System.out.print (j + " ");
j = j + 1;
}
j = 0;
while(j <= 2 * n) {
System.out.print (j + " ");
j = j + 2;
}
Indeterminate Loops
Determinate loops have a limitation
— We must know n (the number of repetitions) in
advance
Many situations need us to repeat a set of
statements an unspecified number of times: — Processing report cards for every student in a school
(or paychecks for all employees, or...)
— Allowing 1 to many ATM transactions
— Asking the user for specific input and allowing re-entry
of input after invalid inputs
Some things that terminate
indeterminate loops
An indeterminate loop repeats a process until some
stopping event terminates the repetition
There are many such events, but we'll focus on these:
— User enters a special value indicating end of data
— A logical expression becomes false
— The Grid's mover hits the wall or an edge
— The end of a file is encountered
Indeterminate loops do not need to know n in advance
Indeterminate loops can actually determine n
Pattern Indeterminate loop
Problem Some process must repeat an unknown number
of times so some event is needed to terminate
the loop.
Algorithm while( the termination event has not occurred ) {
execute several actions1
bring the loop closer to termination}
Code while(dog.frontIsClear()) {
dog.turnLeft()
Example myGrid.move();
}
Example Indeterminate Loopneed Grid.java
// Using random robot placement, instruct robot to get to
// the wall in front, turn left, and move to the next wall
public class MoveAroundTheGrid {
public static void main(String[] args) {
Grid g = new Grid(10, 15);
while (g.frontIsClear()) {
g.move();
}
g.turnLeft();
while (g.frontIsClear()) {
g.move();
}
}
}
While loop with a Scanner
Sometimes a stream of input from the
keyboard or a file needs to be read until there
is no more data in the input stream
Consider a Scanner object constructed with a
String argument
— The string represents an input stream
You will need Scanner in ControlFun
These assertions pass
@Test
public void showScanner() {
Scanner scannerWithInts = new Scanner("1 2 3");
assertEquals(1, scannerWithInts.nextInt());
assertEquals(2, scannerWithInts.nextInt());
assertEquals(3, scannerWithInts.nextInt());
Scanner scanner =
new Scanner("There are five words here.");
assertEquals("There", scanner.next());
assertEquals("are", scanner.next());
assertEquals("five", scanner.next());
assertEquals("words", scanner.next());
assertEquals("here.", scanner.next());
}
Write method average to return the
average of the doubles in a Scanner
@Test
public void testNum100s() {
ControlFun cf = new ControlFun();
Scanner scanner1 = new Scanner("80.0 70.0 90.0");
Scanner scanner2 = new Scanner("1.0\t 2\n 3. 4.0");
assertEquals(80.0, cf.average(scanner). 0.01);
assertEquals(2.5, cf.average(scanner). 0.01);
}
@Test
public void testSumOfNegs() {
ControlFun cf = new ControlFun();
Scanner scanner0 = new Scanner("1 2 3");
Scanner scannerA = new Scanner("1 -2 3 -4");
Scanner scannerB = new Scanner("-1 -2 -3 -4");
assertEquals(0, cf.sumOfNegatives(scanner0));
assertEquals(-6, cf.sumOfNegatives(scannerA));
assertEquals(-10, cf.sumOfNegatives(scannerB));
}
Let sumOfNegatives return the sum of the
negative integers in a Scanner
What's wrong with this method?
public int sumOfNegatives(Scanner scanner) {
int result = 0;
while (scanner.hasNextInt()) {
if (scanner.nextInt() < 0) {
result += scanner.nextInt();
}
}
return result;
}