Lab 2 | CS 61BL Summer 2015 Main Course Info Staff Assignments Resources Piazza Lab 2: Loops and Conditionals Table of Contents A. Intro Learning Goals for Today Pair up for the Lab Exercises B. Review of if/else/while Java Statements How if and if ... else Work How while Works C. Collaboration and problem solving Collaboration Activities Exercise: Code Analyzing Exercise: A Jigsaw Puzzle D. Using command line arguments Using Command Line Arguments Command Line Arguments and Eclipse E. More coding practice Exercise: A Fill-in-the-blanks Problem Exercise: Complete the Program DateConverter.java Exercise: Another Jigsaw Puzzle - Drawing a Triangle Exercise: Check Digit Verification Exercise: An Adding Machine Simulator Exercise: Another Adding Machine F. Conclusion Lab Submission A. Intro Download the code for Lab 2. Create a new Eclipse project out of it: Place the lab02 directory into your workspace directory. Go to File -> New -> Java Project 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. 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. Writing code is of course one of these activities. There may, however, be stylistic or structural constraints on the code to be written. Analyzing code—figuring out how it works—is another. This might involve "playing computer" or doing some more abstract reasoning. Testing code is a third important activity. Here, one executes the code multiple times, intending to expose bugs or other execution flaws by analyzing the output or effect of each test. A fourth activity is evaluating code, choosing which of two given versions is better. One may run more efficiently, or be easier to test or maintain, or be more easily analyzed. 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. DateConverter.java TriangleDrawer.java CheckDigit.java AddingMachine.java AddingMachine.readme 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: an assignment, which stores a value into a variable, e.g. x = 3; a method call, e.g. System.out.print("hello"); calls the method print; an if statement, which conditionally executes code based on the result of a test; a while statement, which conditionally repeats code based on a continuation test. 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. 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. Collaborating allows you to solve much bigger problems much faster than you can alone. In industry, to make anything really cool, you'll have to work on a team. Collaborating is hard, so the sooner you get comfortable with collaboration the better! (But see the previous bullet—to do really cool stuff you need to collaborate.) Companies are continually telling Berkeley professors that our graduates aren't good enough at working in teams. We need to be doing more of this. Many of the upper-division programming courses involve large team projects. If you haven't learned good collaboration techniques by then, you're liable to doom your team. The second two projects in CS 61BL will be done in groups. In almost all cases, you learn by collaborating: explaining a concept to someone helps you understand it better; having a concept explained to you might provide you with different and more productive ways of understanding the concept; explaining a program to someone else can help you find its bugs; working with someone else helps you identify your own strengths and weaknesses. 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. Click on "Run" -> "Run Configurations..." Click on the tab labeled arguments and type in your argument in the box labeled "Program Arguments" 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: The value for dayOfYear is read from args[0], which is a command line argument. Review the previous slides if you don't remember how to run a program with different command line arguments. The statement import java.io.*; makes Java library methods involving input and output accessible inside the program. The five lines starting with try { catches an exception that would occur if the command line argument isn't an integer. We'll learn about exceptions in a couple of weeks. 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: One of you should take the keyboard, with the other looking on. Open DateConverter.java in your lab02 Eclipse project. 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. Test the code with different values of dayOfYear. You will do this by using different command line arguments. 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: We know of at least two different approaches to this problem: one that only uses the single loop given, and one that includes a second inner loop inside. You may write either. To exit the main method, execute a return; statement somewhere inside the method. Because the main method is of type void, it can't return a value. Therefore, the appropriate return statement doesn't have an argument. This code introduces the Scanner class. A Scanner can be used to read user input. Here the Scanner is created with System.in as an argument, which means that it is expecting input from the command line (or from Eclipse's Console). You can do a variety of things with a Scanner, but in this exercise you'll find it most useful to use code like this: int k;
k = scanner.nextInt(); Here, scanner reads everything it can from its input and stores the result in an integer k. Because scanner's input is the command line, the program will actually stop and wait at this part of the code until the user types in something at the command line and hits enter. For example, if the user types 100, then the program will store the value 100 in k before continuing on. 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: Which version did you implement for the exercise? Describe in words how the other version would work, without actually coding it. Which version do you prefer? Describe two reasons for preferring the one-loop version and two reasons for preferring the two-loop version. 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: DateConverter.java TriangleDrawer.java CheckDigit.java AddingMachine.java AddingMachine.readme For the next lab read the following: HFJ chapters 3, 4, and 9 except pages 250 through 255 Boxes and arrows 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. 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?) 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.