CS 110 -- Lab 5

Why did my program do that???

One of the more frustrating aspects of programming is when you have gotten your program to compile and you think that you are just about done, and your program does something unexpected. Why??? In this lab we will explore several ways for finding out what the heck the program is doing.

The instructions below ask several questions of you. Write brief answers on this sheet and turn it in when you are done. This will count as a part of your homework grade. The only grade on this will be "OK" or "not OK".

Step 1: Create an html page

As always, to create an html page do the following:
  1. open XEmacs
  2. C-x C-f html/saywhat.html<RET>
  3. Give the document a likely title (e.g., lab4)
  4. add an applet tag below the <h1>tag. Be sure to make the applet wide and high. For example:
    <applet code=SayWhat.class width=500 height=500> </applet>
  5. Save it
You could call your html page something other than saywhat.html, but I assume that the file is called saywhat.html in the rest of these instructions.

Step 2: Create the Applet and center some text using drawString

Do the usual things to create a new Java applet named SayWhat. Into the applet put the following code:
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
/**
* BY: Me
* FILE: SayWhat.java for the applet and saywhat.html to run the applet
* PURPOSE: explore the issue of what is happening in a program.
* DESCRIPTION: runtime debugging techniques
**/
public class SayWhat extends Applet implements ActionListener {
Button button;
boolean res;
public void actionPerformed(ActionEvent e) {
repaint();
}
public void init() {
setLayout(new GridLayout(20,1));
button=new Button("hit me");
add(button);
button.addActionListener(this);
}
public void paint(Graphics gnu){
mystery((int)(Math.random()*10), (int)(Math.random()*10));
gnu.drawString("Mystery: "+res, 40, 300);
}
private void mystery(int intA, int intB){
int oeA = intA - (intA/2)*2;
int oeB = intB - (intB/2)*2;
res=(oeA==oeB);
}}

Try just this applet. I.e., save compile then run. What does it do? What happens when you repeatedly hit the button? Why?  Of all of these questions, the "why" is by far the hardest because all that you can see is the final result. The point of this lab is to give you some ways to find out the answer to "why?"

Step 3: Getting more information

There are several ways of getting more information about what is going on in the mystery function. One you already know. Specifically, make all of the variables that are local to the mystery function into class variables, the use drawString in the print method to show them within the applet. The problem with this is that it is: cumbersome, ugly and clutters up the interface that you (presumably) want to keep clean. There are two alternatives...

setStatus

Down at the bottom of the applet is usually the statement "Applet running". You can change this statement with the showStatus statement. showStatus takes a single string a parameter, e.g., showStatus("Hello"); Try putting this in as the first line of  the paint method of SayWhat.java.

Happily, showStatus can be put anywhere in your program. So you could put the following line at the bottom of the mystery method.
showStatus("intA="+intA+" intB="+intB+" oeA="+oeA+" oeB="+oeB+" res="+res);
Try it. What does it do?

No doubt you are depressed right now because all you see is "hello". Why? (Hint: trace throught the program line-by-line.) Fix the problem. Now what does it print?

System.out.println

showStatus is great, but -- as you discovered above, it is limited to showing exactly 1 thing at a time. Sometimes you need more. Like showStatus, System.out.println takes a single string as a parameter. Unlike showStatus, that string gets printed out inthe terminal window in which you started the appletviewer. This is handy because the each time System.out.println is used, it just prints a new line in the terminal window..

Try it. I.e., change showStatus to System.out.println in your program.

Step 4: Loops

One of the most confusing things to debug are loops (e.g., "for" or "while"). For instance, put the following class variable and method into your code:
    int resInt = 0;
private void mystery2(int int1, int int2)
{
int remainder = int1 - (int1 / int2)*int2;
while (remainder != 0)
{
int1=int2;
int2=remainder;
remainder = int1 - (int1 / int2)*int2;
}
resInt = int2;
}
}
Add the following 2 lines the paint function:
 
mystery2((int)(Math.random()*10)+20, (int)(Math.random()*10)+1);
gnu.drawString("Mystery2: "+resInt, 40, 350);
Save, compile and test. What happened? What is the meaning of the number that is the result of mystery2? Try putting some System.out.println (for short println) commands into the code to figure it out. Where should the println commands be? Experiment. Here is a println you most likely want to use:
System.out.println("int1="+int1 + " int2="+int2+" rem="+remainder);