Algorithms and OOD (CSC 207 2013F) : Labs
Primary: [Front Door] [Schedule] - [Academic Honesty] [Disabilities] [Email] [FAQ] [IRC] [Teaching & Learning]
Current: [Assignment] [EBoard] [Lab] [Outline] [Partners] [Reading]
Sections: [Assignments] [EBoards] [Examples] [Handouts] [Labs] [Outlines] [Partners] [Readings]
Reference: [Java 7 API] [Java Code Conventions]
Related Courses: [CSC 152 2006S (Rebelsky)] [CSC 207 2013S (Walker)] [CSC 207 2011S (Weinman)]
Misc: [SamR] [Glimmer Labs] [CS@Grinnell] [Grinnell] [Issue Tracker (Course)] [Issue Tracker (Textbook)]
Summary: We begin to explore the ways in which we can use a debugger to better understand flaws in our code.
In the the laboratory on
unit testing, you forked and cloned the repository
github.com/Grinnell-CSC207/lab-unit-testing.
I've now made some changes to that code, so update your repository.
$git remote add upstream https://github.com/Grinnell-CSC207/lab-unit-testing$git pull upstream master
The pull may cause some conflicts, so resolve the conflicts, add the files with conflicts, and then commit.
As you may have noted in the the
laboratory on unit testing, the procedure
SampleMethods.removeAs is not quite successful in its
attempt to remove all copies of the letter 'a' from its parameter
string.
If you haven't yet written your test cases, here's one.
public void testRemoveAs() {
assertEquals("empty string", "", "");
assertEquals("no as", "hello", "hello");
assertEquals("eliminate one a", "", SampleMethods.removeAs("a"));
assertEquals("eliminate many as", "", SampleMethods.removeAs("aaaa"));
assertEquals("eliminate one a, short string", "pin",
SampleMethods.removeAs("pain"));
assertEquals("eliminate many as, medium string", "lphbet",
SampleMethods.removeAs("alphabet"));
assertEquals("eliminate many as, silly string", "BCDEFGHIJKLMNOPQ",
SampleMethods.removeAs("aBaaCDaaaEFGaaaaHIJKaaaaLMNaaaOPaaQa"));
assertEquals("eliminate prefix and suffix as", "bbb",
SampleMethods.removeAs("aaabbbaaa"));
} // testRemoveAs
You may be able to tell by inspection why the method fails. But let's assume that you don't.
Open the code for removeAs and right click in the grey
bar to the left of the code to set a breakpoint at the start of the
method.
Switch to the code for your unit test. Select > > .
A dialog box should pop up asking you to confirm switching to the Java perspective.
If all goes well, Eclipse should stop at the point that you inserted a breakpoint.
a. What do you expect to happen if you click the button - the button that looks like a green triangle. (Note that in the future, you can also hit F8.)
b. Check your answer experimentally.
As you may have noted, Eclipse resumed computation and ran until the completion of this test. (Presumably, failure.) To see the results, you may need to switch back to the Java perspective. You can get that perspective by clicking on the downward arrow in the upper-right-corner of the screen.
c. Start the unit test again. This time, let's single step through the procedure, using the (also F6). See if you can identify where the code goes wrong.
d. Correct the code to the best of your ability, remove the breakpoint, run the unit tests again, and see if your code passes all of the tests. If so, go on to the next exercise. If not, repeat the debugging steps until you find the next bug.
The removeBs procedure has much the same
goals as removeAs although it uses a
different (but still buggy) approach.
Use JUnit and the Eclipse debugger to identify and correct the errors.
Note:
Your goal is to correct the errors in this approach. Inserting
slightly modified code from removeAs is not
an acceptable strategy.
The SampleMethods.expt method computes
xp using a divide-and-conquer approach.
Some people combine the last two when dealing with an odd exponent.
This approach requires only log2p multiplications to raise x to the pth power, while the naive loop requires p multiplications. (Of course, if you have a book of tables, or functions that simulate those tables, you can compute xp in two table lookups.)
It's a nice approach, but have we implemented it correctly?
If you haven't done so already write unit tests for
.
SampleMethods.expt(int,int)
a. Add the following assertion at the start of your test.
assertEquals("1K", 1024, expt(2, 10));
b. Run the test. It will likely fail.
c. Set a breakpoint at the start of the expt
method. (Make sure that you choose the right one. There are two!)
d. Start the debugger. It should bring you to the first line
of expt.
e. What do you expect to happen if you click the button? (The button that looks like a green triangle.)
f. You may have discovered that instead of returning to the call in
the unit test, the debugger continued executing the code until the
next call to expt, which is a recursive call. Hit
the button another time.
g. You are now three levels deep in the recursive call stack for
expt. In the Debug pane, navigate
between them to see the changing values of x and
p.
h. Single step through the code to see if you can identify where the error occurs.
i. Since intermediate values are not clearly represented in the
code, you may find it difficult, if not impossible, to quickly
identify the error. So what next? You could explicitly insert
temporary values for the recursive call. Instead of calling
return in each case, you could set a local values
(e.g., results and then exit in the logical case).
Or you could get Eclipse to behave better.
Choose one approach and see if you can identify the error. Get help if you're not sure which approach you should use or if you still can't identify the error after trying additional approaches.
Consider the
method. As you might have noted, it doesn't work any more correctly
than the old version of expt(double, int)expt
One issue we may hit in unit testing is that
doubles are approximate. Hence, slightly different orders of
computation can make slight differences in the result (e.g., in
practice Math.sqrt(2)*Math.sqrt(2) is often not the
same as Math.sqrt(2*2), even though they are logically
the same.
Write appropriate unit tests for this alternate version. Then determine if your corrections from the exercise above suffice. If not, use the debugger to figure out why.
Primary: [Front Door] [Schedule] - [Academic Honesty] [Disabilities] [Email] [FAQ] [IRC] [Teaching & Learning]
Current: [Assignment] [EBoard] [Lab] [Outline] [Partners] [Reading]
Sections: [Assignments] [EBoards] [Examples] [Handouts] [Labs] [Outlines] [Partners] [Readings]
Reference: [Java 7 API] [Java Code Conventions]
Related Courses: [CSC 152 2006S (Rebelsky)] [CSC 207 2013S (Walker)] [CSC 207 2011S (Weinman)]
Misc: [SamR] [Glimmer Labs] [CS@Grinnell] [Grinnell] [Issue Tracker (Course)] [Issue Tracker (Textbook)]
Copyright (c) 2013 Samuel A. Rebelsky.

This work is licensed under a Creative Commons Attribution 3.0 Unported License. To view a copy of this
license, visit http://creativecommons.org/licenses/by/3.0/
or send a letter to Creative Commons, 543 Howard Street, 5th Floor,
San Francisco, California, 94105, USA.