Lab 2: Loops and Conditionals

A. Intro

Download the code for Lab 2.

Create a new Eclipse project out of it:

  1. Place the lab02 directory into your workspace directory.
  2. Go to File -> New -> Java Project
  3. Under Project name, type "lab02" (This should match the name of the directory where your downloaded files are). After this step, the other fields should mostly be greyed out.
  4. Click "Finish".

Learning Goals for Today

This lab introduces you to Java loops and conditionals (the if and while statements). This online curriculum contains a brief overview of these features, but we expect that you will have learned them (perhaps in some other language) in an earlier course or in previous programming experience.

The term "programming" includes not just writing code, but a variety of activities. Today's lab gives you practice with some of them.

Pair up for the Lab Exercises

At the end up the day you will submit the following five files. You should submit these assignments with a partner, so please use pair programming throughout the lab today. Tell your TA if you don't have a partner.

Be alert to differences between your approaches to today's activities and your partner's. Which ones will work for you? The last discussion for today is intended to help expose good solution approaches.

B. Review of if/else/while

Java Statements

Chapter 1 of Head First Java (which you should have read before lab today) and earlier lab activities introduced you to Java statements, the component lines that make of Java method bodies. Here are some example statements:

Code in a while statement is said to be in a loop.

Assignment statements in Java behave very similarly to those in Python. A method call in Java is analogous to a function call in Python. We assume that you're reasonably comfortable with this — at least in concept. Remaining activities in this lab will focus on if and while statements.

How if and if ... else Work

You've already seen some of this from the first lab, so it should be a bit of a review—but read on!

if statements start with the word if and are followed by a test—a boolean expression—in parentheses, and a sequence of statements surrounded by braces, for example,

if (year % 4 == 0) {
    System.out.println (year + " might be a leap year.");
}

(Note: like in Python, the % symbol above is called mod, and it takes the remainder after division. The above statment is checking if year has no remainder when divided by 4)

The braces after an if statement aren't necessary if there is only one statement in the sequence; however, it is good practice always to include them, since it simplifies later modification of the code.

Tests often involve comparisons. The comparison operators in Java are == and != for equality and inequality testing, and >, >=, <, and <= for comparison of magnitudes. Multiple comparisons can be chained together with the logical operators && (and) and || (or).

The block of statements following the if statement above will not execute if year's value is not divisible by 4. If you wanted something to happen when the test fails, use the else keyword. Here's an example:

if (year % 4 == 0) {
    System.out.println (year + " might be a leap year.");
} else {
    System.out.println (year + " is definitely not a leap year.");
}

You can also add further tests that are executed only if above tests fail, for example:

if (year % 4 != 0) {
    System.out.println (year + " is not a leap year.");
} else if (year % 100 != 0) {
    System.out.println (year + " is a leap year.");
} else if (year % 400 != 0) {
    System.out.println (year + " is not a leap year.");
} else {
    System.out.println (year + " is a leap year.");
}

These all have straightforward conterparts in Python:

if year % 4 != 0:
    print(str(year) + " is not a leap year.")
elif year % 100 != 0:
    print(str(year) + " is a leap year.")
elif year % 400 != 0:
    print(str(year) + " is not a leap year.")
else:
    print(str(year) + " is a leap year.")

How while Works

The while statement is used to repeat a given sequence of statements. It consists of the word while, followed by a continuation test in parentheses, followed by a sequence of statements to repeat, enclosed in braces. The statement sequence is called the loop body.

The while statement works by evaluating the test expression; if it's true, the entire loop body is executed. Then, the test is checked again; if it succeeds, the entire loop body is executed again. This continues, possibly infinitely.

(A common mistake when first learning a Java-like language is to think that the behavior of while is to stop as soon as the test becomes false, possibly in the middle of the loop. This is not the case. The test is checked only at the end of a complete iteration, and so this is the only time the loop can stop.)

Example

Here's an example that implements the remainder operation dividend % divisor, and produces some output. We assume all variables have already been declared, and that divisor and dividend have already been assigned positive values.

while (dividend >= divisor) {
    dividend = dividend - divisor;
    System.out.println ("loop is executed");
}
remainder = dividend;

All statements of the loop body are executed, even if one of them affects the truth value of the test. In the example above, values of 9 for dividend and 4 for divisor result in two lines of output. We show a representations with values of 13 for dividend and 4 for divisor and initially 0 for remainder. This results in 3 lines of output.

When debugging while loop code, sometimes it's useful to make charts like the one below to keep track of the value of each variable.

DividendDivisor

C. Collaboration and problem solving

Collaboration Activities

The subsequent activities in today's lab and all of the lab activities later in the course involve collaboration with one of your classmates.

Why do we care about collaboration? Why don't we just let you work by yourself? There are several reasons.

Finally, collaboration is not only helpful to learning, but it can also be fun! You can make new friends who will be good partners in future courses and supporters along your way to a Berkeley degree.

Exercise: Code Analyzing

Working with your partner but not using a computer, determine what each of the following programs prints.

Keep track of how you figure out the output in each program. You'll need this information for today's later exercises.

First program:

public class Test1 {
    public static void main (String [ ] args) {
        int x = 1;
        int y = 1;
        while (x < 5) {
            y = x - y;
            System.out.print (x + "" + y + " ");
            x = x + 1;
        }
    System.out.println ( );
    }
}

Second program:

public class Test2 {
    public static void main (String [ ] args) {
        int x = 1;
        int y = 1;
        while (x < 5) {
            x = x + 1;
            y = y + x;
            System.out.print (x + "" + y + " ");
            x = x + 1;
        }
        System.out.println ( );
    }
}

Third program:

public class Test3 {
    public static void main (String [ ] args) {
        int x = 1;
        int y = 1;
        while (x < 5) {
            if (y < 5) {
                x = x + 1;
                if (y < 3) {
                    x = x - 1;
                }
            }
            y = y + 2;
            System.out.print (x + "" + y + " ");
            x = x + 1;
        }
        System.out.println ( );
    }
}

Exercise: A Jigsaw Puzzle

Again working with your lab partner, use the following parts to complete a program that, when run, produces the output

a-b c-d

You should use each part exactly once. You will have to add some right braces to complete the code. You may either do this on paper or your computer. Here are the parts. (They're also on page 20 of Head First Java. You may check your answer in the book when you finish.)

As before, keep track of what aspects of this task causes you problems. You'll be referring to them in your later exercises.

Part 1

if (x == 1) {
    System.out.print ("d");
    x = x - 1;
}

Part 2

if (x == 2) {
    System.out.print ("b c");
}

Part 3

public class Shuffled {
    public static void main (String [ ] args) {

Part 4

if (x > 2) {
    System.out.print ("a");
}

Part 5

int x = 3;

Part 6

x = x - 1;
System.out.print ("-");

Part 7

while (x > 0) {

D. Using command line arguments

Using Command Line Arguments

Before we go on with the lab exercises, let's briefly talk about how to run programs that take user input when being start up. Consider the following code

public class Picture {
    public static void main (String [] args) {
        try {
            int reps = Integer.parseInt(args[0])
            while (reps > 0) {
                System.out.println("Looping!");
                reps --;
            }
        } catch (NumberFormatException e) {
            return;
        }
    }
}

This code reads in a number from the user input, and prints out "Looping!" that many times. It isn't really important to know how this code works right now. The important part is to know that args is a list of arguments that a user can input, and args[0] is accessing the first of those arguments.

For example, suppose we want to use this program to print out "Looping!" four times. Let's do this outside of Eclipse, on the command line. Assuming we already have the code compiled, we can run it like so:

java Picture 4

If we wanted to, we could have the program print out "Looping!" thirteen times instead by typing in:

java Picture 13

The 4 and 13 are arguments that are being passed into our program. Since we passed them in at the command line, they are referred to as command line arguments.

Command Line Arguments and Eclipse

Since in this class you'll primarily be using Eclipse to run your programs, and not the command line, let's go over how to use command line arguments in Eclipse. Assume we're using the same code from the previous slide.

  1. Click on "Run" -> "Run Configurations..."

RunConfigurations

  1. Click on the tab labeled arguments and type in your argument in the box labeled "Program Arguments"

RunDialogBox

Then select run.

E. More coding practice

Exercise: A Fill-in-the-blanks Problem

The program DateConverter.java (shown below) is missing two assignment statements. The missing statements will either both be at one of the lines marked with ***, or one will be at one of the *** lines and one will be at the other. In a bit, you'll determine what the statements are and where they go. In the next step, however, you'll come up with a small but comprehensive set of tests for the code before writing the code itself. This technique is called "test-driven development", and we'll be doing it more in subsequent labs.

Testing the code involves supplying a value for dayOfYear on the command line. A few new things about the code:

Here's the code for DateConverter.java. Read it, explain it to your partner, and then move on to the next step. (Do not worry about filling in statements yet!)

import java.io.*;

public class DateConverter {

    // Given a day number in 2008, an integer between 1 and 366,
     // as a command-line argument, prints the date in month/day format.
     // Example:
     // java DateConverter 365
     // should print
     // 12/30

     // The code is missing two assignment statements.
     public static void main (String [ ] args) {
        int dayOfYear = 0;
        try {
            dayOfYear = Integer.parseInt (args[0]);
        }catch (NumberFormatException e) {
            e.printStackTrace();
        }
        int month, dateInMonth, daysInMonth;
        month = 1;
        daysInMonth = 31;
        while (dayOfYear > daysInMonth) {
            // *** Here is one possible place to put assignment statements.
            if (month == 2) {
                daysInMonth = 29;
            } else if (month == 4 || month == 6 || month == 9 || month == 11) {
                daysInMonth = 30;
            } else {
                daysInMonth = 31;
            }
            // *** Here is another possible place to put assignment statements.
        }
        dateInMonth = dayOfYear;
        System.out.println (month + "/" + dateInMonth);
    }
}

Discussion: Test Case Design

Link to the discussion

With your partner, design a set of dayOfYear values—a test suite—that you plan to use to test the program. For each value, indicate what output should result, and explain a bug in the completed code that you think it might reveal.

Exercise: Complete the Program DateConverter.java

In partnership, determine the missing statements. Then complete and test the code. Here's how to do it in Eclipse:

  1. One of you should take the keyboard, with the other looking on. Open DateConverter.java in your lab02 Eclipse project.
  2. Fill in the two missing statements, replacing the lines marked with ***. You will either put both the statements in one of the indicated areas, or one statement in each.
  3. Test the code with different values of dayOfYear. You will do this by using different command line arguments.
  4. If you discover bugs, attempt to fix the code, and repeat step 3 until you're done.

Discussion: Test Case Evaluation

Link to the discussion

Was your test suite sufficient to reveal all your bugs? Explain why or why not.

Exercise: Another Jigsaw Puzzle - Drawing a Triangle

The file TriangleDrawer.stuff contains a collection of statements. Some of the statements, together with some extra right braces, form the body of a main method that, when executed, will print the triangle

*
**
***
****
*****
******
*******
********
*********
**********

(Each line has one more asterisk than its predecessor; the number of asterisks in the last line is the value of the SIZE variable.)

First, switch places with your partner. Start up Eclipse, copy and paste statements from the TriangleDrawer.stuff file into the main method of a new class you create called TriangleDrawer.java. You'll have to add some right braces in addition to the copied lins. (You won't need all the statements. You shouldn't need to use any statement more than once.)

Many students encounter infinite loops in their first solutions to this problem. Eclipse seems not to control infinite loops all that well if you just let them keep running. If you get an infinite loop, be sure to hit the big red square button ("Terminate") in Eclipse's console to stop the program.

Exercise: Check Digit Verification

Identification numbers are everywhere today: student IDs, driver's license numbers, credit card numbers, bank account numbers, Universal Product Codes (UPCs), and International Standard Book Numbers (ISBNs) are but a few examples. One simple security scheme for verifying the accuracy of an identification number is to have one or more of its digits be computed from the remaining digit, that way if this extra digit doesn't match, then you know there was an error.

Switch places again with your partner. Then, create look at the file CheckDigit.java in your lab02 project. Supply the missing code that determines if the identification number in the variable id is legal by storing a true or false value in the variable isLegal. In a legal ID number, the rightmost digit is the last digit of the sum of all the other digits in the number. For example, 123456786 is legal since 6 is the last digit of 1+2+3+4+5+6+7+8 = 36, while 123456782 is not legal.

(Hint: The % operator from earlier might be useful.)

The first few lines of the main method turns the command-line argument into an integer value, as in the DateConverter program. Do not change the value of id. Instead, the code you supply may declare extra variables; give them names that suggest their purpose in the computation.

CheckDigit.java

public class CheckDigit {

    public static void main (String [ ] args) {
        int id = 0;
        try {
            id = Integer.parseInt (args[0]);
        } catch (NumberFormatException e) {
            System.out.println ("The argument has to be a sequence of digits.");
            System.exit (1);
        }
        boolean isLegal = true;
        // your missing code goes here
        if (isLegal) {
            System.out.println (id + " is legal");
        } else {
            System.out.println (id + " is not legal");
        }
    }
}

Exercise: An Adding Machine Simulator

Consider a program that simulates an old-fashioned adding machine. The user types integers as input, one per line. Input should be handled as follows: a nonzero value should be added into a subtotal; a zero value should print the subtotal and reset it to zero; two consecutive zeroes should print the total of all values input, then terminate the program.

Here's an example of how the program should behave.

user input printed output
0 subtotal 0
5
6
0 subtotal 11
-3
-2
5
0 subtotal 0
13
-13
8
0 subtotal 8
0 total 19

First, switch places with your partner one last time. Then complete the framework below — it's also in AddingMachine.java — to produce the simulator program. You can add code anywhere in the program, though you shouldn't have to remove any.

A few more details:

Here is the framework:

import java.util.*;

public class AddingMachine {

    public static void main (String [ ] args) {
        Scanner scanner = new Scanner (System.in);
        boolean justStarting = true;
        int total = 0;
        int subtotal = 0;
        while (true) {
            // TODO Your code here
        }
    }
}

Exercise: Another Adding Machine

As mentioned previously, there are two main different ways of writing the adding machine simulator, one which uses a single loop, and one which uses two loops with one inside the other.

In a file named AddingMachine.readme, answer the following:

F. Conclusion

Lab Submission

Today's activies addressed a variety of aspects of programming. We hope you noticed which ones you seem to be good at already and which ones you are finding more difficult, and you got some ideas for improvement from your classmates.

Finish the date conversion, triangle-drawing, check digit, and adding machine programs if you didn't do so in lab, copy them to a top-level directory named lab02, and submit the working versions. You should submit five files:

For the next lab read the following:

As a part of the lab, you must also provide posts and responses to the discussion activity in the next step.

Discussion: Programming Skills

Link to the discussion

You did a variety of things in lab activities earlier today: designing code from scratch, filling in missing code, analyzing code, inventing convincing test values, and collaborating with a partner.

In your post, include answers to the following.

  1. What made these tasks hard? (Or, if you found them easy, what aspects of the activities might have caused trouble for a less experienced programmer?)
  2. What general skills might help a programmer do better at tasks like the ones listed above?

Also, respond to the list of one of your classmates by suggesting ways that a student could best learn the skills in the list. Draw on personal experience where relevant.

Mention the names and logins of you and your partner in your post.