| CPSC 124 | Introduction to Programming | Spring 2008 |
In this week's lab, you'll modify and create some Java programs that work with various types of expressions and Strings. You'll also be using the non-standard class TextIO to read data typed in by the user. Much of this lab was originally written by Professors Eck, Orr, and Bridgeman.
Create a lab02 directory for this week's lab files in your cs124 directory (~/cs124/) and change to that directory (review lab #1 if you don't remember how to do this.). Copy the provided files from the directory /classes/s08/cs124/labs/lab02 to your new lab02 directory. You can copy them one at a time, or you can use a wildcard pattern to copy everything at once:
cp /classes/s08/cs124/labs/lab02/*.java ~/cs124/lab02/
"*" is a special symbol which matches anything. Using it as part of a longer pattern like /classes/s08/cs124/labs/lab02/*.java means that it will match any file whose name starts with /classes/s08/cs124/labs/lab02/ and ends with .java - i.e. all the .java files in the /classes/s08/cs124/labs/lab02/ directory.
The rest of this lab assumes you are in your lab02 directory.
Programs are written for people just as much as they are written for computers - by far the longest part of a program's lifecycle is the maintenance phase, where programmers may go back for years to fix bugs and add features. It is thus important to make sure they can understand the program.
Any program that you turn in for this course should obey the rules of good programming style. You will lose points for poor style, even if your program works correctly. The following style rules are already relevant:
Put a comment at the beginning of the program that explains what the program does. This comment should explain the purpose of the program. Include your name and the assignment name in this comment.
Use meaningful variable names which suggest the role of the variable in the program, while avoiding extremely long names. Single-letter names are rarely appropriate.
Usually, you should declare each variable on a separate line and include a comment stating the purpose that the variable serves in your program. When several variables are closely related, it might be OK to declare them on the same line.
Start class names with a capital letter and capitalize the first letter of subsequent words (e.g. HelloWorld or TempConvert). Start variable names with a lowercase letter, with capital letters for subsequent words (e.g. lastNumber).
Use indentation to show the structure of the program. This means that you should indent the main() routine inside the class, and you should indent the statements inside the main() routine. Follow examples that you see in class and in the book. If you use emacs or xemacs as a text editor, pressing tab on any line will indent it properly. (If it doesn't, that is often a sign that you have a syntax error somewhere.)
Do not have lines longer than 80 characters. (80 characters is the standard for how much text can be printed on one line of paper.) The easiest way to make sure your lines aren't too long is to set the width of your editor window to be 80 columns, and then hit return to split any line that wraps onto a second line. You can split a line almost anywhere other than in the middle of an identifier, operator, or string. Good places are typically right after operators or commas.
Additional rules will be added throughout the course.
Note: Don't use comments to explain how Java works. Assume that anyone reading a Java source code file knows Java. A comment such as "declare a variable named interestRate" is useless. However, the comment "annual interest rate, expressed in decimal form" gives information that makes the program easier to understand.
One of the files in the lab2 directory is TextIO.java. As discussed in Section 2.4, this file defines some subroutines that you can use for reading data typed by the user into your program. You don't have to read this file or understand the Java code in it, though you are welcome to look at it if you wish. All you need to know is the names of the subroutines and what they do (which you can find out from the book, or by looking at the file).
In fact, you don't really need the source code file, TextIO.java, at all - what you really need is the compiled class file. Once you've compiled TextIO.java, you could actually delete the .java file because you aren't going to make any changes to TextIO (which is why you'd need the .java file once it has been compiled).
Note: TextIO.class is not a standalone program. You can't run it (it has no main() subroutine). It is merely a "helper class" that contains variables and subroutines that can be used by other programs. Also keep in mind that the TextIO.class file must be in the same working directory as any program that uses it.
Another note: use only the methods in TextIO that start with getln (e.g., getlnInt(), getlnBoolean(), getlnDouble(), getln(), etc.) and not the methods that start with get (e.g., getInt(), getBoolean(), getDouble(), get(), etc.). The latter class of methods is for reading multiple inputs on a single line, something we won't need to do in this class. If you forget the ln in getln, it can lead to some strange errors, so make sure your method call always starts with: TextIO.getln.
Here are the exercises for this week's lab, due next Thursday (February 7th) by the beginning of lab.
Important: Before you start on the exercises, read the directions for electronic handin in the "Handin" section below. Test that you can actually hand something in successfully by handing in your current lab02 folder (which currently contains only provided code for this lab). If you have problems, let me know right away. Not being able to hand something in because you didn't test it ahead of time does not excuse a late submission.
Within your lab02 directory is the TempConvert.java file. At first, the TempConvert program will simply print out a temperature in Fahrenheit. You should modify the program to read in the temperature from the user and to convert the temperature to other temperature scales (as described below).
You should make the changes one at a time and test the program to be sure it works after each change - this is known as incremental development, and is a very good strategy. If you find that the program doesn't work at some point, it is likely because of some change you made since the last time you tested it. If you've only made a few changes, there are only a few places to start looking for the problem.
Modify your program so that it will interactively read the temperature from the user. You can use the provided file TextIO.java (described in chapter 2) for reading the temperature from the user. Make sure that before your program reads in the temperature, it prompts the user (using a print statement) with a message telling the user to enter a temperature. Otherwise, the user may not understand why the program has stopped.
Add statements to also compute and display the temperature in the following scales: Celsius, Kelvin, and Réaumur (a mostly obsolete system developed by a French scientist in the 18th century). Here are some facts to help you with your conversions:
By modifying the temperature in Fahrenheit, and re-compiling and re-running the program, you can find the corresponding temperatures in Celsius, Kelvin, and Réaumur for several Fahrenheit temperatures. For example, with Fahrenheit set to 32 (water melting point), your program should look as follows:
Temperature in Fahrenheit: 32.0 Corresponding temperature in Celsius: 0.0 Corresponding temperature in Kelvin: 273.15 Corresponding temperature in Réaumur: 0.0
Re-run your program three times and enter the following Fahrenheit values: 212 (water boiling point), 98.6 (human temperature), and -40. What values do you find for Celsius, Kelvin, and Réaumur? Put these answers in a comment at the top of your program.
Don't forget to update the comments to reflect the changes you made, and be sure to add your name, the assignment name, and the exercise number.
Write a complete program called ComputeDivisor.java that computes whether one number evenly divides another number (i.e., there is no remainder). Your program should read the values (dividend and divisor) interactively from the user. Make sure your program prompts the user with a print statement before attempting to read in each value (otherwise, the user will not realize that they need to enter anything). Once your program has obtained the dividend and divisor, it should compute whether the divisor evenly divides the dividend, and print out this result.
Below is an example run of the program, which illustrates the output when the divisor does evenly divide the dividend. User input is underlined.
Enter the dividend: 32 Enter the divisor: 16 It is true that 16 evenly divides 32.
Below is another example run of the program, which illustrates the output when the divisor does not evenly divide the dividend. User input is underlined.
Enter the dividend: 32 Enter the divisor: 17 It is false that 17 evenly divides 32.
When you have finished your program, test it out by running the program and entering 30,003 for the dividend and 137 for the divisor. Then re-run the program and enter 30,003 for the dividend and 138 for the divisor. Does either divisor evenly divide 30,003? Put your results in a comment at the top of your program.
Don't forget good programming style.
Write a complete program called Conversation.java. The program should hold a short conversation with the user. It should ask the user for information and should use that information in its responses. Here is a sample conversation, with the user's input shown with bold:
Hi, my name is HAL. What's your name?
Dave
Hi Dave. Nice to meet you.
How many years old are you, Dave?
35
Wow, 35! You must have been born in 1969.
What's that in your hand, Dave?
.
.
.
Remember that your program is essentially a script for the conversation. You are welcome to be as serious or absurd as you want to be.
You should have at least five questions and answers, which means you may need as many as five variables. At least one user answer should be used in more than one of the computer's responses (like the name "Dave" is in the sample). The program should ask for at least one number, and it should do some calculation with that number (the sample uses the age to compute the year in which the user was born). You should also use at least one subroutine from the Math class (page 31 of the textbook) and at least one from the String class (page 33 of the textbook). You can use ones discussed in class and in the textbook, or you can use the Java API documentation to find other subroutines to use.
Don't forget good programming style.
Write another complete program called StringTest.java. Your program should do the following:
Declare a string variable.
Assign it to some sequence of lowercase and uppercase letters.
Print the string.
Print the string in all uppercase letters.
Print the length of the string.
Print the first character in the string.
Test your program to see what happens when the string is set to an empty string (i.e., ""). You should observe an error. Describe in comments within the program why this error occurs.
Don't forget good programming style. Hint: for a list of some useful String methods, look at page 33 of the textbook.
There are lots of small details in Java and sometimes you may have a question about whether or not something will work. A great way to get the answer is to try it out. In this part, you'll write a small tester program called Test.java to answer the following set of questions:
int x, y;
x = 10;
y = 42;
System.out.print("the answer is: ");
System.out.println(x*y);
Most operators (e.g., -, *, &&) are not defined on strings. There is one exception: '+'. For example, I can do the following:
String message; message = "** TOP SECRET! **"; System.out.println(message+" (don't tell anyone the answer is 5) "+message);What happens when these statements execute? In general, what happens when I add two strings together?
Finally, can you combine these two ideas and do something like
int x, y;
x = 10;
y = 42;
System.out.println("the answer is: "+x*y);
Does the order matter - could you do
System.out.println(x*y+" is the answer");
instead? Does the choice of operator matter? These examples use *, but what about +, -, /, or % - do those work? Put your answer to these questions in a comment at the top of the program.
State what the results are and explain them as best you can. (Hint: think about the type of each value.) Can you figure out how to fix the things that don't do what you want them do?
Verify that your lab02 folder contains all of the files you created or modified for this lab, then copy your entire lab02 folder to the handin directory ~mcorliss/handin/cs124/username (where username is replaced with your username). To copy a whole directory instead of a single file or a collection of files, use
cp -r sourcedir targetdir
where sourcedir is the directory you want to copy and targetdir is where it will be copied to. The "-r" means "recursive" and tells the system to copy the source directory, any files it contains, any subdirectories it contains, any files those subdirectories contain, any subdirectories the subdirectories contain, etc. In this case, the following command will work regardless of what directory you are currently in:
cp -r ~/cs124/lab02 ~mcorliss/handin/cs124/username
Of course, if you named your cs124 directory something other than "cs124", you'll need to substitute your directory's name as appropriate. You can use the ls command (or dir) to check that the directory ~mcorliss/handin/cs124/username contains a lab02 directory, and that the directory ~mcorliss/handin/cs124/username/lab02 contains copies of the files you wanted to hand in.
You can hand things in multiple times - the cp command will overwrite any existing file with the same name.
You can also delete things if you hand in something you didn't want to. Remove files using the command:
rm filename
where filename is replaced by the name of the file you want to remove (e.g. ~mcorliss/handin/cs124/username/lab02/TempConvert.java to remove the file TempConvert.java from your handin directory). Note: including the full path here is important - if you are in your own lab02 directory and type rm TempConvert.java, you'll delete your copy of the TempConvert.java and will have to redo exercise #1 from scratch.
Another very important note: rm deletes things for real so be careful when you use it - a deleted file is gone for good. (If the file had been in existence for a while before you deleted it, you may be able to recover a version from a system backup. You will lose any changes made to the file since the last backup, however.)
You can delete a directory with the command
rmdir dirname
Note that the directory must be empty of all files before it can be removed.
Finally, you can delete files and directories all together with
rm -r dirname
As with cp, the "-r" means recursive and means that it will delete the directory, all files it contains, all subdirectories it contains, all files contained in the subdirectories, all subdirectories contained in the subdirectories, etc. rm -r is a very powerful command and should be used with extreme caution.