# University of Washington, CSE 142

## Lab 4: if/else, Scanner, cumulative algorithms, Strings

Except where otherwise noted, the contents of this document are Copyright 2012 Stuart Reges and Marty Stepp.

lab document created by Marty Stepp, Stuart Reges, Whitaker Brand and Hélène Martin

# Basic lab instructions

• Talk to your classmates for help. You can even work on the lab with a partner if you like.
• You may want to bring your textbook to future labs to look up syntax and examples.
• Stuck? Confused? Have a question? Ask a TA for help, or look at the book or past lecture slides.
• Complete as many problems as you can within the allotted time. You don't need to keep working on these exercises after you leave the lab.
• Feel free to complete problems in any order.
• Before you leave today, make sure to check in with one of the TAs in the lab to get credit for your work.

# Today's lab

Goals for today:

• use `if/else` statements to select between multiple code actions
• use `Scanner` to create interactive programs that read user input
• practice cumulative algorithms for complex computations
• use `String`s to represent and manipulate text data
• Where you see this icon, you can click it to check the problem in Practice-It!

# `if/else` Statements

An if/else statement lets your program choose between 2 or more options.

```if (test) {
statement(s);
} else {
statement(s);
}
```

Example:

```if (gpa >= 2.0) {
System.out.println("Welcome to Mars University!");
} else {
}
```

# Exercise : `if`/`else` mystery

Consider the following Java code. Fill in the boxes with the output produced by each of the method calls.

```public static void mystery(int n) {
System.out.print(n + " ");
if (n > 10) {
n = n / 2;
} else {
n = n + 7;
}
if (n * 2 < 25) {
n = n + 10;
}
System.out.println(n);
}
```
 `mystery(40);` `40 20` `mystery(8);` `8 15` `mystery(0);` `0 17` `mystery(12);` `12 16` `mystery(20);` `20 20`

# Exercise : numUnique

Write a method named `numUnique` that accepts three integers as parameters and that returns the number of unique integers among the three. For example, the call `numUnique(18, 3, 4)` should return 3 because the parameters have 3 different values. By contrast, the call `numUnique(6, 7, 6)` would return 2 because there are only 2 unique numbers among the three parameters: 6 and 7.

Compare your solution to your neighbors'. Did you all solve it the same way?

• (Try solving this problem in Practice-It by clicking the icon above.)

Write a method `quadrant` that accepts a pair of real numbers x and y and returns the quadrant for that point:

For example, `quadrant(-2.3, 14.2)` returns 2. If the point falls directly on either axis, return 0.

• (Try solving this problem in Practice-It by clicking the icon above.)

# User input and `Scanner`

Method name Description
`nextInt()` reads and returns the next token as an `int`, if possible
`nextDouble()` reads and returns the next token as `double`, if possible
`next()` reads and returns a single word as a `String`
`nextLine()` reads and returns an entire line as a `String`

Example:

```import java.util.*;   // so you can use Scanner
...
Scanner console = new Scanner(System.in);
System.out.print("How old are you? ");   // prompt
int age = console.nextInt();
System.out.println("You typed " + age);
```

Write a complete program `DevryAdmit` with the behavior shown below. Use the `Scanner` to read user input for a student's grade point average and SAT exam score. A GPA below 1.8 will cause the student to be rejected; an SAT score below 900 will also cause a rejection. Otherwise the student is accepted.

```Devry University admission program
What is your SAT score? 1280
You were accepted!
```

# Cumulative algorithms

• A cumulative algorithm is one where you incrementally accumulate a larger value by repeatedly adding, multiplying, etc., and storing the result into a variable over and over.
• Key aspect of a cumulative algorithm: A loop, and a variable declared outside the loop whose value is modified inside the loop.
• Example: Cumulative algorithm to sum the numbers 1-100:
```int sum = 0;
for (int i = 1; i <= 100; i++) {
sum = sum + i;
}
System.out.println(sum);    // 5050
```
• Some of the following problems ask you to write cumulative algorithms.

# Exercise : repl

• Write a method named `repl` that accepts a `String` and a number of repetitions as parameters and returns the `String` concatenated that many times. For example, the call `repl("hello", 3)` returns `"hellohellohello"`. If the number of repetitions is 0 or less, an empty string is returned.
• Try solving this problem in Practice-It! using the link above.
• (Hint: This is best solved with a cumulative algorithm. Start with an empty string and build it up piece by piece.)

# Exercise : swapPairs

• Write a method named `swapPairs` that accepts a `String` as a parameter and returns that `String` with each pair of adjacent letters reversed. If the `String` has an odd number of letters, the last letter is unchanged. For example, the call `swapPairs("forget")` should return `"ofgrte"` and the call ```swapPairs("hello there")``` should return `"ehll ohtree"`.
• Try solving this problem in Practice-It! using the link above.

# Exercise : pow

Write a method named `pow` that accepts a base and an exponent as parameters and returns the base raised to the given power. For example, the call `pow(3, 4)` returns 3 * 3 * 3 * 3 or 81. Do not use `Math.pow` in your solution; use a cumulative algorithm instead. Assume that the base and exponent are non-negative. See ch4 lecture slides on cumulative sums for a hint.

• (Try solving this problem in Practice-It by clicking the icon above.)
• For added challenge, try turning your solution into a second version `pow2` that works with real number bases and negative exponents, as in book Exercise 4.11.

# Exercise : `Scanner` sum

Copy and paste the following code into jGrasp.

```public class SumNumbers {
public static void main(String[] args) {
int low = 1;
int high = 1000;
int sum = 0;
for (int i = low; i <= high; i++) {
sum += i;
}
System.out.println("sum = " + sum);
}
}
```

continued on next slide...

# Exercise : `Scanner` sum

Modify the code to use a `Scanner` to prompt the user for the values of `low` and `high`. Below is a sample execution in which the user asks for the same values as in the original program (1 through 1000):

```low? 1
high? 1000
sum = 500500
```

Below is an execution with different values for `low` and `high`:

```low? 300
high? 5297
sum = 13986903
```

You should exactly reproduce this format.

Use the Output Comparison Tool to check your work.

# `String` methods

Method name Description
`charAt(index)` character at given index
`indexOf(str)` index where the start of the given `String` appears in this string (-1 if not found)
`length()` number of characters in this `String`
`replace(str1, str2)` a new string with all occurrences of str1 changed to str2
`substring(index1, index2)`
or `substring(index1)`
the characters in this string from index1 (inclusive) to index2 (exclusive); if index2 is omitted, grabs till end of string
`toLowerCase()` a new string with all lowercase letters
`toUpperCase()` a new string with all uppercase letters

# Exercise : String expressions

Write the results of each expression with `String`s in "quotes" and characters in single quotes (`'a'`)

```//       index 0123456789012345
String str1 = "Frodo Baggins";
String str2 = "Gandalf the GRAY";
```
 `str1.length()` `13` `str1.charAt(7)` `'a'` `str2.charAt(0)` `'G'` `str1.indexOf("o")` `2` `str2.toUpperCase()` `"GANDALF THE GRAY"` `str1.toLowerCase().indexOf("B")` `-1` `str1.substring(4)` `"o Baggins"` `str2.substring(3, 14)` `"dalf the GR"` `str2.replace("a", "oo")` `"Goondoolf the GRAY"` `str2.replace("gray", "white")` `"Gandalf the GRAY"` `"str1".replace("r", "range")` `"strange1"`

# Exercise : ProcessName

Copy/paste and save ProcessName.java in jGRASP, then go to the next slide.

```import java.util.*;  // for Scanner

public class ProcessName {
public static void main(String[] args) {
Scanner console = new Scanner(System.in);

System.out.println("Your name is: " + name);
}
}
```

continued on the next slide ...

# Exercise - code to add

• Add code to the program so that it reads the user's first and last name (read an entire line as a single string), then prints the last name followed by a comma and the first initial. (Assume that the user types a valid name.) Example:
```Type your name: Jessica Miller
```
• Notice that the program reads an entire line of user input, not just one word.
• Try solving this problem in Practice-It! using the link above.

# Exercise : Syntax errors

• The following Java program has 11 errors. Work with your neighbor to find them all. Can you explain why each of them is an error and describe how Java reacts to them?  ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ``` ```public class StringOops { public static void main(String[] args) { Scanner console = new Scanner(System.in); System.out.print("Type your name: "); String name = console.nextString(); process(name); } public static void process(string "name") { if (name == Whitaker) { System.out.println("You must be really awesome."); } replace("a", "e"); toUppercase(name); name.substring(0, 3); System.out.println(name + " has " + name.length + " letters"); } } ```
• Copy and paste the code into jGrasp and see if you can fix the errors.

1. line 5: `nextString` should be `next`
2. line 9: `string` should be `String`
3. line 9: `name` should not be in quotes
4. line 10: `Whitaker` should be in quotes
5. line 10: cannot compare strings with `==`; must use `.equals`
6. line 13: cannot call `replace` without specifying a string object (`name`)
7. line 14: `toUppercase` should be `toUpperCase`
8. line 14: `name.` should come before `toUpperCase`, not passed as a parameter to it
9. line 14: must say `name =` to store the result of `toUpperCase`
10. line 15: must say `name =` to store the result of `substring`
11. line 16: must use parentheses `()` when calling `length`

# Exercise - Corrected version

```public class StringOops {
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
String name = console.next();
process(name);
}

public static void process(String "name") {
if (name.equals("Whitaker")) {
System.out.println("You must be really awesome.");
}
name = name.replace("a", "e");
name = name.toUpperCase();
name = name.substring(0, 3);
System.out.println(name + " has " + name.length() + " letters");
}
}
```

# `if`/`else` factoring

• It's easy to introduce redundancy in the branches of an `if`/`else`. For example:
```if (x < 30) {
a = 2;
x++;
System.out.println("CSE 142 TAs are awesome! " + x);
} else {
a = 2;
System.out.println("CSE 142 TAs are awesome! " + x);
}
```
• The code can be factored out to become: (notice that the `else` went away!)
```a = 2;
if (x < 30) {
x++;
}
System.out.println("CSE 142 TAs are awesome! " + x);
```

# Exercise : `if`/`else` Factoring

• The program's method is redundant. Factor the method, restructuring the code to eliminate unnecessary statements while retaining the same behavior.
• Insert some test calls of the method in `main` and run it to make sure it works properly.

# Exercise : Syntax errors

• The following Java program has 7 errors. Can you find all of them?  ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ``` ```public class IfOops { public static void main(String[] args) { int a = 7, b = 42; minimum(a, b); if {smaller = a} { System.out.println("a is the smallest!"); } } public static void minimum(int a, int b) { // returns which int is smaller if (a < b) { int smaller = a; } else (a => b) { int smaller = b; } return int smaller; } } ```
• Copy and paste the code into jGrasp and see if you can fix the errors.

1. line 5: `if` statement should use `()` parentheses, not `{}` brackets
2. line 5: `=` should be `==`
3. line 5: `smaller` is out of scope here
4. line 10: `void` should be `int`
5. line 13: `=>` should be `>=` (or better yet, no `if` test is needed)
6. line 16: should not write variable's type of `int` when returning it
7. line 16: `int smaller` is out of scope here (declare outside `if` or return directly)

# Exercise - Corrected version

• ```public class IfOops {
public static void main(String[] args) {
int a = 7, b = 42;
int smaller = minimum(a, b);
if (smaller == a) {
System.out.println("a is the smallest!");
}
}

public static void int minimum(int a, int b) {  // returns which int is smaller
int smaller;
if (a < b) {
int smaller = a;
} else if (a >= b) {
int smaller = b;
}
return int smaller;
}
}
```

# Exercise : AgeCheck

• Copy/paste and save the following program in jGRASP, then see the instructions on the next slide.
```public class AgeCheck {
public static void main(String[] args) {
int myAge = 19;   // I am 19; let me see if I can drive
message(myAge);
}

// Displays message about driving to user based on given age
public static void message(int age) {
if (myAge >= 16) {
System.out.println("I'm old enough to drive!");
}
if (myAge <= 16) {
System.out.println("Not old enough yet... :*(");
}
}
}
```

# Exercise - things to fix

• The program has a few syntax errors. Fix them until it compiles.
• The code has a logic problem. (For some value(s), it prints the wrong answer.) Find any such problems and fix them. (You may need to run the program a few times and try different values to see which ones fail.)
• The program uses `if` and `else` in a clumsy way. Improve the style of the code.

• The following is a corrected version of the program:
```public class AgeCheck {
public static void main(String[] args) {
int myAge = 19;   // I am 19; let me see if I can drive
message(myAge);
}

// Displays a message about driving to user based on given age
public static void message(int age) {
if (age >= 16) {
System.out.println("I'm old enough to drive!");
} else {
System.out.println("Not old enough yet... :*(");
}
}
}
```

# Exercise : AgeCheck2

• Now replace your previous `AgeCheck` program's `message` method with:
```    // Possibly prints some message(s) to the user based on the given age
public static void message(int age) {
if (age >= 21) {
System.out.println("I can legally purchase alcohol!");
} else if (age >= 17) {
System.out.println("I can purchase a ticket to an R-rated movie.");
} else if (age >= 16) {
System.out.println("I can get my driver's license!");
}
}
```
• For some age(s), the message(s) printed are not accurate. (In some cases, it should print no messages; in some cases, one message; and in others, many messages.) Improve the usage of `if`s and `else`s in this method to behave properly.

# Exercise : seeMovie

You're thinking about going with your friends to a movie. Write a Java method `seeMovie` that accepts two parameters: the cost of a ticket in dollars, and the rating number of stars the movie received out of 5. The method should print how interested you are (very, sort-of, or not). Use the following criteria:

• You like bargains. Any movie that costs less than \$5.00 is one that you want to see very much.
• You dislike expensive movies. You are not interested in seeing any movie that costs \$12.00 or more, unless it got 5 stars (and even then, you are only sort-of interested).
• You like quality. You are very interested in seeing 5-star movies that cost under \$12.00.
• You are sort-of interested in seeing movies costing between \$5.00 - \$11.99 that also got between 2-4 stars inclusive.
• You are not interested in seeing any other movies not described previously.

# If you finish them all...

If you finish all the exercises, try out our Practice-It web tool. It lets you solve Java problems from our Building Java Programs textbook.

You can view an exercise, type a solution, and submit it to see if you have solved it correctly.

Choose some problems from the book and try to solve them!