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:
- open XEmacs
- C-x C-f html/saywhat.html<RET>
- Give the document a likely title (e.g., lab4)
- 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>
- 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);