CS124, Fall 2001
Lab 6: Subroutines (and More Web Stuff)

The main part of this lab consists of two short exercises on writing subroutines. There is a third exercise, which is related to making Web pages, which you should probably be able to read and complete on your own time.

The directory /home/cs124/lab6 contains the files that you need for this lab. Copy it into your home directory and use the cd command to switch to your lab6 directory.

A combined lab report for labs 5 and 6 is due in class next Friday, October 12.


Exercise 1: Writing Subroutines

The goal of this exercise is to write a few simple subroutines. You will add these subroutines to the program TempConverter.java. The result will be a program that converts degrees Fahrenheit to degrees Celsius and vice versa. This program already has a main() routine. This routine includes a subroutine call statement that calls a subroutine named showMenu(). It also calls two functions, fahrenheitToCelsius() and celsiusToFahrenheit(). The farenheitToCelsius() subroutine is already defined, but the other two subroutines are not. Your job is to add definitions for showMenu() and celsiusToFahrenheit(). To do this, you should edit the file TempConverter.java in your copy of the lab6 directory.

The showMenu() subroutine simply displays a menu to the user as a numbered list of options. The subroutine that you write will simply print out the following text:

         Your Options are:
         
            (1) Convert Farenheit to Celcius
            (2) Convert Celsius to Fahrenheit
            (3) Exit from the program.
            

This subroutine has no parameters, and it does not return a value. (That is, its return type is void.) The celsuisToFahreheit() function is similar to the fahrenheitToCelsius() function, which already exists in the program. It has one parameter, of type double, and it returns a value of type double.. It should use the formula for converting degrees Celsius to degrees Fahrenheit. Given a temperature measurement in degrees Celsius, you should multiply it by 9.0/5.0 and add 32.

Make a print out of the complete program using a2ps, and turn in in as part of your lab report. Don't forget to write comments for the routines you write!


Exercise 2: Programming with Subroutines

You have already had some experience with using subroutines that have been provided to you as black boxes. This is the case with TextIO.getln(), for example. It is also the case for standard subroutines like Math.sqrt and TextIO.getln(). Section 4.5 of the text introduces the terms toolbox and API to refer to collections of related subroutines that are made available for use as black boxes. Section 4.6 introduces a small toolkit for working with "mosaic windows". A mosaic window is a window that shows a grid of colored squares. The API for this toolkit, as given in Section 4.6 is repeated here, with the addition of a subroutine for coloring all the squares randomly:

Mosaic.open(rows,cols,w,h);  where rows, cols, w, and h are of type int. This will open the window with rows rows and cols columns of rectangles. The size of each little rectangle will be w pixels wide by h pixels high. Initially, all the rectangles are black. Note that for purposes of referring to a specific rectangle, rows are numbered from 0 to rows-1, and columns are numbered from 0 to cols-1.

Mosaic.setColor(row,col,r,g,b);  where all the parameters are of type int. This will set the color of the rectangle in row number row and column number col. Any color can be considered to be a combination of the primary colors red, blue, and green. The parameters r, g, and b are integers in the range from 0 to 255 that specify the red, green, and blue components of the color. The larger the value of r, the more red there is in the color. Black has all three color components equal to 0. White has all three color components equal to 255.

Mosaic.getRed(row,col)  where row and col are integers specifying one of the rectangles. This is a function that returns a value of type int. The returned value is an integer in the range from 0 to 255 that specifies the red component of the color of the specified square. There are also functions Mosaic.getBlue(row,col) and Mosaic.getGreen(row,col) for retrieving the other two color components.

Mosaic.delay(millis);  where millis is of type int. This can be used to insert a time delay in the program (to regulate the speed at which the colors are changed, for example). The parameter millis is an integer that gives the number of milliseconds to delay. One thousand milliseconds equal one second.

Mosaic.isOpen()  is a function that returns a boolean value. If the mosaic window is open, the value is true; otherwise it is false. The user can close the window by clicking its close box. A program can close the window by calling Mosaic.close(). If you call Mosaic.setColor() when there is no window open, it will have no effect. If you call Mosaic.getRed() when there is no window, a value of 0 is returned.

Mosaic.fillRandomly();  is a subroutine sets all the squares in the mosaic to have random colors.

Section 4.6 has one example of a program that uses Mosaics. You will want to look at that program before starting this exercise. For the exercise, you will be writing your own program based on Mosaic. It will do the same thing as the following applet (except that you will be writing a stand-alone program that runs in a separate window).

In this applet, there are 40 rows and 40 columns of little squares. At the beginning, each square is set to a random color. Then the applet repeats the following indefinitely: One of the squares is chosen at random. Then one of the four neighbors is selected at random, and the color of the square is changed to be the same as the color of the selected neighbor.

The idea is that each square wants to be the same color as its neighbors, so it changes its color to match one of its neighbors. As time goes on, large patches of uniform color tend to appear. Furthermore, the total number of different colors in the applet tends to decrease. Once the last square of a given color disappears, that color is gone forever -- extinction is forever. In the long run, only a few colors will be left. Eventually, perhaps there will be only one color. (If you want to see some kind of metaphor for diversity and assimilation in this applet, you can work it out on your own.)

For the exercise, you should create a program named Convert.java that does the same thing as the applet. (You should work in your lab6 directory, which contains all the extra classes that your program will depend on.) Your program should have a main() routine and one subroutine named convertSquare(). This subroutine has no parameters. The main routine should implement the following pseudocode algorithm:

      Open a mosaic with 40 rows and 40 columns
      Fill with random colors (by calling Mosaic.fillRandomly())
      while the mosaic is open:
         call the convertSquare() subroutine
         delay for 5 milliseconds

This is very similar to the main routine in the sample program RandomMosaicWalk.java from Section 4.6, so you might want to take a look at that.

The job of the convertSquare() subroutine is to select a square at random and change its color to match the color of one of its neighbors. Keep in mind that rows and columns are numbered from 0 to 39. To choose a random square, just select a random row number in the range 0 to 39 and a random column number in the range 0 to 39. (You can get the random numbers by using statements such as "row = (int)(40*Math.random());".) For choosing the neighbor, you can use a switch statement that follows the following slightly incorrect pseudocode:

        switch ( (int)(4*Math.random()) ) {
           case 0:
               use row-1,column for the neighbor
               break;
           case 1:
               use row+1,column for the neighbor
               break;
           case 2:
               use row,column-1 for the neighbor
               break;
           case 3:
               use row,column+1 for the neighbor
               break;
        }

This pseudocode is slightly incorrect because there is a problem when the randomly selected square is on the edge of the mosaic. In that case, it doesn't have neighbors on all four sides. For example, if row is 0, then row-1 is not a valid row number, so the pseudocode given for case 0 is not correct. You can fix this either by doing nothing when the selected neighbor doesn't exist or by "wrapping around" to the opposite edge of the mosaic (for example, if row is 0 and you are in case 0 above, use 39 for the neighbor's row number instead of row-1).

After you have row and column numbers for the square and for its selected neighbor, you should read the red, green, and blue components of the neighboring square (using Mosaic.getRed, Mosaic.getGreen, Mosaic.getBlue). Use the values for red, green, and blue to set the color of the square (using Mosaic.setColor).

After you get your program running, you might want to try running it with no delay at all in the loop in the main routine.

You should print out your program using a2ps and turn in the printout as part of your lab report.


Some Reading: About Directory Names

Before looking at some new information about Web pages, it will be useful to look more closely at the way files and directories are named in Linux. It turns out that links from one Web page to another use a similar kind of naming.

First of all, you should recognize a general principle of naming: Things often have full names that can identify them uniquely, but they can be referred to by shorter names in a given context. A file or directory in Linux has a full name starting with "/", such as /home/cs124/lab5. However, in Linux, you are always "in" a working directory (also called the current directory), which provides a context for naming. A simple name without /'s refers to a file or directory that is contained in the working directory. Note that this is similar to the way names work in Java. A static subroutine has a full name, which includes the name of the class that contains the subroutine. However, within the same class, a subroutine can be referred to by its simple name.

Besides simple names and full names, it's possible to refer to files and directories using relative path names. A relative path name tells how to get to a file or directory, starting from the working directory. For example, suppose that you want to refer to a file named TextIO.class which is in the directory /home/cs124/lab2. You could refer to it by its full name /home/cs124/lab2/TextIO.class. But if your working directory is /home/cs124, you could also refer to it using the relative name lab2/TextIO.class. This name means, roughly, "go into the directory named lab2 and get the file named TextIO.class."

This is made even more useful because of the special abbreviation .. which stands for "the directory that contains the current directory." For example, the relative path name ../TextIO.class refers to the file TextIO.class in the directory that contains the current directory. One usually refers to .. as meaning "go up one directory". So, cd .. means "go up one directory from the current directory," and ../lab2/TextIO.class means: go up one directory, then go down into the lab2 directory, and access the file named TextIO.class.

Now, how does this apply to the Web? A Web site with more than just a few pages probably wants to organize those pages into directories. Every Web page has a full name, called its URL, such as http://math.hws.edu/eck/index.html. This URL can be used to make a clickable link from one Web page to another. However, when one Web page is linked to another Web page on the same Web site, relative URL's are used instead. These relative URL's work the same way as relative path names in Linux, including the use of the .. abbreviation. This is no accident. Relative URL's are in fact just names of files and directories on the Web site.

Links are added to an HTML page using the <a> tag. This tag has the form: <a href="URL">clickable text</a>, where URL should be replaced by the URL of the page you want to link to, and clickable text should be replaced by the text that you want to appear on the Web page. For example, the following link:

Visit the CS124 Home Page

was created with this <a> tag in the HTML source code:

<a href="http://math.hws.edu/eck/CS124/index.html">Visit the CS124 Home Page</a>

Here, a full URL is used as the address of the page, but it is also possible to use relative URL's.

Now, you already have a file named cs124.html in your www directory. Suppose you have another file named Draw1.html in the same directory. If you want to put a link on your cs124.html page to your Draw1.html page, you could include something like this in the HTML source code in cs124.html:

<a href="Draw1.html">My First Drawing Applet</a>

Suppose that you have a directory named anim inside your www directory, and that the anim directory contains a file named Anim1.html. You could add a link from cs124.html to Anim1.html by adding the following code to the HTML source code in cs124.html:

<a href="anim/Anim1.html">My First Animated Applet</a>

Finally, let's suppose that you want to put a link on the Anim1.html page that takes the user back to your cs124.html page. You have to go up one directory from the Anim1.html file to find cs124.html, so you could use the relative URL ../cs124.html. The code for the link in the Anim1.html file would look like this:

<a href="../cs124.html">Back to My Main CS124 Page</a>

All this leaves one question unanswered: How can you make new directories in your www directory? One way is to use the GUI interface. Open a directory window for your www directory. Right-click in the window. In the pop-up menu that appears, go to the "New" submenu and select "Folder". You will be asked to give a name for the folder. Don't use spaces or other funny characters in the name of a folder that you want to access on the Web.

Alternatively, you could create a directory using the command line interface. From your home directory, cd into the www directory. Use the mkdir command to make the directory. This command takes the name of the directory you want to make as a parameter. To create a directory named "foo" in the current directory, use:  mkdir  foo


Exercise 3: Starting a Web Portfolio

I have already asked you to post a few things on the Web. You will be doing more of this as the term goes on. At this point, I would like you to think about organizing your work on the Web and making it look nice. You should start developing a "Web portfolio" to display your work. If you continue to take computer science courses, you can continue to build this portfolio in the future so you impress people with all that you have done and maybe use it as part of your resumé when you are looking for a job.

First of all, you should create a file named index.html in your www directory, if you don't already have one. (If you don't want to create one from scratch, you can copy your cs124.html file with the command cp cs124.html index.html and then edit the copied file.) The index.html file will be the main or front page for your Web portfolio. Our Web server is set up so that if a URL does not include a file name, it will look for a file named index.html. This means that it will translate a URL such as http://math.hws.edu/~jsmith into http://math.hws.edu/~jsmith/index.html. So, if you have an index.html file, you can just publish the address of your Web site as http://math.hws.edu/~username where username should be replaced by your own user name.

Your index.html file should include some text and pictures. Eventually, you will want to make it look nice. You might want to have information about yourself. You might add some links to your favorite Web locations, to your high school, to your friends Web pages, and so on. Most important, it will include links to the work you do for this course and possibly for other courses.

For now, you are required to start doing one of the following: Either add links from index.html to all the applets that you create for this course, or add a single link from index.html to cs124.html and plan to add links to other courses later. If you do the latter, you should put links from cs124.html to all the applets that you create for this course. For now, you will want links to the drawing applet and to the animation applet that you wrote for previous labs. Although it is not required, I encourage you to think about posting some of the Java source code that you write. However, don't post your code until after the final due date of the assignment! If you want to be organized, I suggest that you make a cs124 directory inside your www directory and put all your work for this course in that directory.

To grade this exercise, I will check that you have an index.html file in your www directory, and that there are links to your cs124 work, as described in the previous paragraph.


David Eck (eck@hws.edu), 4 October 2001